diff options
author | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
commit | aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6 (patch) | |
tree | a66b2fcd87f37b26e2d4f360e6c2a9db53eb1b5b /apps | |
parent | 9b32a1988f848145d96ba2be8cba86e837196df3 (diff) | |
download | rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.tar.gz rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.zip |
Initial import of libFLAC from flac-1.1.2.tar.gz
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5983 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
56 files changed, 29599 insertions, 0 deletions
diff --git a/apps/codecs/libFLAC/AUTHORS b/apps/codecs/libFLAC/AUTHORS new file mode 100644 index 0000000000..49ddae8466 --- /dev/null +++ b/apps/codecs/libFLAC/AUTHORS | |||
@@ -0,0 +1,41 @@ | |||
1 | /* FLAC - Free Lossless Audio Codec | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * This file is part the FLAC project. FLAC is comprised of several | ||
5 | * components distributed under difference licenses. The codec libraries | ||
6 | * are distributed under Xiph.Org's BSD-like license (see the file | ||
7 | * COPYING.Xiph in this distribution). All other programs, libraries, and | ||
8 | * plugins are distributed under the GPL (see COPYING.GPL). The documentation | ||
9 | * is distributed under the Gnu FDL (see COPYING.FDL). Each file in the | ||
10 | * FLAC distribution contains at the top the terms under which it may be | ||
11 | * distributed. | ||
12 | * | ||
13 | * Since this particular file is relevant to all components of FLAC, | ||
14 | * it may be distributed under the Xiph.Org license, which is the least | ||
15 | * restrictive of those mentioned above. See the file COPYING.Xiph in this | ||
16 | * distribution. | ||
17 | */ | ||
18 | |||
19 | |||
20 | FLAC (http://flac.sourceforge.net/) is an Open Source lossless audio | ||
21 | codec developed by Josh Coalson <jcoalson@users.sourceforge.net>. | ||
22 | |||
23 | Other major contributors and their contributions: | ||
24 | "Andrey Astafiev" <andrei@tvcell.ru> | ||
25 | * Russian translation of the HTML documentation | ||
26 | |||
27 | "Miroslav Lichvar" <lichvarm@phoenix.inf.upol.cz> | ||
28 | * IA-32 assembly versions of several libFLAC routines | ||
29 | |||
30 | "Brady Patterson" <bpat@users.sourceforge.net> | ||
31 | * AIFF file support, PPC assembly versions of libFLAC routines | ||
32 | |||
33 | "Daisuke Shimamura" <Daisuke_Shimamura@nifty.com> | ||
34 | * i18n support in the XMMS plugin | ||
35 | |||
36 | "X-Fixer" <x-fixer@narod.ru> | ||
37 | * Configuration system, tag editing, and file info in the Winamp2 plugin | ||
38 | |||
39 | "Matt Zimmerman" <mdz@debian.org> | ||
40 | * Libtool/autoconf/automake make system, flac man page | ||
41 | |||
diff --git a/apps/codecs/libFLAC/COPYING.Xiph b/apps/codecs/libFLAC/COPYING.Xiph new file mode 100644 index 0000000000..610a3ba144 --- /dev/null +++ b/apps/codecs/libFLAC/COPYING.Xiph | |||
@@ -0,0 +1,28 @@ | |||
1 | Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
2 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions | ||
5 | are met: | ||
6 | |||
7 | - Redistributions of source code must retain the above copyright | ||
8 | notice, this list of conditions and the following disclaimer. | ||
9 | |||
10 | - Redistributions in binary form must reproduce the above copyright | ||
11 | notice, this list of conditions and the following disclaimer in the | ||
12 | documentation and/or other materials provided with the distribution. | ||
13 | |||
14 | - Neither the name of the Xiph.org Foundation nor the names of its | ||
15 | contributors may be used to endorse or promote products derived from | ||
16 | this software without specific prior written permission. | ||
17 | |||
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
19 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
22 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
23 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
26 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
27 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
diff --git a/apps/codecs/libFLAC/README b/apps/codecs/libFLAC/README new file mode 100644 index 0000000000..e135601037 --- /dev/null +++ b/apps/codecs/libFLAC/README | |||
@@ -0,0 +1,257 @@ | |||
1 | /* FLAC - Free Lossless Audio Codec | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * This file is part the FLAC project. FLAC is comprised of several | ||
5 | * components distributed under difference licenses. The codec libraries | ||
6 | * are distributed under Xiph.Org's BSD-like license (see the file | ||
7 | * COPYING.Xiph in this distribution). All other programs, libraries, and | ||
8 | * plugins are distributed under the GPL (see COPYING.GPL). The documentation | ||
9 | * is distributed under the Gnu FDL (see COPYING.FDL). Each file in the | ||
10 | * FLAC distribution contains at the top the terms under which it may be | ||
11 | * distributed. | ||
12 | * | ||
13 | * Since this particular file is relevant to all components of FLAC, | ||
14 | * it may be distributed under the Xiph.Org license, which is the least | ||
15 | * restrictive of those mentioned above. See the file COPYING.Xiph in this | ||
16 | * distribution. | ||
17 | */ | ||
18 | |||
19 | |||
20 | FLAC (http://flac.sourceforge.net/) is an Open Source lossless audio | ||
21 | codec developed by Josh Coalson. | ||
22 | |||
23 | FLAC is comprised of | ||
24 | * `libFLAC', a library which implements reference encoders and | ||
25 | decoders, and a metadata interface | ||
26 | * `libFLAC++', a C++ object wrapper library around libFLAC | ||
27 | * `libOggFLAC' and `libOggFLAC++', which provide encoders and | ||
28 | decoders for FLAC streams in an Ogg container | ||
29 | * `flac', a command-line program for encoding and decoding files | ||
30 | * `metaflac', a command-line program for viewing and editing FLAC | ||
31 | metadata | ||
32 | * player plugins for XMMS and Winamp | ||
33 | * user and API documentation | ||
34 | |||
35 | The libraries (libFLAC, libFLAC++, libOggFLAC, and libOggFLAC++) are | ||
36 | licensed under Xiph.org's BSD-like license (see COPYING.Xiph). All other | ||
37 | programs and plugins are licensed under the GNU General Public License | ||
38 | (see COPYING.GPL). The documentation is licensed under the GNU Free | ||
39 | Documentation License (see COPYING.FDL). | ||
40 | |||
41 | |||
42 | =============================================================================== | ||
43 | FLAC - 1.1.2 - Contents | ||
44 | =============================================================================== | ||
45 | |||
46 | - Introduction | ||
47 | - Prerequisites | ||
48 | - Building in a GNU environment | ||
49 | - Building with Makefile.lite | ||
50 | - Building with MSVC | ||
51 | - Building on Mac OS X | ||
52 | - Note to embedded developers | ||
53 | |||
54 | |||
55 | =============================================================================== | ||
56 | Introduction | ||
57 | =============================================================================== | ||
58 | |||
59 | This is the source release for the FLAC project. See | ||
60 | |||
61 | doc/html/index.html | ||
62 | |||
63 | for full documentation. | ||
64 | |||
65 | A brief description of the directory tree: | ||
66 | |||
67 | doc/ the HTML documentation | ||
68 | flac.pbproj/ the Mac OS X Project Builder project | ||
69 | include/ public include files for libFLAC and libFLAC++ | ||
70 | man/ the man page for `flac' | ||
71 | src/ the source code and private headers | ||
72 | test/ the test scripts | ||
73 | |||
74 | |||
75 | =============================================================================== | ||
76 | Prerequisites | ||
77 | =============================================================================== | ||
78 | |||
79 | To build FLAC with support for Ogg FLAC you must have built and installed | ||
80 | libogg according to the specific instructions below. You must have | ||
81 | libogg 1.1.2 or greater, or there will be seeking problems with Ogg FLAC. | ||
82 | |||
83 | If you are building on x86 and want the assembly optimizations, you will | ||
84 | need to have NASM >= 0.98.30 installed according to the specific instructions | ||
85 | below. | ||
86 | |||
87 | |||
88 | =============================================================================== | ||
89 | Building in a GNU environment | ||
90 | =============================================================================== | ||
91 | |||
92 | FLAC uses autoconf and libtool for configuring and building. | ||
93 | Better documentation for these will be forthcoming, but in | ||
94 | general, this should work: | ||
95 | |||
96 | ./configure && make && make check && make install | ||
97 | |||
98 | The 'make check' step is optional; omit it to skip all the tests, | ||
99 | which can take several hours and use around 70-80 megs of disk space. | ||
100 | Even though it will stop with an explicit message on any failure, it | ||
101 | does print out a lot of stuff so you might want to capture the output | ||
102 | to a file if you're having a problem. Also, don't run 'make check' | ||
103 | as root because it confuses some of the tests. | ||
104 | |||
105 | NOTE: Despite our best efforts it's entirely possible to have | ||
106 | problems when using older versions of autoconf, automake, or | ||
107 | libtool. If you have the latest versions and still can't get it | ||
108 | to work, see the next section on Makefile.lite. | ||
109 | |||
110 | There are a few FLAC-specific arguments you can give to | ||
111 | `configure': | ||
112 | |||
113 | --enable-debug : Builds everything with debug symbols and some | ||
114 | extra (and more verbose) error checking. | ||
115 | |||
116 | --disable-asm-optimizations : Disables the compilation of the | ||
117 | assembly routines. Many routines have assembly versions for | ||
118 | speed and `configure' is pretty good about knowing what is | ||
119 | supported, but you can use this option to build only from the | ||
120 | C sources. | ||
121 | |||
122 | --enable-sse : If you are building for an x86 CPU that supports | ||
123 | SSE instructions, you can enable some of the faster routines | ||
124 | if your operating system also supports SSE instructions. flac | ||
125 | can tell if the CPU supports the instructions but currently has | ||
126 | no way to test if the OS does, so if it does, you must pass | ||
127 | this argument to configure to use the SSE routines. If flac | ||
128 | crashes when built with this option you will have to go back and | ||
129 | configure without --enable-sse. Note that | ||
130 | --disable-asm-optimizations implies --disable-sse. | ||
131 | |||
132 | --enable-local-xmms-plugin : Installs the FLAC XMMS plugin in | ||
133 | $HOME/.xmms/Plugins, instead of the global XMMS plugin area | ||
134 | (usually /usr/lib/xmms/Input). | ||
135 | |||
136 | --with-ogg= | ||
137 | --with-xmms-prefix= | ||
138 | --with-libiconv-prefix= | ||
139 | Use these if you have these packages but configure can't find them. | ||
140 | |||
141 | If you want to build completely from scratch (i.e. starting with just | ||
142 | configure.in and Makefile.am) you should be able to just run 'autogen.sh' | ||
143 | but make sure and read the comments in that file first. | ||
144 | |||
145 | |||
146 | =============================================================================== | ||
147 | Building with Makefile.lite | ||
148 | =============================================================================== | ||
149 | |||
150 | There is a more lightweight build system for do-it-yourself-ers. | ||
151 | It is also useful if configure isn't working, which may be the | ||
152 | case since lately we've had some problems with different versions | ||
153 | of automake and libtool. The Makefile.lite system should work | ||
154 | on GNU systems with few or no adjustments. | ||
155 | |||
156 | From the top level just 'make -f Makefile.lite'. You can | ||
157 | specify zero or one optional target from 'release', 'debug', | ||
158 | 'test', or 'clean'. The default is 'release'. There is no | ||
159 | 'install' target but everything you need will end up in the | ||
160 | obj/ directory. | ||
161 | |||
162 | If you are not on an x86 system or you don't have nasm, you | ||
163 | may have to change the DEFINES in src/libFLAC/Makefile.lite. If | ||
164 | you don't have nasm, remove -DFLAC__HAS_NASM. If your target is | ||
165 | not an x86, change -DFLAC__CPU_IA32 to -DFLAC__CPU_UNKNOWN. | ||
166 | |||
167 | |||
168 | =============================================================================== | ||
169 | Building with MSVC | ||
170 | =============================================================================== | ||
171 | |||
172 | There are now .dsp projects and a master FLAC.dsw workspace to build | ||
173 | all the libraries and executables. | ||
174 | |||
175 | Prerequisite: you must have the Ogg libraries installed as described | ||
176 | later. | ||
177 | |||
178 | Prerequisite: you must have nasm installed, and nasmw.exe must be in | ||
179 | your PATH, or the path to nasmw.exe must be added to the list of | ||
180 | directories for executable files in the MSVC global options. | ||
181 | |||
182 | To build everything, run Developer Studio, do File|Open Workspace, | ||
183 | and open FLAC.dsw. Select "Build | Set active configuration..." | ||
184 | from the menu, then in the dialog, select "All - Win32 Release" (or | ||
185 | Debug if you prefer). Click "Ok" then hit F7 to build. This will build | ||
186 | all libraries both statically (e.g. obj\release\lib\libFLAC_static.lib) | ||
187 | and as DLLs (e.g. obj\release\bin\libFLAC.dll), and it will build all | ||
188 | binaries, statically linked (e.g. obj\release\bin\flac.exe). | ||
189 | |||
190 | Everything will end up in the "obj" directory. DLLs and .exe files | ||
191 | are all that are needed and can be copied to an installation area and | ||
192 | added to the PATH. The plugins have to be copied to their appropriate | ||
193 | place in the player area. For Winamp2 this is <winamp2-dir>\Plugins. | ||
194 | |||
195 | By default the code is configured with Ogg support. Before building FLAC | ||
196 | you will need to get the Ogg source distribution | ||
197 | (see http://xiph.org/ogg/vorbis/download/), build ogg_static.lib (load and | ||
198 | build win32\ogg_static.dsp), copy ogg_static.lib into FLAC's | ||
199 | 'obj\release\lib' directory, and copy the entire include\ogg tree into | ||
200 | FLAC's 'include' directory (so that there is an 'ogg' directory in FLAC's | ||
201 | 'include' directory with the files ogg.h, os_types.h and config_types.h). | ||
202 | |||
203 | |||
204 | =============================================================================== | ||
205 | Building on Mac OS X | ||
206 | =============================================================================== | ||
207 | |||
208 | If you have Fink, the GNU flow above should work. Otherwise, | ||
209 | there is a Project Builder project in the top-level source | ||
210 | directory to build libFLAC and the command-line utilities on | ||
211 | Mac OS X. In a terminal, cd to the top-level directory (the | ||
212 | one that contains this README file) and type: | ||
213 | |||
214 | pbxbuild -alltargets | ||
215 | |||
216 | This will create everything and leave it in the build/ directory. | ||
217 | Don't worry about the rest of the stuff that is in build/ or | ||
218 | the stuff that was already there before building. | ||
219 | |||
220 | The Project Builder project requires that you have libiconv and | ||
221 | libogg in /sw, ala fink. If you don't, you'll need to install | ||
222 | them somewhere and change the path to them in the Library Paths | ||
223 | section of several targets. | ||
224 | |||
225 | It also assumes the CPU supports Altivec instructions. If it does | ||
226 | not, you will also have to add -DFLAC__NO_ASM to the CFLAGS in the | ||
227 | libFLAC target. | ||
228 | |||
229 | There currently is no install procedure; you will have to | ||
230 | manually copy the tools to wherever you need them. | ||
231 | |||
232 | |||
233 | =============================================================================== | ||
234 | Note to embedded developers | ||
235 | =============================================================================== | ||
236 | |||
237 | libFLAC has grown larger over time as more functionality has been | ||
238 | included, but much of it may be unnecessary for a particular embedded | ||
239 | implementation. Unused parts may be pruned by some simple editing of | ||
240 | configure.in and src/libFLAC/Makefile.am; the following dependency | ||
241 | graph shows which modules may be pruned without breaking things | ||
242 | further down: | ||
243 | |||
244 | file_encoder.h | ||
245 | stream_encoder.h | ||
246 | format.h | ||
247 | |||
248 | file_decoder.h | ||
249 | seekable_stream_decoder.h | ||
250 | stream_decoder.h | ||
251 | format.h | ||
252 | |||
253 | metadata.h | ||
254 | format.h | ||
255 | |||
256 | There is a section dedicated to embedded use in the libFLAC API | ||
257 | HTML documentation (see doc/html/api/index.html). | ||
diff --git a/apps/codecs/libFLAC/README.rockbox b/apps/codecs/libFLAC/README.rockbox new file mode 100644 index 0000000000..5c0c5ecc2c --- /dev/null +++ b/apps/codecs/libFLAC/README.rockbox | |||
@@ -0,0 +1,25 @@ | |||
1 | Library: libFLAC-1.1.2 (Released 2005-02-05) | ||
2 | Imported: 2005-02-16 by Dave Chapman | ||
3 | |||
4 | |||
5 | This directory contains a local version of libFLAC for use by Rockbox | ||
6 | for software decoding and encoding of FLAC files. | ||
7 | |||
8 | |||
9 | LICENSING INFORMATION | ||
10 | |||
11 | libFLAC (which is only one part of the FLAC distribution) is | ||
12 | distributed under Xiph.Org's BSD-like license - see the files AUTHORS | ||
13 | and COPYING.Xiph in this directory for details. | ||
14 | |||
15 | |||
16 | IMPORT DETAILS | ||
17 | |||
18 | The base version first imported into Rockbox was the libFLAC included | ||
19 | in the flac-1.1.2.tar.gz distribution, downloaded on 2005-02-06 from | ||
20 | Sourceforge. | ||
21 | |||
22 | The contents of the flac-1.1.2/src/libFLAC directory (minus the | ||
23 | autoconf/automake files and ia32/ppc specific subdirectories) was | ||
24 | imported, along with the contents of the flac-1.2.2/include/FLAC | ||
25 | directory, which was moved into existing libFLAC/include directory. | ||
diff --git a/apps/codecs/libFLAC/bitbuffer.c b/apps/codecs/libFLAC/bitbuffer.c new file mode 100644 index 0000000000..8f5aefa67b --- /dev/null +++ b/apps/codecs/libFLAC/bitbuffer.c | |||
@@ -0,0 +1,2690 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdlib.h> /* for malloc() */ | ||
33 | #include <string.h> /* for memcpy(), memset() */ | ||
34 | #include "private/bitbuffer.h" | ||
35 | #include "private/bitmath.h" | ||
36 | #include "private/crc.h" | ||
37 | #include "FLAC/assert.h" | ||
38 | |||
39 | /* | ||
40 | * Along the way you will see two versions of some functions, selected | ||
41 | * by a FLAC__NO_MANUAL_INLINING macro. One is the simplified, more | ||
42 | * readable, and slow version, and the other is the same function | ||
43 | * where crucial parts have been manually inlined and are much faster. | ||
44 | * | ||
45 | */ | ||
46 | |||
47 | /* | ||
48 | * Some optimization strategies are slower with older versions of MSVC | ||
49 | */ | ||
50 | #if defined _MSC_VER && _MSC_VER <= 1200 | ||
51 | #define FLAC__OLD_MSVC_FLAVOR | ||
52 | #endif | ||
53 | |||
54 | /* | ||
55 | * This should be at least twice as large as the largest number of blurbs | ||
56 | * required to represent any 'number' (in any encoding) you are going to | ||
57 | * read. With FLAC this is on the order of maybe a few hundred bits. | ||
58 | * If the buffer is smaller than that, the decoder won't be able to read | ||
59 | * in a whole number that is in a variable length encoding (e.g. Rice). | ||
60 | * | ||
61 | * The number we are actually using here is based on what would be the | ||
62 | * approximate maximum size of a verbatim frame at the default block size, | ||
63 | * for CD audio (4096 sample * 4 bytes per sample), plus some wiggle room. | ||
64 | * 32kbytes sounds reasonable. For kicks we subtract out 64 bytes for any | ||
65 | * alignment or malloc overhead. | ||
66 | * | ||
67 | * Increase this number to decrease the number of read callbacks, at the | ||
68 | * expense of using more memory. Or decrease for the reverse effect, | ||
69 | * keeping in mind the limit from the first paragraph. | ||
70 | */ | ||
71 | static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = ((65536 - 64) * 8) / FLAC__BITS_PER_BLURB; /* blurbs */ | ||
72 | |||
73 | #ifndef FLAC__OLD_MSVC_FLAVOR | ||
74 | static const unsigned char byte_to_unary_table[] = { | ||
75 | 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, | ||
76 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | ||
77 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
78 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
79 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
80 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
81 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
82 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
83 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
84 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
85 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
86 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
87 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
88 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
89 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
90 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
91 | }; | ||
92 | #endif | ||
93 | |||
94 | #if FLAC__BITS_PER_BLURB == 8 | ||
95 | #define FLAC__BITS_PER_BLURB_LOG2 3 | ||
96 | #define FLAC__BYTES_PER_BLURB 1 | ||
97 | #define FLAC__BLURB_ALL_ONES ((FLAC__byte)0xff) | ||
98 | #define FLAC__BLURB_TOP_BIT_ONE ((FLAC__byte)0x80) | ||
99 | #define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)'\x80') >> (b)) | ||
100 | #define CRC16_UPDATE_BLURB(bb, blurb, crc) FLAC__CRC16_UPDATE((blurb), (crc)); | ||
101 | #ifndef FLAC__OLD_MSVC_FLAVOR | ||
102 | #define FLAC__ALIGNED_BLURB_UNARY(blurb) (byte_to_unary_table[blurb]) | ||
103 | #endif | ||
104 | #elif FLAC__BITS_PER_BLURB == 32 | ||
105 | #define FLAC__BITS_PER_BLURB_LOG2 5 | ||
106 | #define FLAC__BYTES_PER_BLURB 4 | ||
107 | #define FLAC__BLURB_ALL_ONES ((FLAC__uint32)0xffffffff) | ||
108 | #define FLAC__BLURB_TOP_BIT_ONE ((FLAC__uint32)0x80000000) | ||
109 | #define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)0x80000000) >> (b)) | ||
110 | #define CRC16_UPDATE_BLURB(bb, blurb, crc) crc16_update_blurb((bb), (blurb)); | ||
111 | #ifndef FLAC__OLD_MSVC_FLAVOR | ||
112 | #define FLAC__ALIGNED_BLURB_UNARY(blurb) ((blurb) <= 0xff ? byte_to_unary_table[blurb] + 24 : ((blurb) <= 0xffff ? byte_to_unary_table[(blurb) >> 8] + 16 : ((blurb) <= 0xffffff ? byte_to_unary_table[(blurb) >> 16] + 8 : byte_to_unary_table[(blurb) >> 24]))) | ||
113 | #endif | ||
114 | #else | ||
115 | /* ERROR, only sizes of 8 and 32 are supported */ | ||
116 | #endif | ||
117 | |||
118 | #define FLAC__BLURBS_TO_BITS(blurbs) ((blurbs) << FLAC__BITS_PER_BLURB_LOG2) | ||
119 | |||
120 | #ifdef min | ||
121 | #undef min | ||
122 | #endif | ||
123 | #define min(x,y) ((x)<(y)?(x):(y)) | ||
124 | #ifdef max | ||
125 | #undef max | ||
126 | #endif | ||
127 | #define max(x,y) ((x)>(y)?(x):(y)) | ||
128 | |||
129 | /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | ||
130 | #ifdef _MSC_VER | ||
131 | #define FLAC__U64L(x) x | ||
132 | #else | ||
133 | #define FLAC__U64L(x) x##LLU | ||
134 | #endif | ||
135 | |||
136 | #ifndef FLaC__INLINE | ||
137 | #define FLaC__INLINE | ||
138 | #endif | ||
139 | |||
140 | struct FLAC__BitBuffer { | ||
141 | FLAC__blurb *buffer; | ||
142 | unsigned capacity; /* in blurbs */ | ||
143 | unsigned blurbs, bits; | ||
144 | unsigned total_bits; /* must always == FLAC__BITS_PER_BLURB*blurbs+bits */ | ||
145 | unsigned consumed_blurbs, consumed_bits; | ||
146 | unsigned total_consumed_bits; /* must always == FLAC__BITS_PER_BLURB*consumed_blurbs+consumed_bits */ | ||
147 | FLAC__uint16 read_crc16; | ||
148 | #if FLAC__BITS_PER_BLURB == 32 | ||
149 | unsigned crc16_align; | ||
150 | #endif | ||
151 | FLAC__blurb save_head, save_tail; | ||
152 | }; | ||
153 | |||
154 | #if FLAC__BITS_PER_BLURB == 32 | ||
155 | static void crc16_update_blurb(FLAC__BitBuffer *bb, FLAC__blurb blurb) | ||
156 | { | ||
157 | if(bb->crc16_align == 0) { | ||
158 | FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16); | ||
159 | FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16); | ||
160 | FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); | ||
161 | FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); | ||
162 | } | ||
163 | else if(bb->crc16_align == 8) { | ||
164 | FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16); | ||
165 | FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); | ||
166 | FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); | ||
167 | } | ||
168 | else if(bb->crc16_align == 16) { | ||
169 | FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); | ||
170 | FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); | ||
171 | } | ||
172 | else if(bb->crc16_align == 24) { | ||
173 | FLAC__CRC16_UPDATE(blurb & 0xff, bb->read_crc16); | ||
174 | } | ||
175 | bb->crc16_align = 0; | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | /* | ||
180 | * WATCHOUT: The current implentation is not friendly to shrinking, i.e. it | ||
181 | * does not shift left what is consumed, it just chops off the end, whether | ||
182 | * there is unconsumed data there or not. This is OK because currently we | ||
183 | * never shrink the buffer, but if this ever changes, we'll have to do some | ||
184 | * fixups here. | ||
185 | */ | ||
186 | static FLAC__bool bitbuffer_resize_(FLAC__BitBuffer *bb, unsigned new_capacity) | ||
187 | { | ||
188 | FLAC__blurb *new_buffer; | ||
189 | |||
190 | FLAC__ASSERT(0 != bb); | ||
191 | FLAC__ASSERT(0 != bb->buffer); | ||
192 | |||
193 | if(bb->capacity == new_capacity) | ||
194 | return true; | ||
195 | |||
196 | new_buffer = (FLAC__blurb*)calloc(new_capacity, sizeof(FLAC__blurb)); | ||
197 | if(new_buffer == 0) | ||
198 | return false; | ||
199 | memcpy(new_buffer, bb->buffer, sizeof(FLAC__blurb)*min(bb->blurbs+(bb->bits?1:0), new_capacity)); | ||
200 | if(new_capacity < bb->blurbs+(bb->bits?1:0)) { | ||
201 | bb->blurbs = new_capacity; | ||
202 | bb->bits = 0; | ||
203 | bb->total_bits = FLAC__BLURBS_TO_BITS(new_capacity); | ||
204 | } | ||
205 | if(new_capacity < bb->consumed_blurbs+(bb->consumed_bits?1:0)) { | ||
206 | bb->consumed_blurbs = new_capacity; | ||
207 | bb->consumed_bits = 0; | ||
208 | bb->total_consumed_bits = FLAC__BLURBS_TO_BITS(new_capacity); | ||
209 | } | ||
210 | free(bb->buffer); /* we've already asserted above that (0 != bb->buffer) */ | ||
211 | bb->buffer = new_buffer; | ||
212 | bb->capacity = new_capacity; | ||
213 | return true; | ||
214 | } | ||
215 | |||
216 | static FLAC__bool bitbuffer_grow_(FLAC__BitBuffer *bb, unsigned min_blurbs_to_add) | ||
217 | { | ||
218 | unsigned new_capacity; | ||
219 | |||
220 | FLAC__ASSERT(min_blurbs_to_add > 0); | ||
221 | |||
222 | new_capacity = max(bb->capacity * 2, bb->capacity + min_blurbs_to_add); | ||
223 | return bitbuffer_resize_(bb, new_capacity); | ||
224 | } | ||
225 | |||
226 | static FLAC__bool bitbuffer_ensure_size_(FLAC__BitBuffer *bb, unsigned bits_to_add) | ||
227 | { | ||
228 | FLAC__ASSERT(0 != bb); | ||
229 | FLAC__ASSERT(0 != bb->buffer); | ||
230 | |||
231 | if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits_to_add) | ||
232 | return bitbuffer_grow_(bb, (bits_to_add >> FLAC__BITS_PER_BLURB_LOG2) + 2); | ||
233 | else | ||
234 | return true; | ||
235 | } | ||
236 | |||
237 | static FLAC__bool bitbuffer_read_from_client_(FLAC__BitBuffer *bb, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
238 | { | ||
239 | unsigned bytes; | ||
240 | FLAC__byte *target; | ||
241 | |||
242 | /* first shift the unconsumed buffer data toward the front as much as possible */ | ||
243 | if(bb->total_consumed_bits >= FLAC__BITS_PER_BLURB) { | ||
244 | #if FLAC__BITS_PER_BLURB == 8 | ||
245 | /* | ||
246 | * memset and memcpy are usually implemented in assembly language | ||
247 | * by the system libc, and they can be much faster | ||
248 | */ | ||
249 | const unsigned r_end = bb->blurbs + (bb->bits? 1:0); | ||
250 | const unsigned r = bb->consumed_blurbs, l = r_end - r; | ||
251 | memmove(&bb->buffer[0], &bb->buffer[r], l); | ||
252 | memset(&bb->buffer[l], 0, r); | ||
253 | #elif FLAC__BITS_PER_BLURB == 32 | ||
254 | /* still needs optimization */ | ||
255 | const unsigned r_end = bb->blurbs + (bb->bits? 1:0); | ||
256 | unsigned l = 0, r = bb->consumed_blurbs; | ||
257 | for( ; r < r_end; l++, r++) | ||
258 | bb->buffer[l] = bb->buffer[r]; | ||
259 | for( ; l < r_end; l++) | ||
260 | bb->buffer[l] = 0; | ||
261 | #else | ||
262 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
263 | #endif /* FLAC__BITS_PER_BLURB == 32 or 8 */ | ||
264 | |||
265 | bb->blurbs -= bb->consumed_blurbs; | ||
266 | bb->total_bits -= FLAC__BLURBS_TO_BITS(bb->consumed_blurbs); | ||
267 | bb->consumed_blurbs = 0; | ||
268 | bb->total_consumed_bits = bb->consumed_bits; | ||
269 | } | ||
270 | |||
271 | /* grow if we need to */ | ||
272 | if(bb->capacity <= 1) { | ||
273 | if(!bitbuffer_resize_(bb, 16)) | ||
274 | return false; | ||
275 | } | ||
276 | |||
277 | /* set the target for reading, taking into account blurb alignment */ | ||
278 | #if FLAC__BITS_PER_BLURB == 8 | ||
279 | /* blurb == byte, so no gyrations necessary: */ | ||
280 | target = bb->buffer + bb->blurbs; | ||
281 | bytes = bb->capacity - bb->blurbs; | ||
282 | #elif FLAC__BITS_PER_BLURB == 32 | ||
283 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
284 | FLAC__ASSERT((bb->bits & 7) == 0); | ||
285 | target = (FLAC__byte*)(bb->buffer + bb->blurbs) + (bb->bits >> 3); | ||
286 | bytes = ((bb->capacity - bb->blurbs) << 2) - (bb->bits >> 3); /* i.e. (bb->capacity - bb->blurbs) * FLAC__BYTES_PER_BLURB - (bb->bits / 8) */ | ||
287 | #else | ||
288 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
289 | #endif | ||
290 | |||
291 | /* finally, read in some data */ | ||
292 | if(!read_callback(target, &bytes, client_data)) | ||
293 | return false; | ||
294 | |||
295 | /* now we have to handle partial blurb cases: */ | ||
296 | #if FLAC__BITS_PER_BLURB == 8 | ||
297 | /* blurb == byte, so no gyrations necessary: */ | ||
298 | bb->blurbs += bytes; | ||
299 | bb->total_bits += FLAC__BLURBS_TO_BITS(bytes); | ||
300 | #elif FLAC__BITS_PER_BLURB == 32 | ||
301 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
302 | { | ||
303 | const unsigned aligned_bytes = (bb->bits >> 3) + bytes; | ||
304 | bb->blurbs += (aligned_bytes >> 2); /* i.e. aligned_bytes / FLAC__BYTES_PER_BLURB */ | ||
305 | bb->bits = (aligned_bytes & 3u) << 3; /* i.e. (aligned_bytes % FLAC__BYTES_PER_BLURB) * 8 */ | ||
306 | bb->total_bits += (bytes << 3); | ||
307 | } | ||
308 | #else | ||
309 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
310 | #endif | ||
311 | return true; | ||
312 | } | ||
313 | |||
314 | /*********************************************************************** | ||
315 | * | ||
316 | * Class constructor/destructor | ||
317 | * | ||
318 | ***********************************************************************/ | ||
319 | |||
320 | FLAC__BitBuffer *FLAC__bitbuffer_new() | ||
321 | { | ||
322 | FLAC__BitBuffer *bb = (FLAC__BitBuffer*)calloc(1, sizeof(FLAC__BitBuffer)); | ||
323 | |||
324 | /* calloc() implies: | ||
325 | memset(bb, 0, sizeof(FLAC__BitBuffer)); | ||
326 | bb->buffer = 0; | ||
327 | bb->capacity = 0; | ||
328 | bb->blurbs = bb->bits = bb->total_bits = 0; | ||
329 | bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; | ||
330 | */ | ||
331 | return bb; | ||
332 | } | ||
333 | |||
334 | void FLAC__bitbuffer_delete(FLAC__BitBuffer *bb) | ||
335 | { | ||
336 | FLAC__ASSERT(0 != bb); | ||
337 | |||
338 | FLAC__bitbuffer_free(bb); | ||
339 | free(bb); | ||
340 | } | ||
341 | |||
342 | /*********************************************************************** | ||
343 | * | ||
344 | * Public class methods | ||
345 | * | ||
346 | ***********************************************************************/ | ||
347 | |||
348 | FLAC__bool FLAC__bitbuffer_init(FLAC__BitBuffer *bb) | ||
349 | { | ||
350 | FLAC__ASSERT(0 != bb); | ||
351 | |||
352 | bb->buffer = 0; | ||
353 | bb->capacity = 0; | ||
354 | bb->blurbs = bb->bits = bb->total_bits = 0; | ||
355 | bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; | ||
356 | |||
357 | return FLAC__bitbuffer_clear(bb); | ||
358 | } | ||
359 | |||
360 | FLAC__bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const FLAC__byte buffer[], unsigned bytes) | ||
361 | { | ||
362 | FLAC__ASSERT(0 != bb); | ||
363 | FLAC__ASSERT(bytes > 0); | ||
364 | |||
365 | if(!FLAC__bitbuffer_init(bb)) | ||
366 | return false; | ||
367 | |||
368 | if(!bitbuffer_ensure_size_(bb, bytes << 3)) | ||
369 | return false; | ||
370 | |||
371 | FLAC__ASSERT(0 != buffer); | ||
372 | /* @@@ WATCHOUT: code currently only works for 8-bits-per-blurb inclusive-or big-endian: */ | ||
373 | memcpy((FLAC__byte*)bb->buffer, buffer, sizeof(FLAC__byte)*bytes); | ||
374 | bb->blurbs = bytes / FLAC__BYTES_PER_BLURB; | ||
375 | bb->bits = (bytes % FLAC__BYTES_PER_BLURB) << 3; | ||
376 | bb->total_bits = bytes << 3; | ||
377 | return true; | ||
378 | } | ||
379 | |||
380 | FLAC__bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src) | ||
381 | { | ||
382 | unsigned bits_to_add = src->total_bits - src->total_consumed_bits; | ||
383 | |||
384 | FLAC__ASSERT(0 != dest); | ||
385 | FLAC__ASSERT(0 != src); | ||
386 | |||
387 | if(bits_to_add == 0) | ||
388 | return true; | ||
389 | if(dest->bits != src->consumed_bits) | ||
390 | return false; | ||
391 | if(!bitbuffer_ensure_size_(dest, bits_to_add)) | ||
392 | return false; | ||
393 | if(dest->bits == 0) { | ||
394 | memcpy(dest->buffer+dest->blurbs, src->buffer+src->consumed_blurbs, sizeof(FLAC__blurb)*(src->blurbs-src->consumed_blurbs + ((src->bits)? 1:0))); | ||
395 | } | ||
396 | else if(dest->bits + bits_to_add > FLAC__BITS_PER_BLURB) { | ||
397 | dest->buffer[dest->blurbs] <<= (FLAC__BITS_PER_BLURB - dest->bits); | ||
398 | dest->buffer[dest->blurbs] |= (src->buffer[src->consumed_blurbs] & ((1u << (FLAC__BITS_PER_BLURB-dest->bits)) - 1)); | ||
399 | memcpy(dest->buffer+dest->blurbs+1, src->buffer+src->consumed_blurbs+1, sizeof(FLAC__blurb)*(src->blurbs-src->consumed_blurbs-1 + ((src->bits)? 1:0))); | ||
400 | } | ||
401 | else { | ||
402 | dest->buffer[dest->blurbs] <<= bits_to_add; | ||
403 | dest->buffer[dest->blurbs] |= (src->buffer[src->consumed_blurbs] & ((1u << bits_to_add) - 1)); | ||
404 | } | ||
405 | dest->bits = src->bits; | ||
406 | dest->total_bits += bits_to_add; | ||
407 | dest->blurbs = dest->total_bits / FLAC__BITS_PER_BLURB; | ||
408 | |||
409 | return true; | ||
410 | } | ||
411 | |||
412 | void FLAC__bitbuffer_free(FLAC__BitBuffer *bb) | ||
413 | { | ||
414 | FLAC__ASSERT(0 != bb); | ||
415 | |||
416 | if(0 != bb->buffer) | ||
417 | free(bb->buffer); | ||
418 | bb->buffer = 0; | ||
419 | bb->capacity = 0; | ||
420 | bb->blurbs = bb->bits = bb->total_bits = 0; | ||
421 | bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; | ||
422 | } | ||
423 | |||
424 | FLAC__bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb) | ||
425 | { | ||
426 | if(bb->buffer == 0) { | ||
427 | bb->capacity = FLAC__BITBUFFER_DEFAULT_CAPACITY; | ||
428 | bb->buffer = (FLAC__blurb*)calloc(bb->capacity, sizeof(FLAC__blurb)); | ||
429 | if(bb->buffer == 0) | ||
430 | return false; | ||
431 | } | ||
432 | else { | ||
433 | memset(bb->buffer, 0, bb->blurbs + (bb->bits?1:0)); | ||
434 | } | ||
435 | bb->blurbs = bb->bits = bb->total_bits = 0; | ||
436 | bb->consumed_blurbs = bb->consumed_bits = bb->total_consumed_bits = 0; | ||
437 | return true; | ||
438 | } | ||
439 | |||
440 | FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src) | ||
441 | { | ||
442 | FLAC__ASSERT(0 != dest); | ||
443 | FLAC__ASSERT(0 != dest->buffer); | ||
444 | FLAC__ASSERT(0 != src); | ||
445 | FLAC__ASSERT(0 != src->buffer); | ||
446 | |||
447 | if(dest->capacity < src->capacity) | ||
448 | if(!bitbuffer_resize_(dest, src->capacity)) | ||
449 | return false; | ||
450 | memcpy(dest->buffer, src->buffer, sizeof(FLAC__blurb)*min(src->capacity, src->blurbs+1)); | ||
451 | dest->blurbs = src->blurbs; | ||
452 | dest->bits = src->bits; | ||
453 | dest->total_bits = src->total_bits; | ||
454 | dest->consumed_blurbs = src->consumed_blurbs; | ||
455 | dest->consumed_bits = src->consumed_bits; | ||
456 | dest->total_consumed_bits = src->total_consumed_bits; | ||
457 | dest->read_crc16 = src->read_crc16; | ||
458 | return true; | ||
459 | } | ||
460 | |||
461 | void FLAC__bitbuffer_reset_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed) | ||
462 | { | ||
463 | FLAC__ASSERT(0 != bb); | ||
464 | FLAC__ASSERT(0 != bb->buffer); | ||
465 | FLAC__ASSERT((bb->consumed_bits & 7) == 0); | ||
466 | |||
467 | bb->read_crc16 = seed; | ||
468 | #if FLAC__BITS_PER_BLURB == 8 | ||
469 | /* no need to do anything */ | ||
470 | #elif FLAC__BITS_PER_BLURB == 32 | ||
471 | bb->crc16_align = bb->consumed_bits; | ||
472 | #else | ||
473 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
474 | #endif | ||
475 | } | ||
476 | |||
477 | FLAC__uint16 FLAC__bitbuffer_get_read_crc16(FLAC__BitBuffer *bb) | ||
478 | { | ||
479 | FLAC__ASSERT(0 != bb); | ||
480 | FLAC__ASSERT(0 != bb->buffer); | ||
481 | FLAC__ASSERT((bb->bits & 7) == 0); | ||
482 | FLAC__ASSERT((bb->consumed_bits & 7) == 0); | ||
483 | |||
484 | #if FLAC__BITS_PER_BLURB == 8 | ||
485 | /* no need to do anything */ | ||
486 | #elif FLAC__BITS_PER_BLURB == 32 | ||
487 | /*@@@ BUG: even though this probably can't happen with FLAC, need to fix the case where we are called here for the very first blurb and crc16_align is > 0 */ | ||
488 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { | ||
489 | if(bb->consumed_bits == 8) { | ||
490 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
491 | FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16); | ||
492 | } | ||
493 | else if(bb->consumed_bits == 16) { | ||
494 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
495 | FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16); | ||
496 | FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16); | ||
497 | } | ||
498 | else if(bb->consumed_bits == 24) { | ||
499 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
500 | FLAC__CRC16_UPDATE(blurb >> 24, bb->read_crc16); | ||
501 | FLAC__CRC16_UPDATE((blurb >> 16) & 0xff, bb->read_crc16); | ||
502 | FLAC__CRC16_UPDATE((blurb >> 8) & 0xff, bb->read_crc16); | ||
503 | } | ||
504 | } | ||
505 | else { | ||
506 | if(bb->consumed_bits == 8) { | ||
507 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
508 | FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16); | ||
509 | } | ||
510 | else if(bb->consumed_bits == 16) { | ||
511 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
512 | FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16); | ||
513 | FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16); | ||
514 | } | ||
515 | else if(bb->consumed_bits == 24) { | ||
516 | const FLAC__blurb blurb = bb->buffer[bb->consumed_blurbs]; | ||
517 | FLAC__CRC16_UPDATE(blurb >> (bb->bits-8), bb->read_crc16); | ||
518 | FLAC__CRC16_UPDATE((blurb >> (bb->bits-16)) & 0xff, bb->read_crc16); | ||
519 | FLAC__CRC16_UPDATE((blurb >> (bb->bits-24)) & 0xff, bb->read_crc16); | ||
520 | } | ||
521 | } | ||
522 | bb->crc16_align = bb->consumed_bits; | ||
523 | #else | ||
524 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
525 | #endif | ||
526 | return bb->read_crc16; | ||
527 | } | ||
528 | |||
529 | FLAC__uint16 FLAC__bitbuffer_get_write_crc16(const FLAC__BitBuffer *bb) | ||
530 | { | ||
531 | FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */ | ||
532 | |||
533 | #if FLAC__BITS_PER_BLURB == 8 | ||
534 | return FLAC__crc16(bb->buffer, bb->blurbs); | ||
535 | #elif FLAC__BITS_PER_BLURB == 32 | ||
536 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
537 | return FLAC__crc16((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3)); | ||
538 | #else | ||
539 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
540 | #endif | ||
541 | } | ||
542 | |||
543 | FLAC__byte FLAC__bitbuffer_get_write_crc8(const FLAC__BitBuffer *bb) | ||
544 | { | ||
545 | FLAC__ASSERT(0 != bb); | ||
546 | FLAC__ASSERT((bb->bits & 7) == 0); /* assert that we're byte-aligned */ | ||
547 | FLAC__ASSERT(bb->buffer[0] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */ | ||
548 | #if FLAC__BITS_PER_BLURB == 8 | ||
549 | return FLAC__crc8(bb->buffer, bb->blurbs); | ||
550 | #elif FLAC__BITS_PER_BLURB == 32 | ||
551 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
552 | return FLAC__crc8((FLAC__byte*)(bb->buffer), (bb->blurbs * FLAC__BYTES_PER_BLURB) + (bb->bits >> 3)); | ||
553 | #else | ||
554 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
555 | #endif | ||
556 | } | ||
557 | |||
558 | FLAC__bool FLAC__bitbuffer_is_byte_aligned(const FLAC__BitBuffer *bb) | ||
559 | { | ||
560 | return ((bb->bits & 7) == 0); | ||
561 | } | ||
562 | |||
563 | FLAC__bool FLAC__bitbuffer_is_consumed_byte_aligned(const FLAC__BitBuffer *bb) | ||
564 | { | ||
565 | return ((bb->consumed_bits & 7) == 0); | ||
566 | } | ||
567 | |||
568 | unsigned FLAC__bitbuffer_bits_left_for_byte_alignment(const FLAC__BitBuffer *bb) | ||
569 | { | ||
570 | return 8 - (bb->consumed_bits & 7); | ||
571 | } | ||
572 | |||
573 | unsigned FLAC__bitbuffer_get_input_bytes_unconsumed(const FLAC__BitBuffer *bb) | ||
574 | { | ||
575 | FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0); | ||
576 | return (bb->total_bits - bb->total_consumed_bits) >> 3; | ||
577 | } | ||
578 | |||
579 | void FLAC__bitbuffer_get_buffer(FLAC__BitBuffer *bb, const FLAC__byte **buffer, unsigned *bytes) | ||
580 | { | ||
581 | FLAC__ASSERT((bb->consumed_bits & 7) == 0 && (bb->bits & 7) == 0); | ||
582 | #if FLAC__BITS_PER_BLURB == 8 | ||
583 | *buffer = bb->buffer + bb->consumed_blurbs; | ||
584 | *bytes = bb->blurbs - bb->consumed_blurbs; | ||
585 | #elif FLAC__BITS_PER_BLURB == 32 | ||
586 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
587 | *buffer = (FLAC__byte*)(bb->buffer + bb->consumed_blurbs) + (bb->consumed_bits >> 3); | ||
588 | *bytes = (bb->total_bits - bb->total_consumed_bits) >> 3; | ||
589 | #else | ||
590 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
591 | #endif | ||
592 | } | ||
593 | |||
594 | void FLAC__bitbuffer_release_buffer(FLAC__BitBuffer *bb) | ||
595 | { | ||
596 | #if FLAC__BITS_PER_BLURB == 8 | ||
597 | (void)bb; | ||
598 | #elif FLAC__BITS_PER_BLURB == 32 | ||
599 | /* @@@ WATCHOUT: code currently only works for big-endian: */ | ||
600 | (void)bb; | ||
601 | #else | ||
602 | FLAC__ASSERT(false); /* ERROR, only sizes of 8 and 32 are supported */ | ||
603 | #endif | ||
604 | } | ||
605 | |||
606 | FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits) | ||
607 | { | ||
608 | unsigned n; | ||
609 | |||
610 | FLAC__ASSERT(0 != bb); | ||
611 | FLAC__ASSERT(0 != bb->buffer); | ||
612 | |||
613 | if(bits == 0) | ||
614 | return true; | ||
615 | if(!bitbuffer_ensure_size_(bb, bits)) | ||
616 | return false; | ||
617 | bb->total_bits += bits; | ||
618 | while(bits > 0) { | ||
619 | n = min(FLAC__BITS_PER_BLURB - bb->bits, bits); | ||
620 | bb->buffer[bb->blurbs] <<= n; | ||
621 | bits -= n; | ||
622 | bb->bits += n; | ||
623 | if(bb->bits == FLAC__BITS_PER_BLURB) { | ||
624 | bb->blurbs++; | ||
625 | bb->bits = 0; | ||
626 | } | ||
627 | } | ||
628 | return true; | ||
629 | } | ||
630 | |||
631 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val, unsigned bits) | ||
632 | { | ||
633 | unsigned n, k; | ||
634 | |||
635 | FLAC__ASSERT(0 != bb); | ||
636 | FLAC__ASSERT(0 != bb->buffer); | ||
637 | |||
638 | FLAC__ASSERT(bits <= 32); | ||
639 | if(bits == 0) | ||
640 | return true; | ||
641 | /* inline the size check so we don't incure a function call unnecessarily */ | ||
642 | if(FLAC__BLURBS_TO_BITS(bb->capacity) < bb->total_bits + bits) { | ||
643 | if(!bitbuffer_ensure_size_(bb, bits)) | ||
644 | return false; | ||
645 | } | ||
646 | |||
647 | /* zero-out unused bits; WATCHOUT: other code relies on this, so this needs to stay */ | ||
648 | if(bits < 32) /* @@@ gcc seems to require this because the following line causes incorrect results when bits==32; investigate */ | ||
649 | val &= (~(0xffffffff << bits)); /* zero-out unused bits */ | ||
650 | |||
651 | bb->total_bits += bits; | ||
652 | while(bits > 0) { | ||
653 | n = FLAC__BITS_PER_BLURB - bb->bits; | ||
654 | if(n == FLAC__BITS_PER_BLURB) { /* i.e. bb->bits == 0 */ | ||
655 | if(bits < FLAC__BITS_PER_BLURB) { | ||
656 | bb->buffer[bb->blurbs] = (FLAC__blurb)val; | ||
657 | bb->bits = bits; | ||
658 | break; | ||
659 | } | ||
660 | else if(bits == FLAC__BITS_PER_BLURB) { | ||
661 | bb->buffer[bb->blurbs++] = (FLAC__blurb)val; | ||
662 | break; | ||
663 | } | ||
664 | else { | ||
665 | k = bits - FLAC__BITS_PER_BLURB; | ||
666 | bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k); | ||
667 | /* we know k < 32 so no need to protect against the gcc bug mentioned above */ | ||
668 | val &= (~(0xffffffff << k)); | ||
669 | bits -= FLAC__BITS_PER_BLURB; | ||
670 | } | ||
671 | } | ||
672 | else if(bits <= n) { | ||
673 | bb->buffer[bb->blurbs] <<= bits; | ||
674 | bb->buffer[bb->blurbs] |= val; | ||
675 | if(bits == n) { | ||
676 | bb->blurbs++; | ||
677 | bb->bits = 0; | ||
678 | } | ||
679 | else | ||
680 | bb->bits += bits; | ||
681 | break; | ||
682 | } | ||
683 | else { | ||
684 | k = bits - n; | ||
685 | bb->buffer[bb->blurbs] <<= n; | ||
686 | bb->buffer[bb->blurbs] |= (val >> k); | ||
687 | /* we know n > 0 so k < 32 so no need to protect against the gcc bug mentioned above */ | ||
688 | val &= (~(0xffffffff << k)); | ||
689 | bits -= n; | ||
690 | bb->blurbs++; | ||
691 | bb->bits = 0; | ||
692 | } | ||
693 | } | ||
694 | |||
695 | return true; | ||
696 | } | ||
697 | |||
698 | FLAC__bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 val, unsigned bits) | ||
699 | { | ||
700 | return FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)val, bits); | ||
701 | } | ||
702 | |||
703 | FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val, unsigned bits) | ||
704 | { | ||
705 | static const FLAC__uint64 mask[] = { | ||
706 | 0, | ||
707 | FLAC__U64L(0x0000000000000001), FLAC__U64L(0x0000000000000003), FLAC__U64L(0x0000000000000007), FLAC__U64L(0x000000000000000F), | ||
708 | FLAC__U64L(0x000000000000001F), FLAC__U64L(0x000000000000003F), FLAC__U64L(0x000000000000007F), FLAC__U64L(0x00000000000000FF), | ||
709 | FLAC__U64L(0x00000000000001FF), FLAC__U64L(0x00000000000003FF), FLAC__U64L(0x00000000000007FF), FLAC__U64L(0x0000000000000FFF), | ||
710 | FLAC__U64L(0x0000000000001FFF), FLAC__U64L(0x0000000000003FFF), FLAC__U64L(0x0000000000007FFF), FLAC__U64L(0x000000000000FFFF), | ||
711 | FLAC__U64L(0x000000000001FFFF), FLAC__U64L(0x000000000003FFFF), FLAC__U64L(0x000000000007FFFF), FLAC__U64L(0x00000000000FFFFF), | ||
712 | FLAC__U64L(0x00000000001FFFFF), FLAC__U64L(0x00000000003FFFFF), FLAC__U64L(0x00000000007FFFFF), FLAC__U64L(0x0000000000FFFFFF), | ||
713 | FLAC__U64L(0x0000000001FFFFFF), FLAC__U64L(0x0000000003FFFFFF), FLAC__U64L(0x0000000007FFFFFF), FLAC__U64L(0x000000000FFFFFFF), | ||
714 | FLAC__U64L(0x000000001FFFFFFF), FLAC__U64L(0x000000003FFFFFFF), FLAC__U64L(0x000000007FFFFFFF), FLAC__U64L(0x00000000FFFFFFFF), | ||
715 | FLAC__U64L(0x00000001FFFFFFFF), FLAC__U64L(0x00000003FFFFFFFF), FLAC__U64L(0x00000007FFFFFFFF), FLAC__U64L(0x0000000FFFFFFFFF), | ||
716 | FLAC__U64L(0x0000001FFFFFFFFF), FLAC__U64L(0x0000003FFFFFFFFF), FLAC__U64L(0x0000007FFFFFFFFF), FLAC__U64L(0x000000FFFFFFFFFF), | ||
717 | FLAC__U64L(0x000001FFFFFFFFFF), FLAC__U64L(0x000003FFFFFFFFFF), FLAC__U64L(0x000007FFFFFFFFFF), FLAC__U64L(0x00000FFFFFFFFFFF), | ||
718 | FLAC__U64L(0x00001FFFFFFFFFFF), FLAC__U64L(0x00003FFFFFFFFFFF), FLAC__U64L(0x00007FFFFFFFFFFF), FLAC__U64L(0x0000FFFFFFFFFFFF), | ||
719 | FLAC__U64L(0x0001FFFFFFFFFFFF), FLAC__U64L(0x0003FFFFFFFFFFFF), FLAC__U64L(0x0007FFFFFFFFFFFF), FLAC__U64L(0x000FFFFFFFFFFFFF), | ||
720 | FLAC__U64L(0x001FFFFFFFFFFFFF), FLAC__U64L(0x003FFFFFFFFFFFFF), FLAC__U64L(0x007FFFFFFFFFFFFF), FLAC__U64L(0x00FFFFFFFFFFFFFF), | ||
721 | FLAC__U64L(0x01FFFFFFFFFFFFFF), FLAC__U64L(0x03FFFFFFFFFFFFFF), FLAC__U64L(0x07FFFFFFFFFFFFFF), FLAC__U64L(0x0FFFFFFFFFFFFFFF), | ||
722 | FLAC__U64L(0x1FFFFFFFFFFFFFFF), FLAC__U64L(0x3FFFFFFFFFFFFFFF), FLAC__U64L(0x7FFFFFFFFFFFFFFF), FLAC__U64L(0xFFFFFFFFFFFFFFFF) | ||
723 | }; | ||
724 | unsigned n, k; | ||
725 | |||
726 | FLAC__ASSERT(0 != bb); | ||
727 | FLAC__ASSERT(0 != bb->buffer); | ||
728 | |||
729 | FLAC__ASSERT(bits <= 64); | ||
730 | if(bits == 0) | ||
731 | return true; | ||
732 | if(!bitbuffer_ensure_size_(bb, bits)) | ||
733 | return false; | ||
734 | val &= mask[bits]; | ||
735 | bb->total_bits += bits; | ||
736 | while(bits > 0) { | ||
737 | if(bb->bits == 0) { | ||
738 | if(bits < FLAC__BITS_PER_BLURB) { | ||
739 | bb->buffer[bb->blurbs] = (FLAC__blurb)val; | ||
740 | bb->bits = bits; | ||
741 | break; | ||
742 | } | ||
743 | else if(bits == FLAC__BITS_PER_BLURB) { | ||
744 | bb->buffer[bb->blurbs++] = (FLAC__blurb)val; | ||
745 | break; | ||
746 | } | ||
747 | else { | ||
748 | k = bits - FLAC__BITS_PER_BLURB; | ||
749 | bb->buffer[bb->blurbs++] = (FLAC__blurb)(val >> k); | ||
750 | /* we know k < 64 so no need to protect against the gcc bug mentioned above */ | ||
751 | val &= (~(FLAC__U64L(0xffffffffffffffff) << k)); | ||
752 | bits -= FLAC__BITS_PER_BLURB; | ||
753 | } | ||
754 | } | ||
755 | else { | ||
756 | n = min(FLAC__BITS_PER_BLURB - bb->bits, bits); | ||
757 | k = bits - n; | ||
758 | bb->buffer[bb->blurbs] <<= n; | ||
759 | bb->buffer[bb->blurbs] |= (val >> k); | ||
760 | /* we know n > 0 so k < 64 so no need to protect against the gcc bug mentioned above */ | ||
761 | val &= (~(FLAC__U64L(0xffffffffffffffff) << k)); | ||
762 | bits -= n; | ||
763 | bb->bits += n; | ||
764 | if(bb->bits == FLAC__BITS_PER_BLURB) { | ||
765 | bb->blurbs++; | ||
766 | bb->bits = 0; | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | |||
771 | return true; | ||
772 | } | ||
773 | |||
774 | #if 0 /* UNUSED */ | ||
775 | FLAC__bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 val, unsigned bits) | ||
776 | { | ||
777 | return FLAC__bitbuffer_write_raw_uint64(bb, (FLAC__uint64)val, bits); | ||
778 | } | ||
779 | #endif | ||
780 | |||
781 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 val) | ||
782 | { | ||
783 | /* this doesn't need to be that fast as currently it is only used for vorbis comments */ | ||
784 | |||
785 | /* NOTE: we rely on the fact that FLAC__bitbuffer_write_raw_uint32() masks out the unused bits */ | ||
786 | if(!FLAC__bitbuffer_write_raw_uint32(bb, val, 8)) | ||
787 | return false; | ||
788 | if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>8, 8)) | ||
789 | return false; | ||
790 | if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>16, 8)) | ||
791 | return false; | ||
792 | if(!FLAC__bitbuffer_write_raw_uint32(bb, val>>24, 8)) | ||
793 | return false; | ||
794 | |||
795 | return true; | ||
796 | } | ||
797 | |||
798 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_write_byte_block(FLAC__BitBuffer *bb, const FLAC__byte vals[], unsigned nvals) | ||
799 | { | ||
800 | unsigned i; | ||
801 | |||
802 | /* this could be faster but currently we don't need it to be */ | ||
803 | for(i = 0; i < nvals; i++) { | ||
804 | if(!FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)(vals[i]), 8)) | ||
805 | return false; | ||
806 | } | ||
807 | |||
808 | return true; | ||
809 | } | ||
810 | |||
811 | FLAC__bool FLAC__bitbuffer_write_unary_unsigned(FLAC__BitBuffer *bb, unsigned val) | ||
812 | { | ||
813 | if(val < 32) | ||
814 | return FLAC__bitbuffer_write_raw_uint32(bb, 1, ++val); | ||
815 | else if(val < 64) | ||
816 | return FLAC__bitbuffer_write_raw_uint64(bb, 1, ++val); | ||
817 | else { | ||
818 | if(!FLAC__bitbuffer_write_zeroes(bb, val)) | ||
819 | return false; | ||
820 | return FLAC__bitbuffer_write_raw_uint32(bb, 1, 1); | ||
821 | } | ||
822 | } | ||
823 | |||
824 | unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter) | ||
825 | { | ||
826 | unsigned msbs, uval; | ||
827 | |||
828 | /* fold signed to unsigned */ | ||
829 | if(val < 0) | ||
830 | /* equivalent to | ||
831 | * (unsigned)(((--val) << 1) - 1); | ||
832 | * but without the overflow problem at MININT | ||
833 | */ | ||
834 | uval = (unsigned)(((-(++val)) << 1) + 1); | ||
835 | else | ||
836 | uval = (unsigned)(val << 1); | ||
837 | |||
838 | msbs = uval >> parameter; | ||
839 | |||
840 | return 1 + parameter + msbs; | ||
841 | } | ||
842 | |||
843 | #if 0 /* UNUSED */ | ||
844 | unsigned FLAC__bitbuffer_golomb_bits_signed(int val, unsigned parameter) | ||
845 | { | ||
846 | unsigned bits, msbs, uval; | ||
847 | unsigned k; | ||
848 | |||
849 | FLAC__ASSERT(parameter > 0); | ||
850 | |||
851 | /* fold signed to unsigned */ | ||
852 | if(val < 0) | ||
853 | /* equivalent to | ||
854 | * (unsigned)(((--val) << 1) - 1); | ||
855 | * but without the overflow problem at MININT | ||
856 | */ | ||
857 | uval = (unsigned)(((-(++val)) << 1) + 1); | ||
858 | else | ||
859 | uval = (unsigned)(val << 1); | ||
860 | |||
861 | k = FLAC__bitmath_ilog2(parameter); | ||
862 | if(parameter == 1u<<k) { | ||
863 | FLAC__ASSERT(k <= 30); | ||
864 | |||
865 | msbs = uval >> k; | ||
866 | bits = 1 + k + msbs; | ||
867 | } | ||
868 | else { | ||
869 | unsigned q, r, d; | ||
870 | |||
871 | d = (1 << (k+1)) - parameter; | ||
872 | q = uval / parameter; | ||
873 | r = uval - (q * parameter); | ||
874 | |||
875 | bits = 1 + q + k; | ||
876 | if(r >= d) | ||
877 | bits++; | ||
878 | } | ||
879 | return bits; | ||
880 | } | ||
881 | |||
882 | unsigned FLAC__bitbuffer_golomb_bits_unsigned(unsigned uval, unsigned parameter) | ||
883 | { | ||
884 | unsigned bits, msbs; | ||
885 | unsigned k; | ||
886 | |||
887 | FLAC__ASSERT(parameter > 0); | ||
888 | |||
889 | k = FLAC__bitmath_ilog2(parameter); | ||
890 | if(parameter == 1u<<k) { | ||
891 | FLAC__ASSERT(k <= 30); | ||
892 | |||
893 | msbs = uval >> k; | ||
894 | bits = 1 + k + msbs; | ||
895 | } | ||
896 | else { | ||
897 | unsigned q, r, d; | ||
898 | |||
899 | d = (1 << (k+1)) - parameter; | ||
900 | q = uval / parameter; | ||
901 | r = uval - (q * parameter); | ||
902 | |||
903 | bits = 1 + q + k; | ||
904 | if(r >= d) | ||
905 | bits++; | ||
906 | } | ||
907 | return bits; | ||
908 | } | ||
909 | #endif /* UNUSED */ | ||
910 | |||
911 | #ifdef FLAC__SYMMETRIC_RICE | ||
912 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) | ||
913 | { | ||
914 | unsigned total_bits, interesting_bits, msbs; | ||
915 | FLAC__uint32 pattern; | ||
916 | |||
917 | FLAC__ASSERT(0 != bb); | ||
918 | FLAC__ASSERT(0 != bb->buffer); | ||
919 | FLAC__ASSERT(parameter <= 31); | ||
920 | |||
921 | /* init pattern with the unary end bit and the sign bit */ | ||
922 | if(val < 0) { | ||
923 | pattern = 3; | ||
924 | val = -val; | ||
925 | } | ||
926 | else | ||
927 | pattern = 2; | ||
928 | |||
929 | msbs = val >> parameter; | ||
930 | interesting_bits = 2 + parameter; | ||
931 | total_bits = interesting_bits + msbs; | ||
932 | pattern <<= parameter; | ||
933 | pattern |= (val & ((1<<parameter)-1)); /* the binary LSBs */ | ||
934 | |||
935 | if(total_bits <= 32) { | ||
936 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
937 | return false; | ||
938 | } | ||
939 | else { | ||
940 | /* write the unary MSBs */ | ||
941 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
942 | return false; | ||
943 | /* write the unary end bit, the sign bit, and binary LSBs */ | ||
944 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, interesting_bits)) | ||
945 | return false; | ||
946 | } | ||
947 | return true; | ||
948 | } | ||
949 | |||
950 | #if 0 /* UNUSED */ | ||
951 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow) | ||
952 | { | ||
953 | unsigned total_bits, interesting_bits, msbs; | ||
954 | FLAC__uint32 pattern; | ||
955 | |||
956 | FLAC__ASSERT(0 != bb); | ||
957 | FLAC__ASSERT(0 != bb->buffer); | ||
958 | FLAC__ASSERT(parameter <= 31); | ||
959 | |||
960 | *overflow = false; | ||
961 | |||
962 | /* init pattern with the unary end bit and the sign bit */ | ||
963 | if(val < 0) { | ||
964 | pattern = 3; | ||
965 | val = -val; | ||
966 | } | ||
967 | else | ||
968 | pattern = 2; | ||
969 | |||
970 | msbs = val >> parameter; | ||
971 | interesting_bits = 2 + parameter; | ||
972 | total_bits = interesting_bits + msbs; | ||
973 | pattern <<= parameter; | ||
974 | pattern |= (val & ((1<<parameter)-1)); /* the binary LSBs */ | ||
975 | |||
976 | if(total_bits <= 32) { | ||
977 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
978 | return false; | ||
979 | } | ||
980 | else if(total_bits > max_bits) { | ||
981 | *overflow = true; | ||
982 | return true; | ||
983 | } | ||
984 | else { | ||
985 | /* write the unary MSBs */ | ||
986 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
987 | return false; | ||
988 | /* write the unary end bit, the sign bit, and binary LSBs */ | ||
989 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, interesting_bits)) | ||
990 | return false; | ||
991 | } | ||
992 | return true; | ||
993 | } | ||
994 | #endif /* UNUSED */ | ||
995 | |||
996 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter) | ||
997 | { | ||
998 | unsigned total_bits, val_bits; | ||
999 | FLAC__uint32 pattern; | ||
1000 | |||
1001 | FLAC__ASSERT(0 != bb); | ||
1002 | FLAC__ASSERT(0 != bb->buffer); | ||
1003 | FLAC__ASSERT(parameter <= 31); | ||
1004 | |||
1005 | val_bits = FLAC__bitmath_silog2(val); | ||
1006 | total_bits = 2 + parameter + 5 + val_bits; | ||
1007 | |||
1008 | if(total_bits <= 32) { | ||
1009 | pattern = 3; | ||
1010 | pattern <<= (parameter + 5); | ||
1011 | pattern |= val_bits; | ||
1012 | pattern <<= val_bits; | ||
1013 | pattern |= (val & ((1 << val_bits) - 1)); | ||
1014 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
1015 | return false; | ||
1016 | } | ||
1017 | else { | ||
1018 | /* write the '-0' escape code first */ | ||
1019 | if(!FLAC__bitbuffer_write_raw_uint32(bb, 3u << parameter, 2+parameter)) | ||
1020 | return false; | ||
1021 | /* write the length */ | ||
1022 | if(!FLAC__bitbuffer_write_raw_uint32(bb, val_bits, 5)) | ||
1023 | return false; | ||
1024 | /* write the value */ | ||
1025 | if(!FLAC__bitbuffer_write_raw_int32(bb, val, val_bits)) | ||
1026 | return false; | ||
1027 | } | ||
1028 | return true; | ||
1029 | } | ||
1030 | #endif /* ifdef FLAC__SYMMETRIC_RICE */ | ||
1031 | |||
1032 | FLAC__bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) | ||
1033 | { | ||
1034 | unsigned total_bits, interesting_bits, msbs, uval; | ||
1035 | FLAC__uint32 pattern; | ||
1036 | |||
1037 | FLAC__ASSERT(0 != bb); | ||
1038 | FLAC__ASSERT(0 != bb->buffer); | ||
1039 | FLAC__ASSERT(parameter <= 30); | ||
1040 | |||
1041 | /* fold signed to unsigned */ | ||
1042 | if(val < 0) | ||
1043 | /* equivalent to | ||
1044 | * (unsigned)(((--val) << 1) - 1); | ||
1045 | * but without the overflow problem at MININT | ||
1046 | */ | ||
1047 | uval = (unsigned)(((-(++val)) << 1) + 1); | ||
1048 | else | ||
1049 | uval = (unsigned)(val << 1); | ||
1050 | |||
1051 | msbs = uval >> parameter; | ||
1052 | interesting_bits = 1 + parameter; | ||
1053 | total_bits = interesting_bits + msbs; | ||
1054 | pattern = 1 << parameter; /* the unary end bit */ | ||
1055 | pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */ | ||
1056 | |||
1057 | if(total_bits <= 32) { | ||
1058 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
1059 | return false; | ||
1060 | } | ||
1061 | else { | ||
1062 | /* write the unary MSBs */ | ||
1063 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
1064 | return false; | ||
1065 | /* write the unary end bit and binary LSBs */ | ||
1066 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, interesting_bits)) | ||
1067 | return false; | ||
1068 | } | ||
1069 | return true; | ||
1070 | } | ||
1071 | |||
1072 | #if 0 /* UNUSED */ | ||
1073 | FLAC__bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow) | ||
1074 | { | ||
1075 | unsigned total_bits, interesting_bits, msbs, uval; | ||
1076 | FLAC__uint32 pattern; | ||
1077 | |||
1078 | FLAC__ASSERT(0 != bb); | ||
1079 | FLAC__ASSERT(0 != bb->buffer); | ||
1080 | FLAC__ASSERT(parameter <= 30); | ||
1081 | |||
1082 | *overflow = false; | ||
1083 | |||
1084 | /* fold signed to unsigned */ | ||
1085 | if(val < 0) | ||
1086 | /* equivalent to | ||
1087 | * (unsigned)(((--val) << 1) - 1); | ||
1088 | * but without the overflow problem at MININT | ||
1089 | */ | ||
1090 | uval = (unsigned)(((-(++val)) << 1) + 1); | ||
1091 | else | ||
1092 | uval = (unsigned)(val << 1); | ||
1093 | |||
1094 | msbs = uval >> parameter; | ||
1095 | interesting_bits = 1 + parameter; | ||
1096 | total_bits = interesting_bits + msbs; | ||
1097 | pattern = 1 << parameter; /* the unary end bit */ | ||
1098 | pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */ | ||
1099 | |||
1100 | if(total_bits <= 32) { | ||
1101 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
1102 | return false; | ||
1103 | } | ||
1104 | else if(total_bits > max_bits) { | ||
1105 | *overflow = true; | ||
1106 | return true; | ||
1107 | } | ||
1108 | else { | ||
1109 | /* write the unary MSBs */ | ||
1110 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
1111 | return false; | ||
1112 | /* write the unary end bit and binary LSBs */ | ||
1113 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, interesting_bits)) | ||
1114 | return false; | ||
1115 | } | ||
1116 | return true; | ||
1117 | } | ||
1118 | #endif /* UNUSED */ | ||
1119 | |||
1120 | #if 0 /* UNUSED */ | ||
1121 | FLAC__bool FLAC__bitbuffer_write_golomb_signed(FLAC__BitBuffer *bb, int val, unsigned parameter) | ||
1122 | { | ||
1123 | unsigned total_bits, msbs, uval; | ||
1124 | unsigned k; | ||
1125 | |||
1126 | FLAC__ASSERT(0 != bb); | ||
1127 | FLAC__ASSERT(0 != bb->buffer); | ||
1128 | FLAC__ASSERT(parameter > 0); | ||
1129 | |||
1130 | /* fold signed to unsigned */ | ||
1131 | if(val < 0) | ||
1132 | /* equivalent to | ||
1133 | * (unsigned)(((--val) << 1) - 1); | ||
1134 | * but without the overflow problem at MININT | ||
1135 | */ | ||
1136 | uval = (unsigned)(((-(++val)) << 1) + 1); | ||
1137 | else | ||
1138 | uval = (unsigned)(val << 1); | ||
1139 | |||
1140 | k = FLAC__bitmath_ilog2(parameter); | ||
1141 | if(parameter == 1u<<k) { | ||
1142 | unsigned pattern; | ||
1143 | |||
1144 | FLAC__ASSERT(k <= 30); | ||
1145 | |||
1146 | msbs = uval >> k; | ||
1147 | total_bits = 1 + k + msbs; | ||
1148 | pattern = 1 << k; /* the unary end bit */ | ||
1149 | pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | ||
1150 | |||
1151 | if(total_bits <= 32) { | ||
1152 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
1153 | return false; | ||
1154 | } | ||
1155 | else { | ||
1156 | /* write the unary MSBs */ | ||
1157 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
1158 | return false; | ||
1159 | /* write the unary end bit and binary LSBs */ | ||
1160 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, k+1)) | ||
1161 | return false; | ||
1162 | } | ||
1163 | } | ||
1164 | else { | ||
1165 | unsigned q, r, d; | ||
1166 | |||
1167 | d = (1 << (k+1)) - parameter; | ||
1168 | q = uval / parameter; | ||
1169 | r = uval - (q * parameter); | ||
1170 | /* write the unary MSBs */ | ||
1171 | if(!FLAC__bitbuffer_write_zeroes(bb, q)) | ||
1172 | return false; | ||
1173 | /* write the unary end bit */ | ||
1174 | if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1)) | ||
1175 | return false; | ||
1176 | /* write the binary LSBs */ | ||
1177 | if(r >= d) { | ||
1178 | if(!FLAC__bitbuffer_write_raw_uint32(bb, r+d, k+1)) | ||
1179 | return false; | ||
1180 | } | ||
1181 | else { | ||
1182 | if(!FLAC__bitbuffer_write_raw_uint32(bb, r, k)) | ||
1183 | return false; | ||
1184 | } | ||
1185 | } | ||
1186 | return true; | ||
1187 | } | ||
1188 | |||
1189 | FLAC__bool FLAC__bitbuffer_write_golomb_unsigned(FLAC__BitBuffer *bb, unsigned uval, unsigned parameter) | ||
1190 | { | ||
1191 | unsigned total_bits, msbs; | ||
1192 | unsigned k; | ||
1193 | |||
1194 | FLAC__ASSERT(0 != bb); | ||
1195 | FLAC__ASSERT(0 != bb->buffer); | ||
1196 | FLAC__ASSERT(parameter > 0); | ||
1197 | |||
1198 | k = FLAC__bitmath_ilog2(parameter); | ||
1199 | if(parameter == 1u<<k) { | ||
1200 | unsigned pattern; | ||
1201 | |||
1202 | FLAC__ASSERT(k <= 30); | ||
1203 | |||
1204 | msbs = uval >> k; | ||
1205 | total_bits = 1 + k + msbs; | ||
1206 | pattern = 1 << k; /* the unary end bit */ | ||
1207 | pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | ||
1208 | |||
1209 | if(total_bits <= 32) { | ||
1210 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, total_bits)) | ||
1211 | return false; | ||
1212 | } | ||
1213 | else { | ||
1214 | /* write the unary MSBs */ | ||
1215 | if(!FLAC__bitbuffer_write_zeroes(bb, msbs)) | ||
1216 | return false; | ||
1217 | /* write the unary end bit and binary LSBs */ | ||
1218 | if(!FLAC__bitbuffer_write_raw_uint32(bb, pattern, k+1)) | ||
1219 | return false; | ||
1220 | } | ||
1221 | } | ||
1222 | else { | ||
1223 | unsigned q, r, d; | ||
1224 | |||
1225 | d = (1 << (k+1)) - parameter; | ||
1226 | q = uval / parameter; | ||
1227 | r = uval - (q * parameter); | ||
1228 | /* write the unary MSBs */ | ||
1229 | if(!FLAC__bitbuffer_write_zeroes(bb, q)) | ||
1230 | return false; | ||
1231 | /* write the unary end bit */ | ||
1232 | if(!FLAC__bitbuffer_write_raw_uint32(bb, 1, 1)) | ||
1233 | return false; | ||
1234 | /* write the binary LSBs */ | ||
1235 | if(r >= d) { | ||
1236 | if(!FLAC__bitbuffer_write_raw_uint32(bb, r+d, k+1)) | ||
1237 | return false; | ||
1238 | } | ||
1239 | else { | ||
1240 | if(!FLAC__bitbuffer_write_raw_uint32(bb, r, k)) | ||
1241 | return false; | ||
1242 | } | ||
1243 | } | ||
1244 | return true; | ||
1245 | } | ||
1246 | #endif /* UNUSED */ | ||
1247 | |||
1248 | FLAC__bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val) | ||
1249 | { | ||
1250 | FLAC__bool ok = 1; | ||
1251 | |||
1252 | FLAC__ASSERT(0 != bb); | ||
1253 | FLAC__ASSERT(0 != bb->buffer); | ||
1254 | |||
1255 | FLAC__ASSERT(!(val & 0x80000000)); /* this version only handles 31 bits */ | ||
1256 | |||
1257 | if(val < 0x80) { | ||
1258 | return FLAC__bitbuffer_write_raw_uint32(bb, val, 8); | ||
1259 | } | ||
1260 | else if(val < 0x800) { | ||
1261 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (val>>6), 8); | ||
1262 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); | ||
1263 | } | ||
1264 | else if(val < 0x10000) { | ||
1265 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (val>>12), 8); | ||
1266 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); | ||
1267 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); | ||
1268 | } | ||
1269 | else if(val < 0x200000) { | ||
1270 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (val>>18), 8); | ||
1271 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); | ||
1272 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); | ||
1273 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); | ||
1274 | } | ||
1275 | else if(val < 0x4000000) { | ||
1276 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (val>>24), 8); | ||
1277 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8); | ||
1278 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); | ||
1279 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); | ||
1280 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); | ||
1281 | } | ||
1282 | else { | ||
1283 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (val>>30), 8); | ||
1284 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>24)&0x3F), 8); | ||
1285 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>18)&0x3F), 8); | ||
1286 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>12)&0x3F), 8); | ||
1287 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | ((val>>6)&0x3F), 8); | ||
1288 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (val&0x3F), 8); | ||
1289 | } | ||
1290 | |||
1291 | return ok; | ||
1292 | } | ||
1293 | |||
1294 | FLAC__bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val) | ||
1295 | { | ||
1296 | FLAC__bool ok = 1; | ||
1297 | |||
1298 | FLAC__ASSERT(0 != bb); | ||
1299 | FLAC__ASSERT(0 != bb->buffer); | ||
1300 | |||
1301 | FLAC__ASSERT(!(val & FLAC__U64L(0xFFFFFFF000000000))); /* this version only handles 36 bits */ | ||
1302 | |||
1303 | if(val < 0x80) { | ||
1304 | return FLAC__bitbuffer_write_raw_uint32(bb, (FLAC__uint32)val, 8); | ||
1305 | } | ||
1306 | else if(val < 0x800) { | ||
1307 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xC0 | (FLAC__uint32)(val>>6), 8); | ||
1308 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1309 | } | ||
1310 | else if(val < 0x10000) { | ||
1311 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xE0 | (FLAC__uint32)(val>>12), 8); | ||
1312 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | ||
1313 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1314 | } | ||
1315 | else if(val < 0x200000) { | ||
1316 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF0 | (FLAC__uint32)(val>>18), 8); | ||
1317 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | ||
1318 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | ||
1319 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1320 | } | ||
1321 | else if(val < 0x4000000) { | ||
1322 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xF8 | (FLAC__uint32)(val>>24), 8); | ||
1323 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | ||
1324 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | ||
1325 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | ||
1326 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1327 | } | ||
1328 | else if(val < 0x80000000) { | ||
1329 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFC | (FLAC__uint32)(val>>30), 8); | ||
1330 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | ||
1331 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | ||
1332 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | ||
1333 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | ||
1334 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1335 | } | ||
1336 | else { | ||
1337 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0xFE, 8); | ||
1338 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8); | ||
1339 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | ||
1340 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | ||
1341 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | ||
1342 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | ||
1343 | ok &= FLAC__bitbuffer_write_raw_uint32(bb, 0x80 | (FLAC__uint32)(val&0x3F), 8); | ||
1344 | } | ||
1345 | |||
1346 | return ok; | ||
1347 | } | ||
1348 | |||
1349 | FLAC__bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb) | ||
1350 | { | ||
1351 | /* 0-pad to byte boundary */ | ||
1352 | if(bb->bits & 7u) | ||
1353 | return FLAC__bitbuffer_write_zeroes(bb, 8 - (bb->bits & 7u)); | ||
1354 | else | ||
1355 | return true; | ||
1356 | } | ||
1357 | |||
1358 | FLAC__bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1359 | { | ||
1360 | /* to avoid a drastic speed penalty we don't: | ||
1361 | FLAC__ASSERT(0 != bb); | ||
1362 | FLAC__ASSERT(0 != bb->buffer); | ||
1363 | FLAC__ASSERT(bb->bits == 0); | ||
1364 | */ | ||
1365 | |||
1366 | while(1) { | ||
1367 | if(bb->total_consumed_bits < bb->total_bits) { | ||
1368 | *val = (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; | ||
1369 | return true; | ||
1370 | } | ||
1371 | else { | ||
1372 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1373 | return false; | ||
1374 | } | ||
1375 | } | ||
1376 | } | ||
1377 | |||
1378 | FLAC__bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1379 | { | ||
1380 | /* to avoid a drastic speed penalty we don't: | ||
1381 | FLAC__ASSERT(0 != bb); | ||
1382 | FLAC__ASSERT(0 != bb->buffer); | ||
1383 | FLAC__ASSERT(bb->bits == 0); | ||
1384 | */ | ||
1385 | |||
1386 | while(1) { | ||
1387 | if(bb->total_consumed_bits < bb->total_bits) { | ||
1388 | *val = (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; | ||
1389 | bb->consumed_bits++; | ||
1390 | if(bb->consumed_bits == FLAC__BITS_PER_BLURB) { | ||
1391 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1392 | bb->consumed_blurbs++; | ||
1393 | bb->consumed_bits = 0; | ||
1394 | } | ||
1395 | bb->total_consumed_bits++; | ||
1396 | return true; | ||
1397 | } | ||
1398 | else { | ||
1399 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1400 | return false; | ||
1401 | } | ||
1402 | } | ||
1403 | } | ||
1404 | |||
1405 | FLAC__bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1406 | { | ||
1407 | /* to avoid a drastic speed penalty we don't: | ||
1408 | FLAC__ASSERT(0 != bb); | ||
1409 | FLAC__ASSERT(0 != bb->buffer); | ||
1410 | FLAC__ASSERT(bb->bits == 0); | ||
1411 | */ | ||
1412 | |||
1413 | while(1) { | ||
1414 | if(bb->total_consumed_bits < bb->total_bits) { | ||
1415 | *val <<= 1; | ||
1416 | *val |= (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; | ||
1417 | bb->consumed_bits++; | ||
1418 | if(bb->consumed_bits == FLAC__BITS_PER_BLURB) { | ||
1419 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1420 | bb->consumed_blurbs++; | ||
1421 | bb->consumed_bits = 0; | ||
1422 | } | ||
1423 | bb->total_consumed_bits++; | ||
1424 | return true; | ||
1425 | } | ||
1426 | else { | ||
1427 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1428 | return false; | ||
1429 | } | ||
1430 | } | ||
1431 | } | ||
1432 | |||
1433 | FLAC__bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1434 | { | ||
1435 | /* to avoid a drastic speed penalty we don't: | ||
1436 | FLAC__ASSERT(0 != bb); | ||
1437 | FLAC__ASSERT(0 != bb->buffer); | ||
1438 | FLAC__ASSERT(bb->bits == 0); | ||
1439 | */ | ||
1440 | |||
1441 | while(1) { | ||
1442 | if(bb->total_consumed_bits < bb->total_bits) { | ||
1443 | *val <<= 1; | ||
1444 | *val |= (bb->buffer[bb->consumed_blurbs] & BLURB_BIT_TO_MASK(bb->consumed_bits))? 1 : 0; | ||
1445 | bb->consumed_bits++; | ||
1446 | if(bb->consumed_bits == FLAC__BITS_PER_BLURB) { | ||
1447 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1448 | bb->consumed_blurbs++; | ||
1449 | bb->consumed_bits = 0; | ||
1450 | } | ||
1451 | bb->total_consumed_bits++; | ||
1452 | return true; | ||
1453 | } | ||
1454 | else { | ||
1455 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1456 | return false; | ||
1457 | } | ||
1458 | } | ||
1459 | } | ||
1460 | |||
1461 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1462 | #ifdef FLAC__NO_MANUAL_INLINING | ||
1463 | { | ||
1464 | unsigned i; | ||
1465 | |||
1466 | FLAC__ASSERT(0 != bb); | ||
1467 | FLAC__ASSERT(0 != bb->buffer); | ||
1468 | |||
1469 | FLAC__ASSERT(bits <= 32); | ||
1470 | |||
1471 | *val = 0; | ||
1472 | for(i = 0; i < bits; i++) { | ||
1473 | if(!FLAC__bitbuffer_read_bit_to_uint32(bb, val, read_callback, client_data)) | ||
1474 | return false; | ||
1475 | } | ||
1476 | return true; | ||
1477 | } | ||
1478 | #else | ||
1479 | { | ||
1480 | unsigned i, bits_ = bits; | ||
1481 | FLAC__uint32 v = 0; | ||
1482 | |||
1483 | FLAC__ASSERT(0 != bb); | ||
1484 | FLAC__ASSERT(0 != bb->buffer); | ||
1485 | |||
1486 | FLAC__ASSERT(bits <= 32); | ||
1487 | FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits); | ||
1488 | |||
1489 | if(bits == 0) { | ||
1490 | *val = 0; | ||
1491 | return true; | ||
1492 | } | ||
1493 | |||
1494 | while(bb->total_consumed_bits + bits > bb->total_bits) { | ||
1495 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1496 | return false; | ||
1497 | } | ||
1498 | #if FLAC__BITS_PER_BLURB > 8 | ||
1499 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/ | ||
1500 | #endif | ||
1501 | if(bb->consumed_bits) { | ||
1502 | i = FLAC__BITS_PER_BLURB - bb->consumed_bits; | ||
1503 | if(i <= bits_) { | ||
1504 | v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits); | ||
1505 | bits_ -= i; | ||
1506 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1507 | bb->consumed_blurbs++; | ||
1508 | bb->consumed_bits = 0; | ||
1509 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1510 | } | ||
1511 | else { | ||
1512 | *val = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits)) >> (i-bits_); | ||
1513 | bb->consumed_bits += bits_; | ||
1514 | bb->total_consumed_bits += bits_; | ||
1515 | return true; | ||
1516 | } | ||
1517 | } | ||
1518 | #if FLAC__BITS_PER_BLURB == 32 | ||
1519 | /* note that we know bits_ cannot be > 32 because of previous assertions */ | ||
1520 | if(bits_ == FLAC__BITS_PER_BLURB) { | ||
1521 | v = bb->buffer[bb->consumed_blurbs]; | ||
1522 | CRC16_UPDATE_BLURB(bb, v, bb->read_crc16); | ||
1523 | bb->consumed_blurbs++; | ||
1524 | /* bb->consumed_bits is already 0 */ | ||
1525 | bb->total_consumed_bits += bits; | ||
1526 | *val = v; | ||
1527 | return true; | ||
1528 | } | ||
1529 | #else | ||
1530 | while(bits_ >= FLAC__BITS_PER_BLURB) { | ||
1531 | v <<= FLAC__BITS_PER_BLURB; | ||
1532 | v |= bb->buffer[bb->consumed_blurbs]; | ||
1533 | bits_ -= FLAC__BITS_PER_BLURB; | ||
1534 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1535 | bb->consumed_blurbs++; | ||
1536 | /* bb->consumed_bits is already 0 */ | ||
1537 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1538 | } | ||
1539 | #endif | ||
1540 | if(bits_ > 0) { | ||
1541 | v <<= bits_; | ||
1542 | v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_)); | ||
1543 | bb->consumed_bits = bits_; | ||
1544 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1545 | } | ||
1546 | bb->total_consumed_bits += bits; | ||
1547 | *val = v; | ||
1548 | #if FLAC__BITS_PER_BLURB > 8 | ||
1549 | } | ||
1550 | else { | ||
1551 | *val = 0; | ||
1552 | for(i = 0; i < bits; i++) { | ||
1553 | if(!FLAC__bitbuffer_read_bit_to_uint32(bb, val, read_callback, client_data)) | ||
1554 | return false; | ||
1555 | } | ||
1556 | } | ||
1557 | #endif | ||
1558 | return true; | ||
1559 | } | ||
1560 | #endif | ||
1561 | |||
1562 | FLAC__bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1563 | #ifdef FLAC__NO_MANUAL_INLINING | ||
1564 | { | ||
1565 | unsigned i; | ||
1566 | FLAC__uint32 v; | ||
1567 | |||
1568 | FLAC__ASSERT(0 != bb); | ||
1569 | FLAC__ASSERT(0 != bb->buffer); | ||
1570 | |||
1571 | FLAC__ASSERT(bits <= 32); | ||
1572 | |||
1573 | if(bits == 0) { | ||
1574 | *val = 0; | ||
1575 | return true; | ||
1576 | } | ||
1577 | |||
1578 | v = 0; | ||
1579 | for(i = 0; i < bits; i++) { | ||
1580 | if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &v, read_callback, client_data)) | ||
1581 | return false; | ||
1582 | } | ||
1583 | |||
1584 | /* fix the sign */ | ||
1585 | i = 32 - bits; | ||
1586 | if(i) { | ||
1587 | v <<= i; | ||
1588 | *val = (FLAC__int32)v; | ||
1589 | *val >>= i; | ||
1590 | } | ||
1591 | else | ||
1592 | *val = (FLAC__int32)v; | ||
1593 | |||
1594 | return true; | ||
1595 | } | ||
1596 | #else | ||
1597 | { | ||
1598 | unsigned i, bits_ = bits; | ||
1599 | FLAC__uint32 v = 0; | ||
1600 | |||
1601 | FLAC__ASSERT(0 != bb); | ||
1602 | FLAC__ASSERT(0 != bb->buffer); | ||
1603 | |||
1604 | FLAC__ASSERT(bits <= 32); | ||
1605 | FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits); | ||
1606 | |||
1607 | if(bits == 0) { | ||
1608 | *val = 0; | ||
1609 | return true; | ||
1610 | } | ||
1611 | |||
1612 | while(bb->total_consumed_bits + bits > bb->total_bits) { | ||
1613 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1614 | return false; | ||
1615 | } | ||
1616 | #if FLAC__BITS_PER_BLURB > 8 | ||
1617 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/ | ||
1618 | #endif | ||
1619 | if(bb->consumed_bits) { | ||
1620 | i = FLAC__BITS_PER_BLURB - bb->consumed_bits; | ||
1621 | if(i <= bits_) { | ||
1622 | v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits); | ||
1623 | bits_ -= i; | ||
1624 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1625 | bb->consumed_blurbs++; | ||
1626 | bb->consumed_bits = 0; | ||
1627 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1628 | } | ||
1629 | else { | ||
1630 | /* bits_ must be < FLAC__BITS_PER_BLURB-1 if we get to here */ | ||
1631 | v = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits)); | ||
1632 | v <<= (32-i); | ||
1633 | *val = (FLAC__int32)v; | ||
1634 | *val >>= (32-bits_); | ||
1635 | bb->consumed_bits += bits_; | ||
1636 | bb->total_consumed_bits += bits_; | ||
1637 | return true; | ||
1638 | } | ||
1639 | } | ||
1640 | #if FLAC__BITS_PER_BLURB == 32 | ||
1641 | /* note that we know bits_ cannot be > 32 because of previous assertions */ | ||
1642 | if(bits_ == FLAC__BITS_PER_BLURB) { | ||
1643 | v = bb->buffer[bb->consumed_blurbs]; | ||
1644 | bits_ = 0; | ||
1645 | CRC16_UPDATE_BLURB(bb, v, bb->read_crc16); | ||
1646 | bb->consumed_blurbs++; | ||
1647 | /* bb->consumed_bits is already 0 */ | ||
1648 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1649 | } | ||
1650 | #else | ||
1651 | while(bits_ >= FLAC__BITS_PER_BLURB) { | ||
1652 | v <<= FLAC__BITS_PER_BLURB; | ||
1653 | v |= bb->buffer[bb->consumed_blurbs]; | ||
1654 | bits_ -= FLAC__BITS_PER_BLURB; | ||
1655 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1656 | bb->consumed_blurbs++; | ||
1657 | /* bb->consumed_bits is already 0 */ | ||
1658 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1659 | } | ||
1660 | #endif | ||
1661 | if(bits_ > 0) { | ||
1662 | v <<= bits_; | ||
1663 | v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_)); | ||
1664 | bb->consumed_bits = bits_; | ||
1665 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1666 | } | ||
1667 | bb->total_consumed_bits += bits; | ||
1668 | #if FLAC__BITS_PER_BLURB > 8 | ||
1669 | } | ||
1670 | else { | ||
1671 | for(i = 0; i < bits; i++) { | ||
1672 | if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &v, read_callback, client_data)) | ||
1673 | return false; | ||
1674 | } | ||
1675 | } | ||
1676 | #endif | ||
1677 | |||
1678 | /* fix the sign */ | ||
1679 | i = 32 - bits; | ||
1680 | if(i) { | ||
1681 | v <<= i; | ||
1682 | *val = (FLAC__int32)v; | ||
1683 | *val >>= i; | ||
1684 | } | ||
1685 | else | ||
1686 | *val = (FLAC__int32)v; | ||
1687 | |||
1688 | return true; | ||
1689 | } | ||
1690 | #endif | ||
1691 | |||
1692 | FLAC__bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1693 | #ifdef FLAC__NO_MANUAL_INLINING | ||
1694 | { | ||
1695 | unsigned i; | ||
1696 | |||
1697 | FLAC__ASSERT(0 != bb); | ||
1698 | FLAC__ASSERT(0 != bb->buffer); | ||
1699 | |||
1700 | FLAC__ASSERT(bits <= 64); | ||
1701 | |||
1702 | *val = 0; | ||
1703 | for(i = 0; i < bits; i++) { | ||
1704 | if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data)) | ||
1705 | return false; | ||
1706 | } | ||
1707 | return true; | ||
1708 | } | ||
1709 | #else | ||
1710 | { | ||
1711 | unsigned i, bits_ = bits; | ||
1712 | FLAC__uint64 v = 0; | ||
1713 | |||
1714 | FLAC__ASSERT(0 != bb); | ||
1715 | FLAC__ASSERT(0 != bb->buffer); | ||
1716 | |||
1717 | FLAC__ASSERT(bits <= 64); | ||
1718 | FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits); | ||
1719 | |||
1720 | if(bits == 0) { | ||
1721 | *val = 0; | ||
1722 | return true; | ||
1723 | } | ||
1724 | |||
1725 | while(bb->total_consumed_bits + bits > bb->total_bits) { | ||
1726 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1727 | return false; | ||
1728 | } | ||
1729 | #if FLAC__BITS_PER_BLURB > 8 | ||
1730 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/ | ||
1731 | #endif | ||
1732 | if(bb->consumed_bits) { | ||
1733 | i = FLAC__BITS_PER_BLURB - bb->consumed_bits; | ||
1734 | if(i <= bits_) { | ||
1735 | v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits); | ||
1736 | bits_ -= i; | ||
1737 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1738 | bb->consumed_blurbs++; | ||
1739 | bb->consumed_bits = 0; | ||
1740 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1741 | } | ||
1742 | else { | ||
1743 | *val = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits)) >> (i-bits_); | ||
1744 | bb->consumed_bits += bits_; | ||
1745 | bb->total_consumed_bits += bits_; | ||
1746 | return true; | ||
1747 | } | ||
1748 | } | ||
1749 | while(bits_ >= FLAC__BITS_PER_BLURB) { | ||
1750 | v <<= FLAC__BITS_PER_BLURB; | ||
1751 | v |= bb->buffer[bb->consumed_blurbs]; | ||
1752 | bits_ -= FLAC__BITS_PER_BLURB; | ||
1753 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1754 | bb->consumed_blurbs++; | ||
1755 | /* bb->consumed_bits is already 0 */ | ||
1756 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1757 | } | ||
1758 | if(bits_ > 0) { | ||
1759 | v <<= bits_; | ||
1760 | v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_)); | ||
1761 | bb->consumed_bits = bits_; | ||
1762 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1763 | } | ||
1764 | bb->total_consumed_bits += bits; | ||
1765 | *val = v; | ||
1766 | #if FLAC__BITS_PER_BLURB > 8 | ||
1767 | } | ||
1768 | else { | ||
1769 | *val = 0; | ||
1770 | for(i = 0; i < bits; i++) { | ||
1771 | if(!FLAC__bitbuffer_read_bit_to_uint64(bb, val, read_callback, client_data)) | ||
1772 | return false; | ||
1773 | } | ||
1774 | } | ||
1775 | #endif | ||
1776 | return true; | ||
1777 | } | ||
1778 | #endif | ||
1779 | |||
1780 | #if 0 /* UNUSED */ | ||
1781 | FLAC__bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1782 | #ifdef FLAC__NO_MANUAL_INLINING | ||
1783 | { | ||
1784 | unsigned i; | ||
1785 | FLAC__uint64 v; | ||
1786 | |||
1787 | FLAC__ASSERT(0 != bb); | ||
1788 | FLAC__ASSERT(0 != bb->buffer); | ||
1789 | |||
1790 | FLAC__ASSERT(bits <= 64); | ||
1791 | |||
1792 | v = 0; | ||
1793 | for(i = 0; i < bits; i++) { | ||
1794 | if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &v, read_callback, client_data)) | ||
1795 | return false; | ||
1796 | } | ||
1797 | /* fix the sign */ | ||
1798 | i = 64 - bits; | ||
1799 | if(i) { | ||
1800 | v <<= i; | ||
1801 | *val = (FLAC__int64)v; | ||
1802 | *val >>= i; | ||
1803 | } | ||
1804 | else | ||
1805 | *val = (FLAC__int64)v; | ||
1806 | |||
1807 | return true; | ||
1808 | } | ||
1809 | #else | ||
1810 | { | ||
1811 | unsigned i, bits_ = bits; | ||
1812 | FLAC__uint64 v = 0; | ||
1813 | |||
1814 | FLAC__ASSERT(0 != bb); | ||
1815 | FLAC__ASSERT(0 != bb->buffer); | ||
1816 | |||
1817 | FLAC__ASSERT(bits <= 64); | ||
1818 | FLAC__ASSERT((bb->capacity*FLAC__BITS_PER_BLURB) * 2 >= bits); | ||
1819 | |||
1820 | if(bits == 0) { | ||
1821 | *val = 0; | ||
1822 | return true; | ||
1823 | } | ||
1824 | |||
1825 | while(bb->total_consumed_bits + bits > bb->total_bits) { | ||
1826 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1827 | return false; | ||
1828 | } | ||
1829 | #if FLAC__BITS_PER_BLURB > 8 | ||
1830 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/ | ||
1831 | #endif | ||
1832 | if(bb->consumed_bits) { | ||
1833 | i = FLAC__BITS_PER_BLURB - bb->consumed_bits; | ||
1834 | if(i <= bits_) { | ||
1835 | v = bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits); | ||
1836 | bits_ -= i; | ||
1837 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1838 | bb->consumed_blurbs++; | ||
1839 | bb->consumed_bits = 0; | ||
1840 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1841 | } | ||
1842 | else { | ||
1843 | /* bits_ must be < FLAC__BITS_PER_BLURB-1 if we get to here */ | ||
1844 | v = (bb->buffer[bb->consumed_blurbs] & (FLAC__BLURB_ALL_ONES >> bb->consumed_bits)); | ||
1845 | v <<= (64-i); | ||
1846 | *val = (FLAC__int64)v; | ||
1847 | *val >>= (64-bits_); | ||
1848 | bb->consumed_bits += bits_; | ||
1849 | bb->total_consumed_bits += bits_; | ||
1850 | return true; | ||
1851 | } | ||
1852 | } | ||
1853 | while(bits_ >= FLAC__BITS_PER_BLURB) { | ||
1854 | v <<= FLAC__BITS_PER_BLURB; | ||
1855 | v |= bb->buffer[bb->consumed_blurbs]; | ||
1856 | bits_ -= FLAC__BITS_PER_BLURB; | ||
1857 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
1858 | bb->consumed_blurbs++; | ||
1859 | /* bb->consumed_bits is already 0 */ | ||
1860 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1861 | } | ||
1862 | if(bits_ > 0) { | ||
1863 | v <<= bits_; | ||
1864 | v |= (bb->buffer[bb->consumed_blurbs] >> (FLAC__BITS_PER_BLURB-bits_)); | ||
1865 | bb->consumed_bits = bits_; | ||
1866 | /* we hold off updating bb->total_consumed_bits until the end */ | ||
1867 | } | ||
1868 | bb->total_consumed_bits += bits; | ||
1869 | #if FLAC__BITS_PER_BLURB > 8 | ||
1870 | } | ||
1871 | else { | ||
1872 | for(i = 0; i < bits; i++) { | ||
1873 | if(!FLAC__bitbuffer_read_bit_to_uint64(bb, &v, read_callback, client_data)) | ||
1874 | return false; | ||
1875 | } | ||
1876 | } | ||
1877 | #endif | ||
1878 | |||
1879 | /* fix the sign */ | ||
1880 | i = 64 - bits; | ||
1881 | if(i) { | ||
1882 | v <<= i; | ||
1883 | *val = (FLAC__int64)v; | ||
1884 | *val >>= i; | ||
1885 | } | ||
1886 | else | ||
1887 | *val = (FLAC__int64)v; | ||
1888 | |||
1889 | return true; | ||
1890 | } | ||
1891 | #endif | ||
1892 | #endif | ||
1893 | |||
1894 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1895 | { | ||
1896 | FLAC__uint32 x8, x32 = 0; | ||
1897 | |||
1898 | /* this doesn't need to be that fast as currently it is only used for vorbis comments */ | ||
1899 | |||
1900 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x32, 8, read_callback, client_data)) | ||
1901 | return false; | ||
1902 | |||
1903 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data)) | ||
1904 | return false; | ||
1905 | x32 |= (x8 << 8); | ||
1906 | |||
1907 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data)) | ||
1908 | return false; | ||
1909 | x32 |= (x8 << 16); | ||
1910 | |||
1911 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x8, 8, read_callback, client_data)) | ||
1912 | return false; | ||
1913 | x32 |= (x8 << 24); | ||
1914 | |||
1915 | *val = x32; | ||
1916 | return true; | ||
1917 | } | ||
1918 | |||
1919 | FLAC__bool FLAC__bitbuffer_skip_bits_no_crc(FLAC__BitBuffer *bb, unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1920 | { | ||
1921 | /* | ||
1922 | * @@@ a slightly faster implementation is possible but | ||
1923 | * probably not that useful since this is only called a | ||
1924 | * couple of times in the metadata readers. | ||
1925 | */ | ||
1926 | FLAC__ASSERT(0 != bb); | ||
1927 | FLAC__ASSERT(0 != bb->buffer); | ||
1928 | |||
1929 | if(bits > 0) { | ||
1930 | const unsigned n = bb->consumed_bits & 7; | ||
1931 | unsigned m; | ||
1932 | FLAC__uint32 x; | ||
1933 | |||
1934 | if(n != 0) { | ||
1935 | m = min(8-n, bits); | ||
1936 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, m, read_callback, client_data)) | ||
1937 | return false; | ||
1938 | bits -= m; | ||
1939 | } | ||
1940 | m = bits / 8; | ||
1941 | if(m > 0) { | ||
1942 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(bb, 0, m, read_callback, client_data)) | ||
1943 | return false; | ||
1944 | bits %= 8; | ||
1945 | } | ||
1946 | if(bits > 0) { | ||
1947 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, bits, read_callback, client_data)) | ||
1948 | return false; | ||
1949 | } | ||
1950 | } | ||
1951 | |||
1952 | return true; | ||
1953 | } | ||
1954 | |||
1955 | FLAC__bool FLAC__bitbuffer_read_byte_block_aligned_no_crc(FLAC__BitBuffer *bb, FLAC__byte *val, unsigned nvals, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1956 | { | ||
1957 | FLAC__ASSERT(0 != bb); | ||
1958 | FLAC__ASSERT(0 != bb->buffer); | ||
1959 | FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb)); | ||
1960 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(bb)); | ||
1961 | #if FLAC__BITS_PER_BLURB == 8 | ||
1962 | while(nvals > 0) { | ||
1963 | unsigned chunk = min(nvals, bb->blurbs - bb->consumed_blurbs); | ||
1964 | if(chunk == 0) { | ||
1965 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
1966 | return false; | ||
1967 | } | ||
1968 | else { | ||
1969 | if(0 != val) { | ||
1970 | memcpy(val, bb->buffer + bb->consumed_blurbs, FLAC__BYTES_PER_BLURB * chunk); | ||
1971 | val += FLAC__BYTES_PER_BLURB * chunk; | ||
1972 | } | ||
1973 | nvals -= chunk; | ||
1974 | bb->consumed_blurbs += chunk; | ||
1975 | bb->total_consumed_bits = (bb->consumed_blurbs << FLAC__BITS_PER_BLURB_LOG2); | ||
1976 | } | ||
1977 | } | ||
1978 | #else | ||
1979 | @@@ need to write this still | ||
1980 | FLAC__ASSERT(0); | ||
1981 | #endif | ||
1982 | |||
1983 | return true; | ||
1984 | } | ||
1985 | |||
1986 | FLaC__INLINE FLAC__bool FLAC__bitbuffer_read_unary_unsigned(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
1987 | #ifdef FLAC__NO_MANUAL_INLINING | ||
1988 | { | ||
1989 | unsigned bit, val_ = 0; | ||
1990 | |||
1991 | FLAC__ASSERT(0 != bb); | ||
1992 | FLAC__ASSERT(0 != bb->buffer); | ||
1993 | |||
1994 | while(1) { | ||
1995 | if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data)) | ||
1996 | return false; | ||
1997 | if(bit) | ||
1998 | break; | ||
1999 | else | ||
2000 | val_++; | ||
2001 | } | ||
2002 | *val = val_; | ||
2003 | return true; | ||
2004 | } | ||
2005 | #else | ||
2006 | { | ||
2007 | unsigned i, val_ = 0; | ||
2008 | unsigned total_blurbs_ = (bb->total_bits + (FLAC__BITS_PER_BLURB-1)) / FLAC__BITS_PER_BLURB; | ||
2009 | FLAC__blurb b; | ||
2010 | |||
2011 | FLAC__ASSERT(0 != bb); | ||
2012 | FLAC__ASSERT(0 != bb->buffer); | ||
2013 | |||
2014 | #if FLAC__BITS_PER_BLURB > 8 | ||
2015 | if(bb->bits == 0 || bb->consumed_blurbs < bb->blurbs) { /*@@@ comment on why this is here*/ | ||
2016 | #endif | ||
2017 | if(bb->consumed_bits) { | ||
2018 | b = bb->buffer[bb->consumed_blurbs] << bb->consumed_bits; | ||
2019 | if(b) { | ||
2020 | for(i = 0; !(b & FLAC__BLURB_TOP_BIT_ONE); i++) | ||
2021 | b <<= 1; | ||
2022 | *val = i; | ||
2023 | i++; | ||
2024 | bb->consumed_bits += i; | ||
2025 | bb->total_consumed_bits += i; | ||
2026 | if(bb->consumed_bits == FLAC__BITS_PER_BLURB) { | ||
2027 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
2028 | bb->consumed_blurbs++; | ||
2029 | bb->consumed_bits = 0; | ||
2030 | } | ||
2031 | return true; | ||
2032 | } | ||
2033 | else { | ||
2034 | val_ = FLAC__BITS_PER_BLURB - bb->consumed_bits; | ||
2035 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
2036 | bb->consumed_blurbs++; | ||
2037 | bb->consumed_bits = 0; | ||
2038 | bb->total_consumed_bits += val_; | ||
2039 | } | ||
2040 | } | ||
2041 | while(1) { | ||
2042 | if(bb->consumed_blurbs >= total_blurbs_) { | ||
2043 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
2044 | return false; | ||
2045 | total_blurbs_ = (bb->total_bits + (FLAC__BITS_PER_BLURB-1)) / FLAC__BITS_PER_BLURB; | ||
2046 | } | ||
2047 | b = bb->buffer[bb->consumed_blurbs]; | ||
2048 | if(b) { | ||
2049 | for(i = 0; !(b & FLAC__BLURB_TOP_BIT_ONE); i++) | ||
2050 | b <<= 1; | ||
2051 | val_ += i; | ||
2052 | i++; | ||
2053 | bb->consumed_bits = i; | ||
2054 | *val = val_; | ||
2055 | if(i == FLAC__BITS_PER_BLURB) { | ||
2056 | CRC16_UPDATE_BLURB(bb, bb->buffer[bb->consumed_blurbs], bb->read_crc16); | ||
2057 | bb->consumed_blurbs++; | ||
2058 | bb->consumed_bits = 0; | ||
2059 | } | ||
2060 | bb->total_consumed_bits += i; | ||
2061 | return true; | ||
2062 | } | ||
2063 | else { | ||
2064 | val_ += FLAC__BITS_PER_BLURB; | ||
2065 | CRC16_UPDATE_BLURB(bb, 0, bb->read_crc16); | ||
2066 | bb->consumed_blurbs++; | ||
2067 | /* bb->consumed_bits is already 0 */ | ||
2068 | bb->total_consumed_bits += FLAC__BITS_PER_BLURB; | ||
2069 | } | ||
2070 | } | ||
2071 | #if FLAC__BITS_PER_BLURB > 8 | ||
2072 | } | ||
2073 | else { | ||
2074 | while(1) { | ||
2075 | if(!FLAC__bitbuffer_read_bit(bb, &i, read_callback, client_data)) | ||
2076 | return false; | ||
2077 | if(i) | ||
2078 | break; | ||
2079 | else | ||
2080 | val_++; | ||
2081 | } | ||
2082 | *val = val_; | ||
2083 | return true; | ||
2084 | } | ||
2085 | #endif | ||
2086 | } | ||
2087 | #endif | ||
2088 | |||
2089 | #ifdef FLAC__SYMMETRIC_RICE | ||
2090 | FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
2091 | { | ||
2092 | FLAC__uint32 sign = 0, lsbs = 0, msbs = 0; | ||
2093 | |||
2094 | FLAC__ASSERT(0 != bb); | ||
2095 | FLAC__ASSERT(0 != bb->buffer); | ||
2096 | FLAC__ASSERT(parameter <= 31); | ||
2097 | |||
2098 | /* read the unary MSBs and end bit */ | ||
2099 | if(!FLAC__bitbuffer_read_unary_unsigned(bb, &msbs, read_callback, client_data)) | ||
2100 | return false; | ||
2101 | |||
2102 | /* read the sign bit */ | ||
2103 | if(!FLAC__bitbuffer_read_bit_to_uint32(bb, &sign, read_callback, client_data)) | ||
2104 | return false; | ||
2105 | |||
2106 | /* read the binary LSBs */ | ||
2107 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, parameter, read_callback, client_data)) | ||
2108 | return false; | ||
2109 | |||
2110 | /* compose the value */ | ||
2111 | *val = (msbs << parameter) | lsbs; | ||
2112 | if(sign) | ||
2113 | *val = -(*val); | ||
2114 | |||
2115 | return true; | ||
2116 | } | ||
2117 | #endif /* ifdef FLAC__SYMMETRIC_RICE */ | ||
2118 | |||
2119 | FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
2120 | { | ||
2121 | FLAC__uint32 lsbs = 0, msbs = 0; | ||
2122 | unsigned uval; | ||
2123 | |||
2124 | FLAC__ASSERT(0 != bb); | ||
2125 | FLAC__ASSERT(0 != bb->buffer); | ||
2126 | FLAC__ASSERT(parameter <= 31); | ||
2127 | |||
2128 | /* read the unary MSBs and end bit */ | ||
2129 | if(!FLAC__bitbuffer_read_unary_unsigned(bb, &msbs, read_callback, client_data)) | ||
2130 | return false; | ||
2131 | |||
2132 | /* read the binary LSBs */ | ||
2133 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, parameter, read_callback, client_data)) | ||
2134 | return false; | ||
2135 | |||
2136 | /* compose the value */ | ||
2137 | uval = (msbs << parameter) | lsbs; | ||
2138 | if(uval & 1) | ||
2139 | *val = -((int)(uval >> 1)) - 1; | ||
2140 | else | ||
2141 | *val = (int)(uval >> 1); | ||
2142 | |||
2143 | return true; | ||
2144 | } | ||
2145 | |||
2146 | FLAC__bool FLAC__bitbuffer_read_rice_signed_block(FLAC__BitBuffer *bb, int vals[], unsigned nvals, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
2147 | #ifdef FLAC__OLD_MSVC_FLAVOR | ||
2148 | { | ||
2149 | const FLAC__blurb *buffer = bb->buffer; | ||
2150 | |||
2151 | unsigned i, j, val_i = 0; | ||
2152 | unsigned cbits = 0, uval = 0, msbs = 0, lsbs_left = 0; | ||
2153 | FLAC__blurb blurb, save_blurb; | ||
2154 | unsigned state = 0; /* 0 = getting unary MSBs, 1 = getting binary LSBs */ | ||
2155 | |||
2156 | FLAC__ASSERT(0 != bb); | ||
2157 | FLAC__ASSERT(0 != bb->buffer); | ||
2158 | FLAC__ASSERT(parameter <= 31); | ||
2159 | |||
2160 | if(nvals == 0) | ||
2161 | return true; | ||
2162 | |||
2163 | i = bb->consumed_blurbs; | ||
2164 | /* | ||
2165 | * We unroll the main loop to take care of partially consumed blurbs here. | ||
2166 | */ | ||
2167 | if(bb->consumed_bits > 0) { | ||
2168 | save_blurb = blurb = buffer[i]; | ||
2169 | cbits = bb->consumed_bits; | ||
2170 | blurb <<= cbits; | ||
2171 | |||
2172 | while(1) { | ||
2173 | if(state == 0) { | ||
2174 | if(blurb) { | ||
2175 | for(j = 0; !(blurb & FLAC__BLURB_TOP_BIT_ONE); j++) | ||
2176 | blurb <<= 1; | ||
2177 | msbs += j; | ||
2178 | |||
2179 | /* dispose of the unary end bit */ | ||
2180 | blurb <<= 1; | ||
2181 | j++; | ||
2182 | cbits += j; | ||
2183 | |||
2184 | uval = 0; | ||
2185 | lsbs_left = parameter; | ||
2186 | state++; | ||
2187 | if(cbits == FLAC__BITS_PER_BLURB) { | ||
2188 | cbits = 0; | ||
2189 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2190 | break; | ||
2191 | } | ||
2192 | } | ||
2193 | else { | ||
2194 | msbs += FLAC__BITS_PER_BLURB - cbits; | ||
2195 | cbits = 0; | ||
2196 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2197 | break; | ||
2198 | } | ||
2199 | } | ||
2200 | else { | ||
2201 | const unsigned available_bits = FLAC__BITS_PER_BLURB - cbits; | ||
2202 | if(lsbs_left >= available_bits) { | ||
2203 | uval <<= available_bits; | ||
2204 | uval |= (blurb >> cbits); | ||
2205 | cbits = 0; | ||
2206 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2207 | |||
2208 | if(lsbs_left == available_bits) { | ||
2209 | /* compose the value */ | ||
2210 | uval |= (msbs << parameter); | ||
2211 | if(uval & 1) | ||
2212 | vals[val_i++] = -((int)(uval >> 1)) - 1; | ||
2213 | else | ||
2214 | vals[val_i++] = (int)(uval >> 1); | ||
2215 | if(val_i == nvals) | ||
2216 | break; | ||
2217 | |||
2218 | msbs = 0; | ||
2219 | state = 0; | ||
2220 | } | ||
2221 | |||
2222 | lsbs_left -= available_bits; | ||
2223 | break; | ||
2224 | } | ||
2225 | else { | ||
2226 | uval <<= lsbs_left; | ||
2227 | uval |= (blurb >> (FLAC__BITS_PER_BLURB - lsbs_left)); | ||
2228 | blurb <<= lsbs_left; | ||
2229 | cbits += lsbs_left; | ||
2230 | |||
2231 | /* compose the value */ | ||
2232 | uval |= (msbs << parameter); | ||
2233 | if(uval & 1) | ||
2234 | vals[val_i++] = -((int)(uval >> 1)) - 1; | ||
2235 | else | ||
2236 | vals[val_i++] = (int)(uval >> 1); | ||
2237 | if(val_i == nvals) { | ||
2238 | /* back up one if we exited the for loop because we read all nvals but the end came in the middle of a blurb */ | ||
2239 | i--; | ||
2240 | break; | ||
2241 | } | ||
2242 | |||
2243 | msbs = 0; | ||
2244 | state = 0; | ||
2245 | } | ||
2246 | } | ||
2247 | } | ||
2248 | i++; | ||
2249 | |||
2250 | bb->consumed_blurbs = i; | ||
2251 | bb->consumed_bits = cbits; | ||
2252 | bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits; | ||
2253 | } | ||
2254 | |||
2255 | /* | ||
2256 | * Now that we are blurb-aligned the logic is slightly simpler | ||
2257 | */ | ||
2258 | while(val_i < nvals) { | ||
2259 | for( ; i < bb->blurbs && val_i < nvals; i++) { | ||
2260 | save_blurb = blurb = buffer[i]; | ||
2261 | cbits = 0; | ||
2262 | while(1) { | ||
2263 | if(state == 0) { | ||
2264 | if(blurb) { | ||
2265 | for(j = 0; !(blurb & FLAC__BLURB_TOP_BIT_ONE); j++) | ||
2266 | blurb <<= 1; | ||
2267 | msbs += j; | ||
2268 | |||
2269 | /* dispose of the unary end bit */ | ||
2270 | blurb <<= 1; | ||
2271 | j++; | ||
2272 | cbits += j; | ||
2273 | |||
2274 | uval = 0; | ||
2275 | lsbs_left = parameter; | ||
2276 | state++; | ||
2277 | if(cbits == FLAC__BITS_PER_BLURB) { | ||
2278 | cbits = 0; | ||
2279 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2280 | break; | ||
2281 | } | ||
2282 | } | ||
2283 | else { | ||
2284 | msbs += FLAC__BITS_PER_BLURB - cbits; | ||
2285 | cbits = 0; | ||
2286 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2287 | break; | ||
2288 | } | ||
2289 | } | ||
2290 | else { | ||
2291 | const unsigned available_bits = FLAC__BITS_PER_BLURB - cbits; | ||
2292 | if(lsbs_left >= available_bits) { | ||
2293 | uval <<= available_bits; | ||
2294 | uval |= (blurb >> cbits); | ||
2295 | cbits = 0; | ||
2296 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2297 | |||
2298 | if(lsbs_left == available_bits) { | ||
2299 | /* compose the value */ | ||
2300 | uval |= (msbs << parameter); | ||
2301 | if(uval & 1) | ||
2302 | vals[val_i++] = -((int)(uval >> 1)) - 1; | ||
2303 | else | ||
2304 | vals[val_i++] = (int)(uval >> 1); | ||
2305 | if(val_i == nvals) | ||
2306 | break; | ||
2307 | |||
2308 | msbs = 0; | ||
2309 | state = 0; | ||
2310 | } | ||
2311 | |||
2312 | lsbs_left -= available_bits; | ||
2313 | break; | ||
2314 | } | ||
2315 | else { | ||
2316 | uval <<= lsbs_left; | ||
2317 | uval |= (blurb >> (FLAC__BITS_PER_BLURB - lsbs_left)); | ||
2318 | blurb <<= lsbs_left; | ||
2319 | cbits += lsbs_left; | ||
2320 | |||
2321 | /* compose the value */ | ||
2322 | uval |= (msbs << parameter); | ||
2323 | if(uval & 1) | ||
2324 | vals[val_i++] = -((int)(uval >> 1)) - 1; | ||
2325 | else | ||
2326 | vals[val_i++] = (int)(uval >> 1); | ||
2327 | if(val_i == nvals) { | ||
2328 | /* back up one if we exited the for loop because we read all nvals but the end came in the middle of a blurb */ | ||
2329 | i--; | ||
2330 | break; | ||
2331 | } | ||
2332 | |||
2333 | msbs = 0; | ||
2334 | state = 0; | ||
2335 | } | ||
2336 | } | ||
2337 | } | ||
2338 | } | ||
2339 | bb->consumed_blurbs = i; | ||
2340 | bb->consumed_bits = cbits; | ||
2341 | bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits; | ||
2342 | if(val_i < nvals) { | ||
2343 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
2344 | return false; | ||
2345 | /* these must be zero because we can only get here if we got to the end of the buffer */ | ||
2346 | FLAC__ASSERT(bb->consumed_blurbs == 0); | ||
2347 | FLAC__ASSERT(bb->consumed_bits == 0); | ||
2348 | i = 0; | ||
2349 | } | ||
2350 | } | ||
2351 | |||
2352 | return true; | ||
2353 | } | ||
2354 | #else | ||
2355 | { | ||
2356 | const FLAC__blurb *buffer = bb->buffer; | ||
2357 | |||
2358 | unsigned i, j, val_i = nvals; | ||
2359 | unsigned cbits = 0, uval = 0, msbs = 0, lsbs_left = 0; | ||
2360 | FLAC__blurb blurb, save_blurb; | ||
2361 | unsigned state = 0; /* 0 = getting unary MSBs, 1 = getting binary LSBs */ | ||
2362 | |||
2363 | FLAC__ASSERT(0 != bb); | ||
2364 | FLAC__ASSERT(0 != bb->buffer); | ||
2365 | FLAC__ASSERT(parameter <= 31); | ||
2366 | |||
2367 | if(nvals == 0) | ||
2368 | return true; | ||
2369 | |||
2370 | cbits = bb->consumed_bits; | ||
2371 | i = bb->consumed_blurbs; | ||
2372 | while(val_i != 0) { | ||
2373 | for( ; i < bb->blurbs; i++) { | ||
2374 | blurb = (save_blurb = buffer[i]) << cbits; | ||
2375 | while(1) { | ||
2376 | if(state == 0) { | ||
2377 | if(blurb) { | ||
2378 | j = FLAC__ALIGNED_BLURB_UNARY(blurb); | ||
2379 | msbs += j; | ||
2380 | j++; | ||
2381 | cbits += j; | ||
2382 | |||
2383 | uval = 0; | ||
2384 | lsbs_left = parameter; | ||
2385 | state++; | ||
2386 | if(cbits == FLAC__BITS_PER_BLURB) { | ||
2387 | cbits = 0; | ||
2388 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2389 | break; | ||
2390 | } | ||
2391 | blurb <<= j; | ||
2392 | } | ||
2393 | else { | ||
2394 | msbs += FLAC__BITS_PER_BLURB - cbits; | ||
2395 | cbits = 0; | ||
2396 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2397 | break; | ||
2398 | } | ||
2399 | } | ||
2400 | else { | ||
2401 | const unsigned available_bits = FLAC__BITS_PER_BLURB - cbits; | ||
2402 | if(lsbs_left >= available_bits) { | ||
2403 | uval <<= available_bits; | ||
2404 | uval |= (blurb >> cbits); | ||
2405 | cbits = 0; | ||
2406 | CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16); | ||
2407 | |||
2408 | if(lsbs_left == available_bits) { | ||
2409 | /* compose the value */ | ||
2410 | uval |= (msbs << parameter); | ||
2411 | *vals = (int)(uval >> 1 ^ -(int)(uval & 1)); | ||
2412 | --val_i; | ||
2413 | if(val_i == 0) { | ||
2414 | i++; | ||
2415 | goto break2; | ||
2416 | } | ||
2417 | ++vals; | ||
2418 | |||
2419 | msbs = 0; | ||
2420 | state = 0; | ||
2421 | } | ||
2422 | |||
2423 | lsbs_left -= available_bits; | ||
2424 | break; | ||
2425 | } | ||
2426 | else { | ||
2427 | cbits += lsbs_left; | ||
2428 | uval <<= lsbs_left; | ||
2429 | uval |= (blurb >> (FLAC__BITS_PER_BLURB - lsbs_left)); | ||
2430 | blurb <<= lsbs_left; | ||
2431 | |||
2432 | /* compose the value */ | ||
2433 | uval |= (msbs << parameter); | ||
2434 | *vals = (int)(uval >> 1 ^ -(int)(uval & 1)); | ||
2435 | --val_i; | ||
2436 | if(val_i == 0) | ||
2437 | goto break2; | ||
2438 | ++vals; | ||
2439 | |||
2440 | msbs = 0; | ||
2441 | state = 0; | ||
2442 | } | ||
2443 | } | ||
2444 | } | ||
2445 | } | ||
2446 | break2: | ||
2447 | bb->consumed_blurbs = i; | ||
2448 | bb->consumed_bits = cbits; | ||
2449 | bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits; | ||
2450 | if(val_i != 0) { | ||
2451 | if(!bitbuffer_read_from_client_(bb, read_callback, client_data)) | ||
2452 | return false; | ||
2453 | /* these must be zero because we can only get here if we got to the end of the buffer */ | ||
2454 | FLAC__ASSERT(bb->consumed_blurbs == 0); | ||
2455 | FLAC__ASSERT(bb->consumed_bits == 0); | ||
2456 | i = 0; | ||
2457 | } | ||
2458 | } | ||
2459 | |||
2460 | return true; | ||
2461 | } | ||
2462 | #endif | ||
2463 | |||
2464 | #if 0 /* UNUSED */ | ||
2465 | FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
2466 | { | ||
2467 | FLAC__uint32 lsbs = 0, msbs = 0; | ||
2468 | unsigned bit, uval, k; | ||
2469 | |||
2470 | FLAC__ASSERT(0 != bb); | ||
2471 | FLAC__ASSERT(0 != bb->buffer); | ||
2472 | |||
2473 | k = FLAC__bitmath_ilog2(parameter); | ||
2474 | |||
2475 | /* read the unary MSBs and end bit */ | ||
2476 | if(!FLAC__bitbuffer_read_unary_unsigned(bb, &msbs, read_callback, client_data)) | ||
2477 | return false; | ||
2478 | |||
2479 | /* read the binary LSBs */ | ||
2480 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, k, read_callback, client_data)) | ||
2481 | return false; | ||
2482 | |||
2483 | if(parameter == 1u<<k) { | ||
2484 | /* compose the value */ | ||
2485 | uval = (msbs << k) | lsbs; | ||
2486 | } | ||
2487 | else { | ||
2488 | unsigned d = (1 << (k+1)) - parameter; | ||
2489 | if(lsbs >= d) { | ||
2490 | if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data)) | ||
2491 | return false; | ||
2492 | lsbs <<= 1; | ||
2493 | lsbs |= bit; | ||
2494 | lsbs -= d; | ||
2495 | } | ||
2496 | /* compose the value */ | ||
2497 | uval = msbs * parameter + lsbs; | ||
2498 | } | ||
2499 | |||
2500 | /* unfold unsigned to signed */ | ||
2501 | if(uval & 1) | ||
2502 | *val = -((int)(uval >> 1)) - 1; | ||
2503 | else | ||
2504 | *val = (int)(uval >> 1); | ||
2505 | |||
2506 | return true; | ||
2507 | } | ||
2508 | |||
2509 | FLAC__bool FLAC__bitbuffer_read_golomb_unsigned(FLAC__BitBuffer *bb, unsigned *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data) | ||
2510 | { | ||
2511 | FLAC__uint32 lsbs, msbs = 0; | ||
2512 | unsigned bit, k; | ||
2513 | |||
2514 | FLAC__ASSERT(0 != bb); | ||
2515 | FLAC__ASSERT(0 != bb->buffer); | ||
2516 | |||
2517 | k = FLAC__bitmath_ilog2(parameter); | ||
2518 | |||
2519 | /* read the unary MSBs and end bit */ | ||
2520 | if(!FLAC__bitbuffer_read_unary_unsigned(bb, &msbs, read_callback, client_data)) | ||
2521 | return false; | ||
2522 | |||
2523 | /* read the binary LSBs */ | ||
2524 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &lsbs, k, read_callback, client_data)) | ||
2525 | return false; | ||
2526 | |||
2527 | if(parameter == 1u<<k) { | ||
2528 | /* compose the value */ | ||
2529 | *val = (msbs << k) | lsbs; | ||
2530 | } | ||
2531 | else { | ||
2532 | unsigned d = (1 << (k+1)) - parameter; | ||
2533 | if(lsbs >= d) { | ||
2534 | if(!FLAC__bitbuffer_read_bit(bb, &bit, read_callback, client_data)) | ||
2535 | return false; | ||
2536 | lsbs <<= 1; | ||
2537 | lsbs |= bit; | ||
2538 | lsbs -= d; | ||
2539 | } | ||
2540 | /* compose the value */ | ||
2541 | *val = msbs * parameter + lsbs; | ||
2542 | } | ||
2543 | |||
2544 | return true; | ||
2545 | } | ||
2546 | #endif /* UNUSED */ | ||
2547 | |||
2548 | /* on return, if *val == 0xffffffff then the utf-8 sequence was invalid, but the return value will be true */ | ||
2549 | FLAC__bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen) | ||
2550 | { | ||
2551 | FLAC__uint32 v = 0; | ||
2552 | FLAC__uint32 x; | ||
2553 | unsigned i; | ||
2554 | |||
2555 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) | ||
2556 | return false; | ||
2557 | if(raw) | ||
2558 | raw[(*rawlen)++] = (FLAC__byte)x; | ||
2559 | if(!(x & 0x80)) { /* 0xxxxxxx */ | ||
2560 | v = x; | ||
2561 | i = 0; | ||
2562 | } | ||
2563 | else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ | ||
2564 | v = x & 0x1F; | ||
2565 | i = 1; | ||
2566 | } | ||
2567 | else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ | ||
2568 | v = x & 0x0F; | ||
2569 | i = 2; | ||
2570 | } | ||
2571 | else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ | ||
2572 | v = x & 0x07; | ||
2573 | i = 3; | ||
2574 | } | ||
2575 | else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ | ||
2576 | v = x & 0x03; | ||
2577 | i = 4; | ||
2578 | } | ||
2579 | else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ | ||
2580 | v = x & 0x01; | ||
2581 | i = 5; | ||
2582 | } | ||
2583 | else { | ||
2584 | *val = 0xffffffff; | ||
2585 | return true; | ||
2586 | } | ||
2587 | for( ; i; i--) { | ||
2588 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) | ||
2589 | return false; | ||
2590 | if(raw) | ||
2591 | raw[(*rawlen)++] = (FLAC__byte)x; | ||
2592 | if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ | ||
2593 | *val = 0xffffffff; | ||
2594 | return true; | ||
2595 | } | ||
2596 | v <<= 6; | ||
2597 | v |= (x & 0x3F); | ||
2598 | } | ||
2599 | *val = v; | ||
2600 | return true; | ||
2601 | } | ||
2602 | |||
2603 | /* on return, if *val == 0xffffffffffffffff then the utf-8 sequence was invalid, but the return value will be true */ | ||
2604 | FLAC__bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen) | ||
2605 | { | ||
2606 | FLAC__uint64 v = 0; | ||
2607 | FLAC__uint32 x; | ||
2608 | unsigned i; | ||
2609 | |||
2610 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) | ||
2611 | return false; | ||
2612 | if(raw) | ||
2613 | raw[(*rawlen)++] = (FLAC__byte)x; | ||
2614 | if(!(x & 0x80)) { /* 0xxxxxxx */ | ||
2615 | v = x; | ||
2616 | i = 0; | ||
2617 | } | ||
2618 | else if(x & 0xC0 && !(x & 0x20)) { /* 110xxxxx */ | ||
2619 | v = x & 0x1F; | ||
2620 | i = 1; | ||
2621 | } | ||
2622 | else if(x & 0xE0 && !(x & 0x10)) { /* 1110xxxx */ | ||
2623 | v = x & 0x0F; | ||
2624 | i = 2; | ||
2625 | } | ||
2626 | else if(x & 0xF0 && !(x & 0x08)) { /* 11110xxx */ | ||
2627 | v = x & 0x07; | ||
2628 | i = 3; | ||
2629 | } | ||
2630 | else if(x & 0xF8 && !(x & 0x04)) { /* 111110xx */ | ||
2631 | v = x & 0x03; | ||
2632 | i = 4; | ||
2633 | } | ||
2634 | else if(x & 0xFC && !(x & 0x02)) { /* 1111110x */ | ||
2635 | v = x & 0x01; | ||
2636 | i = 5; | ||
2637 | } | ||
2638 | else if(x & 0xFE && !(x & 0x01)) { /* 11111110 */ | ||
2639 | v = 0; | ||
2640 | i = 6; | ||
2641 | } | ||
2642 | else { | ||
2643 | *val = FLAC__U64L(0xffffffffffffffff); | ||
2644 | return true; | ||
2645 | } | ||
2646 | for( ; i; i--) { | ||
2647 | if(!FLAC__bitbuffer_read_raw_uint32(bb, &x, 8, read_callback, client_data)) | ||
2648 | return false; | ||
2649 | if(raw) | ||
2650 | raw[(*rawlen)++] = (FLAC__byte)x; | ||
2651 | if(!(x & 0x80) || (x & 0x40)) { /* 10xxxxxx */ | ||
2652 | *val = FLAC__U64L(0xffffffffffffffff); | ||
2653 | return true; | ||
2654 | } | ||
2655 | v <<= 6; | ||
2656 | v |= (x & 0x3F); | ||
2657 | } | ||
2658 | *val = v; | ||
2659 | return true; | ||
2660 | } | ||
2661 | |||
2662 | void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out) | ||
2663 | { | ||
2664 | unsigned i, j; | ||
2665 | if(bb == 0) { | ||
2666 | fprintf(out, "bitbuffer is NULL\n"); | ||
2667 | } | ||
2668 | else { | ||
2669 | fprintf(out, "bitbuffer: capacity=%u blurbs=%u bits=%u total_bits=%u consumed: blurbs=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->blurbs, bb->bits, bb->total_bits, bb->consumed_blurbs, bb->consumed_bits, bb->total_consumed_bits); | ||
2670 | |||
2671 | for(i = 0; i < bb->blurbs; i++) { | ||
2672 | fprintf(out, "%08X: ", i); | ||
2673 | for(j = 0; j < FLAC__BITS_PER_BLURB; j++) | ||
2674 | if(i*FLAC__BITS_PER_BLURB+j < bb->total_consumed_bits) | ||
2675 | fprintf(out, "."); | ||
2676 | else | ||
2677 | fprintf(out, "%01u", bb->buffer[i] & (1 << (FLAC__BITS_PER_BLURB-j-1)) ? 1:0); | ||
2678 | fprintf(out, "\n"); | ||
2679 | } | ||
2680 | if(bb->bits > 0) { | ||
2681 | fprintf(out, "%08X: ", i); | ||
2682 | for(j = 0; j < bb->bits; j++) | ||
2683 | if(i*FLAC__BITS_PER_BLURB+j < bb->total_consumed_bits) | ||
2684 | fprintf(out, "."); | ||
2685 | else | ||
2686 | fprintf(out, "%01u", bb->buffer[i] & (1 << (bb->bits-j-1)) ? 1:0); | ||
2687 | fprintf(out, "\n"); | ||
2688 | } | ||
2689 | } | ||
2690 | } | ||
diff --git a/apps/codecs/libFLAC/bitmath.c b/apps/codecs/libFLAC/bitmath.c new file mode 100644 index 0000000000..2bc509b414 --- /dev/null +++ b/apps/codecs/libFLAC/bitmath.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include "private/bitmath.h" | ||
33 | #include "FLAC/assert.h" | ||
34 | |||
35 | /* An example of what FLAC__bitmath_ilog2() computes: | ||
36 | * | ||
37 | * ilog2( 0) = assertion failure | ||
38 | * ilog2( 1) = 0 | ||
39 | * ilog2( 2) = 1 | ||
40 | * ilog2( 3) = 1 | ||
41 | * ilog2( 4) = 2 | ||
42 | * ilog2( 5) = 2 | ||
43 | * ilog2( 6) = 2 | ||
44 | * ilog2( 7) = 2 | ||
45 | * ilog2( 8) = 3 | ||
46 | * ilog2( 9) = 3 | ||
47 | * ilog2(10) = 3 | ||
48 | * ilog2(11) = 3 | ||
49 | * ilog2(12) = 3 | ||
50 | * ilog2(13) = 3 | ||
51 | * ilog2(14) = 3 | ||
52 | * ilog2(15) = 3 | ||
53 | * ilog2(16) = 4 | ||
54 | * ilog2(17) = 4 | ||
55 | * ilog2(18) = 4 | ||
56 | */ | ||
57 | unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) | ||
58 | { | ||
59 | unsigned l = 0; | ||
60 | FLAC__ASSERT(v > 0); | ||
61 | while(v >>= 1) | ||
62 | l++; | ||
63 | return l; | ||
64 | } | ||
65 | |||
66 | unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) | ||
67 | { | ||
68 | unsigned l = 0; | ||
69 | FLAC__ASSERT(v > 0); | ||
70 | while(v >>= 1) | ||
71 | l++; | ||
72 | return l; | ||
73 | } | ||
74 | |||
75 | /* An example of what FLAC__bitmath_silog2() computes: | ||
76 | * | ||
77 | * silog2(-10) = 5 | ||
78 | * silog2(- 9) = 5 | ||
79 | * silog2(- 8) = 4 | ||
80 | * silog2(- 7) = 4 | ||
81 | * silog2(- 6) = 4 | ||
82 | * silog2(- 5) = 4 | ||
83 | * silog2(- 4) = 3 | ||
84 | * silog2(- 3) = 3 | ||
85 | * silog2(- 2) = 2 | ||
86 | * silog2(- 1) = 2 | ||
87 | * silog2( 0) = 0 | ||
88 | * silog2( 1) = 2 | ||
89 | * silog2( 2) = 3 | ||
90 | * silog2( 3) = 3 | ||
91 | * silog2( 4) = 4 | ||
92 | * silog2( 5) = 4 | ||
93 | * silog2( 6) = 4 | ||
94 | * silog2( 7) = 4 | ||
95 | * silog2( 8) = 5 | ||
96 | * silog2( 9) = 5 | ||
97 | * silog2( 10) = 5 | ||
98 | */ | ||
99 | unsigned FLAC__bitmath_silog2(int v) | ||
100 | { | ||
101 | while(1) { | ||
102 | if(v == 0) { | ||
103 | return 0; | ||
104 | } | ||
105 | else if(v > 0) { | ||
106 | unsigned l = 0; | ||
107 | while(v) { | ||
108 | l++; | ||
109 | v >>= 1; | ||
110 | } | ||
111 | return l+1; | ||
112 | } | ||
113 | else if(v == -1) { | ||
114 | return 2; | ||
115 | } | ||
116 | else { | ||
117 | v++; | ||
118 | v = -v; | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v) | ||
124 | { | ||
125 | while(1) { | ||
126 | if(v == 0) { | ||
127 | return 0; | ||
128 | } | ||
129 | else if(v > 0) { | ||
130 | unsigned l = 0; | ||
131 | while(v) { | ||
132 | l++; | ||
133 | v >>= 1; | ||
134 | } | ||
135 | return l+1; | ||
136 | } | ||
137 | else if(v == -1) { | ||
138 | return 2; | ||
139 | } | ||
140 | else { | ||
141 | v++; | ||
142 | v = -v; | ||
143 | } | ||
144 | } | ||
145 | } | ||
diff --git a/apps/codecs/libFLAC/cpu.c b/apps/codecs/libFLAC/cpu.c new file mode 100644 index 0000000000..1e6b27994f --- /dev/null +++ b/apps/codecs/libFLAC/cpu.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include "private/cpu.h" | ||
33 | #include <stdlib.h> | ||
34 | #include <stdio.h> | ||
35 | |||
36 | #ifdef HAVE_CONFIG_H | ||
37 | #include <config.h> | ||
38 | #endif | ||
39 | |||
40 | #if defined FLAC__CPU_PPC | ||
41 | #if !defined FLAC__NO_ASM | ||
42 | #if defined FLAC__SYS_DARWIN | ||
43 | #include <sys/sysctl.h> | ||
44 | #include <mach/mach.h> | ||
45 | #include <mach/mach_host.h> | ||
46 | #include <mach/host_info.h> | ||
47 | #include <mach/machine.h> | ||
48 | #ifndef CPU_SUBTYPE_POWERPC_970 | ||
49 | #define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) | ||
50 | #endif | ||
51 | #else /* FLAC__SYS_DARWIN */ | ||
52 | #include <signal.h> | ||
53 | #include <setjmp.h> | ||
54 | |||
55 | static sigjmp_buf jmpbuf; | ||
56 | static volatile sig_atomic_t canjump = 0; | ||
57 | |||
58 | static void sigill_handler (int sig) | ||
59 | { | ||
60 | if (!canjump) { | ||
61 | signal (sig, SIG_DFL); | ||
62 | raise (sig); | ||
63 | } | ||
64 | canjump = 0; | ||
65 | siglongjmp (jmpbuf, 1); | ||
66 | } | ||
67 | #endif /* FLAC__SYS_DARWIN */ | ||
68 | #endif /* FLAC__NO_ASM */ | ||
69 | #endif /* FLAC__CPU_PPC */ | ||
70 | |||
71 | const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; | ||
72 | const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; | ||
73 | const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; | ||
74 | const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; | ||
75 | const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; | ||
76 | |||
77 | const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000; | ||
78 | const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000; | ||
79 | const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000; | ||
80 | |||
81 | |||
82 | void FLAC__cpu_info(FLAC__CPUInfo *info) | ||
83 | { | ||
84 | #ifdef FLAC__CPU_IA32 | ||
85 | info->type = FLAC__CPUINFO_TYPE_IA32; | ||
86 | #if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM | ||
87 | info->use_asm = true; | ||
88 | { | ||
89 | unsigned cpuid = FLAC__cpu_info_asm_ia32(); | ||
90 | info->data.ia32.cmov = (cpuid & FLAC__CPUINFO_IA32_CPUID_CMOV)? true : false; | ||
91 | info->data.ia32.mmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_MMX)? true : false; | ||
92 | info->data.ia32.fxsr = (cpuid & FLAC__CPUINFO_IA32_CPUID_FXSR)? true : false; | ||
93 | info->data.ia32.sse = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE)? true : false; | ||
94 | info->data.ia32.sse2 = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE2)? true : false; | ||
95 | |||
96 | #ifndef FLAC__SSE_OS | ||
97 | info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = false; | ||
98 | #endif | ||
99 | |||
100 | #ifdef FLAC__USE_3DNOW | ||
101 | cpuid = FLAC__cpu_info_extended_amd_asm_ia32(); | ||
102 | info->data.ia32._3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW)? true : false; | ||
103 | info->data.ia32.ext3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false; | ||
104 | info->data.ia32.extmmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX)? true : false; | ||
105 | #else | ||
106 | info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false; | ||
107 | #endif | ||
108 | } | ||
109 | #else | ||
110 | info->use_asm = false; | ||
111 | #endif | ||
112 | #elif defined FLAC__CPU_PPC | ||
113 | info->type = FLAC__CPUINFO_TYPE_PPC; | ||
114 | #if !defined FLAC__NO_ASM | ||
115 | info->use_asm = true; | ||
116 | #ifdef FLAC__USE_ALTIVEC | ||
117 | #if defined FLAC__SYS_DARWIN | ||
118 | { | ||
119 | int selectors[2] = { CTL_HW, HW_VECTORUNIT }; | ||
120 | int result = 0; | ||
121 | size_t length = sizeof(result); | ||
122 | int error = sysctl(selectors, 2, &result, &length, 0, 0); | ||
123 | |||
124 | info->data.ppc.altivec = error==0 ? result!=0 : 0; | ||
125 | } | ||
126 | { | ||
127 | host_basic_info_data_t hostInfo; | ||
128 | mach_msg_type_number_t infoCount; | ||
129 | |||
130 | infoCount = HOST_BASIC_INFO_COUNT; | ||
131 | host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount); | ||
132 | |||
133 | info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970); | ||
134 | } | ||
135 | #else /* FLAC__SYS_DARWIN */ | ||
136 | { | ||
137 | /* no Darwin, do it the brute-force way */ | ||
138 | /* this is borrowed from MPlayer from the libmpeg2 library */ | ||
139 | info->data.ppc.altivec = 0; | ||
140 | info->data.ppc.ppc64 = 0; | ||
141 | |||
142 | signal (SIGILL, sigill_handler); | ||
143 | if (!sigsetjmp (jmpbuf, 1)) { | ||
144 | canjump = 1; | ||
145 | |||
146 | asm volatile ( | ||
147 | "mtspr 256, %0\n\t" | ||
148 | "vand %%v0, %%v0, %%v0" | ||
149 | : | ||
150 | : "r" (-1) | ||
151 | ); | ||
152 | |||
153 | info->data.ppc.altivec = 1; | ||
154 | } | ||
155 | canjump = 0; | ||
156 | if (!sigsetjmp (jmpbuf, 1)) { | ||
157 | int x = 0; | ||
158 | canjump = 1; | ||
159 | |||
160 | /* PPC64 hardware implements the cntlzd instruction */ | ||
161 | asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) ); | ||
162 | |||
163 | info->data.ppc.ppc64 = 1; | ||
164 | } | ||
165 | signal (SIGILL, SIG_DFL); | ||
166 | } | ||
167 | #endif /* FLAC__SYS_DARWIN */ | ||
168 | #else /* FLAC__USE_ALTIVEC */ | ||
169 | info->data.ppc.altivec = 0; | ||
170 | info->data.ppc.ppc64 = 0; | ||
171 | #endif /* FLAC__USE_ALTIVEC */ | ||
172 | #else /* FLAC__NO_ASM */ | ||
173 | info->use_asm = false; | ||
174 | #endif /* FLAC__NO_ASM */ | ||
175 | #else | ||
176 | info->type = FLAC__CPUINFO_TYPE_UNKNOWN; | ||
177 | info->use_asm = false; | ||
178 | #endif | ||
179 | } | ||
diff --git a/apps/codecs/libFLAC/crc.c b/apps/codecs/libFLAC/crc.c new file mode 100644 index 0000000000..52e1b600ea --- /dev/null +++ b/apps/codecs/libFLAC/crc.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include "private/crc.h" | ||
33 | |||
34 | /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ | ||
35 | |||
36 | FLAC__byte const FLAC__crc8_table[256] = { | ||
37 | 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, | ||
38 | 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, | ||
39 | 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, | ||
40 | 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, | ||
41 | 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, | ||
42 | 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, | ||
43 | 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, | ||
44 | 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, | ||
45 | 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, | ||
46 | 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, | ||
47 | 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, | ||
48 | 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, | ||
49 | 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, | ||
50 | 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, | ||
51 | 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, | ||
52 | 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, | ||
53 | 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, | ||
54 | 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, | ||
55 | 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, | ||
56 | 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, | ||
57 | 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, | ||
58 | 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, | ||
59 | 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, | ||
60 | 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, | ||
61 | 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, | ||
62 | 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, | ||
63 | 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, | ||
64 | 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, | ||
65 | 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, | ||
66 | 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, | ||
67 | 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, | ||
68 | 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 | ||
69 | }; | ||
70 | |||
71 | /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ | ||
72 | |||
73 | FLAC__uint16 FLAC__crc16_table[256] = { | ||
74 | 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, | ||
75 | 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, | ||
76 | 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, | ||
77 | 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, | ||
78 | 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, | ||
79 | 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, | ||
80 | 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, | ||
81 | 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, | ||
82 | 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, | ||
83 | 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, | ||
84 | 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, | ||
85 | 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, | ||
86 | 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, | ||
87 | 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, | ||
88 | 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, | ||
89 | 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, | ||
90 | 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, | ||
91 | 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, | ||
92 | 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, | ||
93 | 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, | ||
94 | 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, | ||
95 | 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, | ||
96 | 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, | ||
97 | 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, | ||
98 | 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, | ||
99 | 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, | ||
100 | 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, | ||
101 | 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, | ||
102 | 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, | ||
103 | 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, | ||
104 | 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, | ||
105 | 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 | ||
106 | }; | ||
107 | |||
108 | |||
109 | void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc) | ||
110 | { | ||
111 | *crc = FLAC__crc8_table[*crc ^ data]; | ||
112 | } | ||
113 | |||
114 | void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc) | ||
115 | { | ||
116 | while(len--) | ||
117 | *crc = FLAC__crc8_table[*crc ^ *data++]; | ||
118 | } | ||
119 | |||
120 | FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len) | ||
121 | { | ||
122 | FLAC__uint8 crc = 0; | ||
123 | |||
124 | while(len--) | ||
125 | crc = FLAC__crc8_table[crc ^ *data++]; | ||
126 | |||
127 | return crc; | ||
128 | } | ||
129 | |||
130 | void FLAC__crc16_update(const FLAC__byte data, FLAC__uint16 *crc) | ||
131 | { | ||
132 | *crc = (*crc<<8) ^ FLAC__crc16_table[(*crc>>8) ^ data]; | ||
133 | } | ||
134 | |||
135 | void FLAC__crc16_update_block(const FLAC__byte *data, unsigned len, FLAC__uint16 *crc) | ||
136 | { | ||
137 | while(len--) | ||
138 | *crc = (*crc<<8) ^ FLAC__crc16_table[(*crc>>8) ^ *data++]; | ||
139 | } | ||
140 | |||
141 | FLAC__uint16 FLAC__crc16(const FLAC__byte *data, unsigned len) | ||
142 | { | ||
143 | FLAC__uint16 crc = 0; | ||
144 | |||
145 | while(len--) | ||
146 | crc = (crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]; | ||
147 | |||
148 | return crc; | ||
149 | } | ||
diff --git a/apps/codecs/libFLAC/file_decoder.c b/apps/codecs/libFLAC/file_decoder.c new file mode 100644 index 0000000000..29d489587a --- /dev/null +++ b/apps/codecs/libFLAC/file_decoder.c | |||
@@ -0,0 +1,673 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for malloc() */ | ||
34 | #include <string.h> /* for strcmp() */ | ||
35 | #include <sys/stat.h> /* for stat() */ | ||
36 | #if defined _MSC_VER || defined __MINGW32__ | ||
37 | #include <io.h> /* for _setmode() */ | ||
38 | #include <fcntl.h> /* for _O_BINARY */ | ||
39 | #elif defined __CYGWIN__ | ||
40 | #include <io.h> /* for setmode(), O_BINARY */ | ||
41 | #include <fcntl.h> /* for _O_BINARY */ | ||
42 | #endif | ||
43 | #include "FLAC/assert.h" | ||
44 | #include "protected/file_decoder.h" | ||
45 | #include "protected/seekable_stream_decoder.h" | ||
46 | |||
47 | /*********************************************************************** | ||
48 | * | ||
49 | * Private class method prototypes | ||
50 | * | ||
51 | ***********************************************************************/ | ||
52 | |||
53 | static void set_defaults_(FLAC__FileDecoder *decoder); | ||
54 | static FILE *get_binary_stdin_(); | ||
55 | static FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
56 | static FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
57 | static FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
58 | static FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); | ||
59 | static FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data); | ||
60 | static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
61 | static void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
62 | static void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
63 | |||
64 | /*********************************************************************** | ||
65 | * | ||
66 | * Private class data | ||
67 | * | ||
68 | ***********************************************************************/ | ||
69 | |||
70 | typedef struct FLAC__FileDecoderPrivate { | ||
71 | FLAC__FileDecoderWriteCallback write_callback; | ||
72 | FLAC__FileDecoderMetadataCallback metadata_callback; | ||
73 | FLAC__FileDecoderErrorCallback error_callback; | ||
74 | void *client_data; | ||
75 | FILE *file; | ||
76 | char *filename; /* == NULL if stdin */ | ||
77 | FLAC__SeekableStreamDecoder *seekable_stream_decoder; | ||
78 | } FLAC__FileDecoderPrivate; | ||
79 | |||
80 | /*********************************************************************** | ||
81 | * | ||
82 | * Public static class data | ||
83 | * | ||
84 | ***********************************************************************/ | ||
85 | |||
86 | FLAC_API const char * const FLAC__FileDecoderStateString[] = { | ||
87 | "FLAC__FILE_DECODER_OK", | ||
88 | "FLAC__FILE_DECODER_END_OF_FILE", | ||
89 | "FLAC__FILE_DECODER_ERROR_OPENING_FILE", | ||
90 | "FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR", | ||
91 | "FLAC__FILE_DECODER_SEEK_ERROR", | ||
92 | "FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR", | ||
93 | "FLAC__FILE_DECODER_ALREADY_INITIALIZED", | ||
94 | "FLAC__FILE_DECODER_INVALID_CALLBACK", | ||
95 | "FLAC__FILE_DECODER_UNINITIALIZED" | ||
96 | }; | ||
97 | |||
98 | /*********************************************************************** | ||
99 | * | ||
100 | * Class constructor/destructor | ||
101 | * | ||
102 | ***********************************************************************/ | ||
103 | |||
104 | FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new() | ||
105 | { | ||
106 | FLAC__FileDecoder *decoder; | ||
107 | |||
108 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
109 | |||
110 | decoder = (FLAC__FileDecoder*)calloc(1, sizeof(FLAC__FileDecoder)); | ||
111 | if(decoder == 0) { | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | decoder->protected_ = (FLAC__FileDecoderProtected*)calloc(1, sizeof(FLAC__FileDecoderProtected)); | ||
116 | if(decoder->protected_ == 0) { | ||
117 | free(decoder); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | decoder->private_ = (FLAC__FileDecoderPrivate*)calloc(1, sizeof(FLAC__FileDecoderPrivate)); | ||
122 | if(decoder->private_ == 0) { | ||
123 | free(decoder->protected_); | ||
124 | free(decoder); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | decoder->private_->seekable_stream_decoder = FLAC__seekable_stream_decoder_new(); | ||
129 | if(0 == decoder->private_->seekable_stream_decoder) { | ||
130 | free(decoder->private_); | ||
131 | free(decoder->protected_); | ||
132 | free(decoder); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | decoder->private_->file = 0; | ||
137 | |||
138 | set_defaults_(decoder); | ||
139 | |||
140 | decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED; | ||
141 | |||
142 | return decoder; | ||
143 | } | ||
144 | |||
145 | FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder) | ||
146 | { | ||
147 | FLAC__ASSERT(0 != decoder); | ||
148 | FLAC__ASSERT(0 != decoder->protected_); | ||
149 | FLAC__ASSERT(0 != decoder->private_); | ||
150 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
151 | |||
152 | (void)FLAC__file_decoder_finish(decoder); | ||
153 | |||
154 | FLAC__seekable_stream_decoder_delete(decoder->private_->seekable_stream_decoder); | ||
155 | |||
156 | free(decoder->private_); | ||
157 | free(decoder->protected_); | ||
158 | free(decoder); | ||
159 | } | ||
160 | |||
161 | /*********************************************************************** | ||
162 | * | ||
163 | * Public class methods | ||
164 | * | ||
165 | ***********************************************************************/ | ||
166 | |||
167 | FLAC_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder) | ||
168 | { | ||
169 | FLAC__ASSERT(0 != decoder); | ||
170 | |||
171 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
172 | return decoder->protected_->state = FLAC__FILE_DECODER_ALREADY_INITIALIZED; | ||
173 | |||
174 | if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) | ||
175 | return decoder->protected_->state = FLAC__FILE_DECODER_INVALID_CALLBACK; | ||
176 | |||
177 | if(0 == decoder->private_->filename) | ||
178 | decoder->private_->file = get_binary_stdin_(); | ||
179 | else | ||
180 | decoder->private_->file = fopen(decoder->private_->filename, "rb"); | ||
181 | |||
182 | if(decoder->private_->file == 0) | ||
183 | return decoder->protected_->state = FLAC__FILE_DECODER_ERROR_OPENING_FILE; | ||
184 | |||
185 | FLAC__seekable_stream_decoder_set_read_callback(decoder->private_->seekable_stream_decoder, read_callback_); | ||
186 | FLAC__seekable_stream_decoder_set_seek_callback(decoder->private_->seekable_stream_decoder, seek_callback_); | ||
187 | FLAC__seekable_stream_decoder_set_tell_callback(decoder->private_->seekable_stream_decoder, tell_callback_); | ||
188 | FLAC__seekable_stream_decoder_set_length_callback(decoder->private_->seekable_stream_decoder, length_callback_); | ||
189 | FLAC__seekable_stream_decoder_set_eof_callback(decoder->private_->seekable_stream_decoder, eof_callback_); | ||
190 | FLAC__seekable_stream_decoder_set_write_callback(decoder->private_->seekable_stream_decoder, write_callback_); | ||
191 | FLAC__seekable_stream_decoder_set_metadata_callback(decoder->private_->seekable_stream_decoder, metadata_callback_); | ||
192 | FLAC__seekable_stream_decoder_set_error_callback(decoder->private_->seekable_stream_decoder, error_callback_); | ||
193 | FLAC__seekable_stream_decoder_set_client_data(decoder->private_->seekable_stream_decoder, decoder); | ||
194 | |||
195 | if(FLAC__seekable_stream_decoder_init(decoder->private_->seekable_stream_decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) | ||
196 | return decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; | ||
197 | |||
198 | return decoder->protected_->state = FLAC__FILE_DECODER_OK; | ||
199 | } | ||
200 | |||
201 | FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder) | ||
202 | { | ||
203 | FLAC__ASSERT(0 != decoder); | ||
204 | |||
205 | if(decoder->protected_->state == FLAC__FILE_DECODER_UNINITIALIZED) | ||
206 | return true; | ||
207 | |||
208 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
209 | |||
210 | if(0 != decoder->private_->file && decoder->private_->file != stdin) { | ||
211 | fclose(decoder->private_->file); | ||
212 | decoder->private_->file = 0; | ||
213 | } | ||
214 | |||
215 | if(0 != decoder->private_->filename) { | ||
216 | free(decoder->private_->filename); | ||
217 | decoder->private_->filename = 0; | ||
218 | } | ||
219 | |||
220 | set_defaults_(decoder); | ||
221 | |||
222 | decoder->protected_->state = FLAC__FILE_DECODER_UNINITIALIZED; | ||
223 | |||
224 | return FLAC__seekable_stream_decoder_finish(decoder->private_->seekable_stream_decoder); | ||
225 | } | ||
226 | |||
227 | FLAC_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value) | ||
228 | { | ||
229 | FLAC__ASSERT(0 != decoder); | ||
230 | FLAC__ASSERT(0 != decoder->private_); | ||
231 | FLAC__ASSERT(0 != decoder->protected_); | ||
232 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
233 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
234 | return false; | ||
235 | return FLAC__seekable_stream_decoder_set_md5_checking(decoder->private_->seekable_stream_decoder, value); | ||
236 | } | ||
237 | |||
238 | FLAC_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value) | ||
239 | { | ||
240 | FLAC__ASSERT(0 != decoder); | ||
241 | FLAC__ASSERT(0 != decoder->private_); | ||
242 | FLAC__ASSERT(0 != decoder->protected_); | ||
243 | FLAC__ASSERT(0 != value); | ||
244 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
245 | return false; | ||
246 | if(0 != decoder->private_->filename) { | ||
247 | free(decoder->private_->filename); | ||
248 | decoder->private_->filename = 0; | ||
249 | } | ||
250 | if(0 != strcmp(value, "-")) { | ||
251 | if(0 == (decoder->private_->filename = (char*)malloc(strlen(value)+1))) { | ||
252 | decoder->protected_->state = FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR; | ||
253 | return false; | ||
254 | } | ||
255 | strcpy(decoder->private_->filename, value); | ||
256 | } | ||
257 | return true; | ||
258 | } | ||
259 | |||
260 | FLAC_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value) | ||
261 | { | ||
262 | FLAC__ASSERT(0 != decoder); | ||
263 | FLAC__ASSERT(0 != decoder->private_); | ||
264 | FLAC__ASSERT(0 != decoder->protected_); | ||
265 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
266 | return false; | ||
267 | decoder->private_->write_callback = value; | ||
268 | return true; | ||
269 | } | ||
270 | |||
271 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value) | ||
272 | { | ||
273 | FLAC__ASSERT(0 != decoder); | ||
274 | FLAC__ASSERT(0 != decoder->private_); | ||
275 | FLAC__ASSERT(0 != decoder->protected_); | ||
276 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
277 | return false; | ||
278 | decoder->private_->metadata_callback = value; | ||
279 | return true; | ||
280 | } | ||
281 | |||
282 | FLAC_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value) | ||
283 | { | ||
284 | FLAC__ASSERT(0 != decoder); | ||
285 | FLAC__ASSERT(0 != decoder->private_); | ||
286 | FLAC__ASSERT(0 != decoder->protected_); | ||
287 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
288 | return false; | ||
289 | decoder->private_->error_callback = value; | ||
290 | return true; | ||
291 | } | ||
292 | |||
293 | FLAC_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value) | ||
294 | { | ||
295 | FLAC__ASSERT(0 != decoder); | ||
296 | FLAC__ASSERT(0 != decoder->private_); | ||
297 | FLAC__ASSERT(0 != decoder->protected_); | ||
298 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
299 | return false; | ||
300 | decoder->private_->client_data = value; | ||
301 | return true; | ||
302 | } | ||
303 | |||
304 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type) | ||
305 | { | ||
306 | FLAC__ASSERT(0 != decoder); | ||
307 | FLAC__ASSERT(0 != decoder->private_); | ||
308 | FLAC__ASSERT(0 != decoder->protected_); | ||
309 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
310 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
311 | return false; | ||
312 | return FLAC__seekable_stream_decoder_set_metadata_respond(decoder->private_->seekable_stream_decoder, type); | ||
313 | } | ||
314 | |||
315 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4]) | ||
316 | { | ||
317 | FLAC__ASSERT(0 != decoder); | ||
318 | FLAC__ASSERT(0 != decoder->private_); | ||
319 | FLAC__ASSERT(0 != decoder->protected_); | ||
320 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
321 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
322 | return false; | ||
323 | return FLAC__seekable_stream_decoder_set_metadata_respond_application(decoder->private_->seekable_stream_decoder, id); | ||
324 | } | ||
325 | |||
326 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder) | ||
327 | { | ||
328 | FLAC__ASSERT(0 != decoder); | ||
329 | FLAC__ASSERT(0 != decoder->private_); | ||
330 | FLAC__ASSERT(0 != decoder->protected_); | ||
331 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
332 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
333 | return false; | ||
334 | return FLAC__seekable_stream_decoder_set_metadata_respond_all(decoder->private_->seekable_stream_decoder); | ||
335 | } | ||
336 | |||
337 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type) | ||
338 | { | ||
339 | FLAC__ASSERT(0 != decoder); | ||
340 | FLAC__ASSERT(0 != decoder->private_); | ||
341 | FLAC__ASSERT(0 != decoder->protected_); | ||
342 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
343 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
344 | return false; | ||
345 | return FLAC__seekable_stream_decoder_set_metadata_ignore(decoder->private_->seekable_stream_decoder, type); | ||
346 | } | ||
347 | |||
348 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4]) | ||
349 | { | ||
350 | FLAC__ASSERT(0 != decoder); | ||
351 | FLAC__ASSERT(0 != decoder->private_); | ||
352 | FLAC__ASSERT(0 != decoder->protected_); | ||
353 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
354 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
355 | return false; | ||
356 | return FLAC__seekable_stream_decoder_set_metadata_ignore_application(decoder->private_->seekable_stream_decoder, id); | ||
357 | } | ||
358 | |||
359 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder) | ||
360 | { | ||
361 | FLAC__ASSERT(0 != decoder); | ||
362 | FLAC__ASSERT(0 != decoder->private_); | ||
363 | FLAC__ASSERT(0 != decoder->protected_); | ||
364 | FLAC__ASSERT(0 != decoder->private_->seekable_stream_decoder); | ||
365 | if(decoder->protected_->state != FLAC__FILE_DECODER_UNINITIALIZED) | ||
366 | return false; | ||
367 | return FLAC__seekable_stream_decoder_set_metadata_ignore_all(decoder->private_->seekable_stream_decoder); | ||
368 | } | ||
369 | |||
370 | FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder) | ||
371 | { | ||
372 | FLAC__ASSERT(0 != decoder); | ||
373 | FLAC__ASSERT(0 != decoder->protected_); | ||
374 | return decoder->protected_->state; | ||
375 | } | ||
376 | |||
377 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder) | ||
378 | { | ||
379 | FLAC__ASSERT(0 != decoder); | ||
380 | FLAC__ASSERT(0 != decoder->private_); | ||
381 | return FLAC__seekable_stream_decoder_get_state(decoder->private_->seekable_stream_decoder); | ||
382 | } | ||
383 | |||
384 | FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder) | ||
385 | { | ||
386 | FLAC__ASSERT(0 != decoder); | ||
387 | FLAC__ASSERT(0 != decoder->private_); | ||
388 | return FLAC__seekable_stream_decoder_get_stream_decoder_state(decoder->private_->seekable_stream_decoder); | ||
389 | } | ||
390 | |||
391 | FLAC_API const char *FLAC__file_decoder_get_resolved_state_string(const FLAC__FileDecoder *decoder) | ||
392 | { | ||
393 | if(decoder->protected_->state != FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR) | ||
394 | return FLAC__FileDecoderStateString[decoder->protected_->state]; | ||
395 | else | ||
396 | return FLAC__seekable_stream_decoder_get_resolved_state_string(decoder->private_->seekable_stream_decoder); | ||
397 | } | ||
398 | |||
399 | FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder) | ||
400 | { | ||
401 | FLAC__ASSERT(0 != decoder); | ||
402 | FLAC__ASSERT(0 != decoder->private_); | ||
403 | return FLAC__seekable_stream_decoder_get_md5_checking(decoder->private_->seekable_stream_decoder); | ||
404 | } | ||
405 | |||
406 | FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder) | ||
407 | { | ||
408 | FLAC__ASSERT(0 != decoder); | ||
409 | FLAC__ASSERT(0 != decoder->private_); | ||
410 | return FLAC__seekable_stream_decoder_get_channels(decoder->private_->seekable_stream_decoder); | ||
411 | } | ||
412 | |||
413 | FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder) | ||
414 | { | ||
415 | FLAC__ASSERT(0 != decoder); | ||
416 | FLAC__ASSERT(0 != decoder->private_); | ||
417 | return FLAC__seekable_stream_decoder_get_channel_assignment(decoder->private_->seekable_stream_decoder); | ||
418 | } | ||
419 | |||
420 | FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder) | ||
421 | { | ||
422 | FLAC__ASSERT(0 != decoder); | ||
423 | FLAC__ASSERT(0 != decoder->private_); | ||
424 | return FLAC__seekable_stream_decoder_get_bits_per_sample(decoder->private_->seekable_stream_decoder); | ||
425 | } | ||
426 | |||
427 | FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder) | ||
428 | { | ||
429 | FLAC__ASSERT(0 != decoder); | ||
430 | FLAC__ASSERT(0 != decoder->private_); | ||
431 | return FLAC__seekable_stream_decoder_get_sample_rate(decoder->private_->seekable_stream_decoder); | ||
432 | } | ||
433 | |||
434 | FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder) | ||
435 | { | ||
436 | FLAC__ASSERT(0 != decoder); | ||
437 | FLAC__ASSERT(0 != decoder->private_); | ||
438 | return FLAC__seekable_stream_decoder_get_blocksize(decoder->private_->seekable_stream_decoder); | ||
439 | } | ||
440 | |||
441 | FLAC_API FLAC__bool FLAC__file_decoder_get_decode_position(const FLAC__FileDecoder *decoder, FLAC__uint64 *position) | ||
442 | { | ||
443 | FLAC__ASSERT(0 != decoder); | ||
444 | FLAC__ASSERT(0 != decoder->private_); | ||
445 | return FLAC__seekable_stream_decoder_get_decode_position(decoder->private_->seekable_stream_decoder, position); | ||
446 | } | ||
447 | |||
448 | FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder) | ||
449 | { | ||
450 | FLAC__bool ret; | ||
451 | FLAC__ASSERT(0 != decoder); | ||
452 | |||
453 | if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
454 | decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE; | ||
455 | |||
456 | if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE) | ||
457 | return true; | ||
458 | |||
459 | FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK); | ||
460 | |||
461 | ret = FLAC__seekable_stream_decoder_process_single(decoder->private_->seekable_stream_decoder); | ||
462 | if(!ret) | ||
463 | decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; | ||
464 | |||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder) | ||
469 | { | ||
470 | FLAC__bool ret; | ||
471 | FLAC__ASSERT(0 != decoder); | ||
472 | |||
473 | if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
474 | decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE; | ||
475 | |||
476 | if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE) | ||
477 | return true; | ||
478 | |||
479 | FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK); | ||
480 | |||
481 | ret = FLAC__seekable_stream_decoder_process_until_end_of_metadata(decoder->private_->seekable_stream_decoder); | ||
482 | if(!ret) | ||
483 | decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; | ||
484 | |||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder) | ||
489 | { | ||
490 | FLAC__bool ret; | ||
491 | FLAC__ASSERT(0 != decoder); | ||
492 | |||
493 | if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
494 | decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE; | ||
495 | |||
496 | if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE) | ||
497 | return true; | ||
498 | |||
499 | FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK); | ||
500 | |||
501 | ret = FLAC__seekable_stream_decoder_process_until_end_of_stream(decoder->private_->seekable_stream_decoder); | ||
502 | if(!ret) | ||
503 | decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; | ||
504 | |||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | FLAC_API FLAC__bool FLAC__file_decoder_skip_single_frame(FLAC__FileDecoder *decoder) | ||
509 | { | ||
510 | FLAC__bool ret; | ||
511 | FLAC__ASSERT(0 != decoder); | ||
512 | |||
513 | if(decoder->private_->seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
514 | decoder->protected_->state = FLAC__FILE_DECODER_END_OF_FILE; | ||
515 | |||
516 | if(decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE) | ||
517 | return true; | ||
518 | |||
519 | FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK); | ||
520 | |||
521 | ret = FLAC__seekable_stream_decoder_skip_single_frame(decoder->private_->seekable_stream_decoder); | ||
522 | if(!ret) | ||
523 | decoder->protected_->state = FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR; | ||
524 | |||
525 | return ret; | ||
526 | } | ||
527 | |||
528 | FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample) | ||
529 | { | ||
530 | FLAC__ASSERT(0 != decoder); | ||
531 | FLAC__ASSERT(decoder->protected_->state == FLAC__FILE_DECODER_OK || decoder->protected_->state == FLAC__FILE_DECODER_END_OF_FILE); | ||
532 | |||
533 | if(decoder->private_->filename == 0) { /* means the file is stdin... */ | ||
534 | decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR; | ||
535 | return false; | ||
536 | } | ||
537 | |||
538 | if(!FLAC__seekable_stream_decoder_seek_absolute(decoder->private_->seekable_stream_decoder, sample)) { | ||
539 | decoder->protected_->state = FLAC__FILE_DECODER_SEEK_ERROR; | ||
540 | return false; | ||
541 | } | ||
542 | else { | ||
543 | decoder->protected_->state = FLAC__FILE_DECODER_OK; | ||
544 | return true; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | |||
549 | /*********************************************************************** | ||
550 | * | ||
551 | * Private class methods | ||
552 | * | ||
553 | ***********************************************************************/ | ||
554 | |||
555 | void set_defaults_(FLAC__FileDecoder *decoder) | ||
556 | { | ||
557 | FLAC__ASSERT(0 != decoder); | ||
558 | FLAC__ASSERT(0 != decoder->private_); | ||
559 | |||
560 | decoder->private_->filename = 0; | ||
561 | decoder->private_->write_callback = 0; | ||
562 | decoder->private_->metadata_callback = 0; | ||
563 | decoder->private_->error_callback = 0; | ||
564 | decoder->private_->client_data = 0; | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | * This will forcibly set stdin to binary mode (for OSes that require it) | ||
569 | */ | ||
570 | FILE *get_binary_stdin_() | ||
571 | { | ||
572 | /* if something breaks here it is probably due to the presence or | ||
573 | * absence of an underscore before the identifiers 'setmode', | ||
574 | * 'fileno', and/or 'O_BINARY'; check your system header files. | ||
575 | */ | ||
576 | #if defined _MSC_VER || defined __MINGW32__ | ||
577 | _setmode(_fileno(stdin), _O_BINARY); | ||
578 | #elif defined __CYGWIN__ | ||
579 | /* almost certainly not needed for any modern Cygwin, but let's be safe... */ | ||
580 | setmode(_fileno(stdin), _O_BINARY); | ||
581 | #endif | ||
582 | |||
583 | return stdin; | ||
584 | } | ||
585 | |||
586 | FLAC__SeekableStreamDecoderReadStatus read_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) | ||
587 | { | ||
588 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
589 | (void)decoder; | ||
590 | |||
591 | if(*bytes > 0) { | ||
592 | *bytes = (unsigned)fread(buffer, sizeof(FLAC__byte), *bytes, file_decoder->private_->file); | ||
593 | if(ferror(file_decoder->private_->file)) { | ||
594 | return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; | ||
595 | } | ||
596 | else { | ||
597 | return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; | ||
598 | } | ||
599 | } | ||
600 | else | ||
601 | return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; /* abort to avoid a deadlock */ | ||
602 | } | ||
603 | |||
604 | FLAC__SeekableStreamDecoderSeekStatus seek_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) | ||
605 | { | ||
606 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
607 | (void)decoder; | ||
608 | |||
609 | if(fseek(file_decoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0) | ||
610 | return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; | ||
611 | else | ||
612 | return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; | ||
613 | } | ||
614 | |||
615 | FLAC__SeekableStreamDecoderTellStatus tell_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | ||
616 | { | ||
617 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
618 | long pos; | ||
619 | (void)decoder; | ||
620 | |||
621 | if((pos = ftell(file_decoder->private_->file)) < 0) | ||
622 | return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR; | ||
623 | else { | ||
624 | *absolute_byte_offset = (FLAC__uint64)pos; | ||
625 | return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; | ||
626 | } | ||
627 | } | ||
628 | |||
629 | FLAC__SeekableStreamDecoderLengthStatus length_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) | ||
630 | { | ||
631 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
632 | struct stat filestats; | ||
633 | (void)decoder; | ||
634 | |||
635 | if(0 == file_decoder->private_->filename || stat(file_decoder->private_->filename, &filestats) != 0) | ||
636 | return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR; | ||
637 | else { | ||
638 | *stream_length = (FLAC__uint64)filestats.st_size; | ||
639 | return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | FLAC__bool eof_callback_(const FLAC__SeekableStreamDecoder *decoder, void *client_data) | ||
644 | { | ||
645 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
646 | (void)decoder; | ||
647 | |||
648 | return feof(file_decoder->private_->file)? true : false; | ||
649 | } | ||
650 | |||
651 | FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) | ||
652 | { | ||
653 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
654 | (void)decoder; | ||
655 | |||
656 | return file_decoder->private_->write_callback(file_decoder, frame, buffer, file_decoder->private_->client_data); | ||
657 | } | ||
658 | |||
659 | void metadata_callback_(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) | ||
660 | { | ||
661 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
662 | (void)decoder; | ||
663 | |||
664 | file_decoder->private_->metadata_callback(file_decoder, metadata, file_decoder->private_->client_data); | ||
665 | } | ||
666 | |||
667 | void error_callback_(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) | ||
668 | { | ||
669 | FLAC__FileDecoder *file_decoder = (FLAC__FileDecoder *)client_data; | ||
670 | (void)decoder; | ||
671 | |||
672 | file_decoder->private_->error_callback(file_decoder, status, file_decoder->private_->client_data); | ||
673 | } | ||
diff --git a/apps/codecs/libFLAC/file_encoder.c b/apps/codecs/libFLAC/file_encoder.c new file mode 100644 index 0000000000..db4c421f98 --- /dev/null +++ b/apps/codecs/libFLAC/file_encoder.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for malloc() */ | ||
34 | #include <string.h> /* for strlen(), strcpy() */ | ||
35 | #include "FLAC/assert.h" | ||
36 | #include "protected/file_encoder.h" | ||
37 | |||
38 | #ifdef max | ||
39 | #undef max | ||
40 | #endif | ||
41 | #define max(x,y) ((x)>(y)?(x):(y)) | ||
42 | |||
43 | /*********************************************************************** | ||
44 | * | ||
45 | * Private class method prototypes | ||
46 | * | ||
47 | ***********************************************************************/ | ||
48 | |||
49 | /* unpublished debug routines */ | ||
50 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
51 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
52 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
53 | |||
54 | static void set_defaults_(FLAC__FileEncoder *encoder); | ||
55 | static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
56 | static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
57 | static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); | ||
58 | |||
59 | /*********************************************************************** | ||
60 | * | ||
61 | * Private class data | ||
62 | * | ||
63 | ***********************************************************************/ | ||
64 | |||
65 | typedef struct FLAC__FileEncoderPrivate { | ||
66 | FLAC__FileEncoderProgressCallback progress_callback; | ||
67 | void *client_data; | ||
68 | char *filename; | ||
69 | FLAC__uint64 bytes_written; | ||
70 | FLAC__uint64 samples_written; | ||
71 | unsigned frames_written; | ||
72 | unsigned total_frames_estimate; | ||
73 | FLAC__SeekableStreamEncoder *seekable_stream_encoder; | ||
74 | FILE *file; | ||
75 | } FLAC__FileEncoderPrivate; | ||
76 | |||
77 | /*********************************************************************** | ||
78 | * | ||
79 | * Public static class data | ||
80 | * | ||
81 | ***********************************************************************/ | ||
82 | |||
83 | FLAC_API const char * const FLAC__FileEncoderStateString[] = { | ||
84 | "FLAC__FILE_ENCODER_OK", | ||
85 | "FLAC__FILE_ENCODER_NO_FILENAME", | ||
86 | "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR", | ||
87 | "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING", | ||
88 | "FLAC__FILE_ENCODER_ERROR_OPENING_FILE", | ||
89 | "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR", | ||
90 | "FLAC__FILE_ENCODER_ALREADY_INITIALIZED", | ||
91 | "FLAC__FILE_ENCODER_UNINITIALIZED" | ||
92 | }; | ||
93 | |||
94 | |||
95 | /*********************************************************************** | ||
96 | * | ||
97 | * Class constructor/destructor | ||
98 | * | ||
99 | ***********************************************************************/ | ||
100 | |||
101 | FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new() | ||
102 | { | ||
103 | FLAC__FileEncoder *encoder; | ||
104 | |||
105 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
106 | |||
107 | encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder)); | ||
108 | if(encoder == 0) { | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected)); | ||
113 | if(encoder->protected_ == 0) { | ||
114 | free(encoder); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate)); | ||
119 | if(encoder->private_ == 0) { | ||
120 | free(encoder->protected_); | ||
121 | free(encoder); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new(); | ||
126 | if(0 == encoder->private_->seekable_stream_encoder) { | ||
127 | free(encoder->private_); | ||
128 | free(encoder->protected_); | ||
129 | free(encoder); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | encoder->private_->file = 0; | ||
134 | |||
135 | set_defaults_(encoder); | ||
136 | |||
137 | encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; | ||
138 | |||
139 | return encoder; | ||
140 | } | ||
141 | |||
142 | FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder) | ||
143 | { | ||
144 | FLAC__ASSERT(0 != encoder); | ||
145 | FLAC__ASSERT(0 != encoder->protected_); | ||
146 | FLAC__ASSERT(0 != encoder->private_); | ||
147 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
148 | |||
149 | (void)FLAC__file_encoder_finish(encoder); | ||
150 | |||
151 | FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder); | ||
152 | |||
153 | free(encoder->private_); | ||
154 | free(encoder->protected_); | ||
155 | free(encoder); | ||
156 | } | ||
157 | |||
158 | /*********************************************************************** | ||
159 | * | ||
160 | * Public class methods | ||
161 | * | ||
162 | ***********************************************************************/ | ||
163 | |||
164 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder) | ||
165 | { | ||
166 | FLAC__ASSERT(0 != encoder); | ||
167 | |||
168 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
169 | return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED; | ||
170 | |||
171 | if(0 == encoder->private_->filename) | ||
172 | return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME; | ||
173 | |||
174 | encoder->private_->file = fopen(encoder->private_->filename, "w+b"); | ||
175 | |||
176 | if(encoder->private_->file == 0) | ||
177 | return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE; | ||
178 | |||
179 | encoder->private_->bytes_written = 0; | ||
180 | encoder->private_->samples_written = 0; | ||
181 | encoder->private_->frames_written = 0; | ||
182 | |||
183 | FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_); | ||
184 | FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_); | ||
185 | FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_); | ||
186 | FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder); | ||
187 | |||
188 | if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK) | ||
189 | return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
190 | |||
191 | { | ||
192 | unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder); | ||
193 | |||
194 | FLAC__ASSERT(blocksize != 0); | ||
195 | encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize); | ||
196 | } | ||
197 | |||
198 | return encoder->protected_->state = FLAC__FILE_ENCODER_OK; | ||
199 | } | ||
200 | |||
201 | FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder) | ||
202 | { | ||
203 | FLAC__ASSERT(0 != encoder); | ||
204 | |||
205 | if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED) | ||
206 | return; | ||
207 | |||
208 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
209 | |||
210 | /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */ | ||
211 | |||
212 | FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder); | ||
213 | |||
214 | if(0 != encoder->private_->file) { | ||
215 | fclose(encoder->private_->file); | ||
216 | encoder->private_->file = 0; | ||
217 | } | ||
218 | |||
219 | if(0 != encoder->private_->filename) { | ||
220 | free(encoder->private_->filename); | ||
221 | encoder->private_->filename = 0; | ||
222 | } | ||
223 | |||
224 | set_defaults_(encoder); | ||
225 | |||
226 | encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; | ||
227 | } | ||
228 | |||
229 | FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
230 | { | ||
231 | FLAC__ASSERT(0 != encoder); | ||
232 | FLAC__ASSERT(0 != encoder->private_); | ||
233 | FLAC__ASSERT(0 != encoder->protected_); | ||
234 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
235 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
236 | return false; | ||
237 | return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value); | ||
238 | } | ||
239 | |||
240 | FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
241 | { | ||
242 | FLAC__ASSERT(0 != encoder); | ||
243 | FLAC__ASSERT(0 != encoder->private_); | ||
244 | FLAC__ASSERT(0 != encoder->protected_); | ||
245 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
246 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
247 | return false; | ||
248 | return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value); | ||
249 | } | ||
250 | |||
251 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
252 | { | ||
253 | FLAC__ASSERT(0 != encoder); | ||
254 | FLAC__ASSERT(0 != encoder->private_); | ||
255 | FLAC__ASSERT(0 != encoder->protected_); | ||
256 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
257 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
258 | return false; | ||
259 | return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); | ||
260 | } | ||
261 | |||
262 | FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
263 | { | ||
264 | FLAC__ASSERT(0 != encoder); | ||
265 | FLAC__ASSERT(0 != encoder->private_); | ||
266 | FLAC__ASSERT(0 != encoder->protected_); | ||
267 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
268 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
269 | return false; | ||
270 | return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); | ||
271 | } | ||
272 | |||
273 | FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value) | ||
274 | { | ||
275 | FLAC__ASSERT(0 != encoder); | ||
276 | FLAC__ASSERT(0 != encoder->private_); | ||
277 | FLAC__ASSERT(0 != encoder->protected_); | ||
278 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
279 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
280 | return false; | ||
281 | return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value); | ||
282 | } | ||
283 | |||
284 | FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value) | ||
285 | { | ||
286 | FLAC__ASSERT(0 != encoder); | ||
287 | FLAC__ASSERT(0 != encoder->private_); | ||
288 | FLAC__ASSERT(0 != encoder->protected_); | ||
289 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
290 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
291 | return false; | ||
292 | return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value); | ||
293 | } | ||
294 | |||
295 | FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value) | ||
296 | { | ||
297 | FLAC__ASSERT(0 != encoder); | ||
298 | FLAC__ASSERT(0 != encoder->private_); | ||
299 | FLAC__ASSERT(0 != encoder->protected_); | ||
300 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
301 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
302 | return false; | ||
303 | return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value); | ||
304 | } | ||
305 | |||
306 | FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value) | ||
307 | { | ||
308 | FLAC__ASSERT(0 != encoder); | ||
309 | FLAC__ASSERT(0 != encoder->private_); | ||
310 | FLAC__ASSERT(0 != encoder->protected_); | ||
311 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
312 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
313 | return false; | ||
314 | return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value); | ||
315 | } | ||
316 | |||
317 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value) | ||
318 | { | ||
319 | FLAC__ASSERT(0 != encoder); | ||
320 | FLAC__ASSERT(0 != encoder->private_); | ||
321 | FLAC__ASSERT(0 != encoder->protected_); | ||
322 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
323 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
324 | return false; | ||
325 | return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value); | ||
326 | } | ||
327 | |||
328 | FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value) | ||
329 | { | ||
330 | FLAC__ASSERT(0 != encoder); | ||
331 | FLAC__ASSERT(0 != encoder->private_); | ||
332 | FLAC__ASSERT(0 != encoder->protected_); | ||
333 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
334 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
335 | return false; | ||
336 | return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value); | ||
337 | } | ||
338 | |||
339 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
340 | { | ||
341 | FLAC__ASSERT(0 != encoder); | ||
342 | FLAC__ASSERT(0 != encoder->private_); | ||
343 | FLAC__ASSERT(0 != encoder->protected_); | ||
344 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
345 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
346 | return false; | ||
347 | return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value); | ||
348 | } | ||
349 | |||
350 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
351 | { | ||
352 | FLAC__ASSERT(0 != encoder); | ||
353 | FLAC__ASSERT(0 != encoder->private_); | ||
354 | FLAC__ASSERT(0 != encoder->protected_); | ||
355 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
356 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
357 | return false; | ||
358 | return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value); | ||
359 | } | ||
360 | |||
361 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
362 | { | ||
363 | FLAC__ASSERT(0 != encoder); | ||
364 | FLAC__ASSERT(0 != encoder->private_); | ||
365 | FLAC__ASSERT(0 != encoder->protected_); | ||
366 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
367 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
368 | return false; | ||
369 | return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value); | ||
370 | } | ||
371 | |||
372 | FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) | ||
373 | { | ||
374 | FLAC__ASSERT(0 != encoder); | ||
375 | FLAC__ASSERT(0 != encoder->private_); | ||
376 | FLAC__ASSERT(0 != encoder->protected_); | ||
377 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
378 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
379 | return false; | ||
380 | return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value); | ||
381 | } | ||
382 | |||
383 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) | ||
384 | { | ||
385 | FLAC__ASSERT(0 != encoder); | ||
386 | FLAC__ASSERT(0 != encoder->private_); | ||
387 | FLAC__ASSERT(0 != encoder->protected_); | ||
388 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
389 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
390 | return false; | ||
391 | return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value); | ||
392 | } | ||
393 | |||
394 | FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value) | ||
395 | { | ||
396 | FLAC__ASSERT(0 != encoder); | ||
397 | FLAC__ASSERT(0 != encoder->private_); | ||
398 | FLAC__ASSERT(0 != encoder->protected_); | ||
399 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
400 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
401 | return false; | ||
402 | return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value); | ||
403 | } | ||
404 | |||
405 | FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value) | ||
406 | { | ||
407 | FLAC__ASSERT(0 != encoder); | ||
408 | FLAC__ASSERT(0 != encoder->private_); | ||
409 | FLAC__ASSERT(0 != encoder->protected_); | ||
410 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
411 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
412 | return false; | ||
413 | return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value); | ||
414 | } | ||
415 | |||
416 | FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) | ||
417 | { | ||
418 | FLAC__ASSERT(0 != encoder); | ||
419 | FLAC__ASSERT(0 != encoder->private_); | ||
420 | FLAC__ASSERT(0 != encoder->protected_); | ||
421 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
422 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
423 | return false; | ||
424 | return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks); | ||
425 | } | ||
426 | |||
427 | FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value) | ||
428 | { | ||
429 | FLAC__ASSERT(0 != encoder); | ||
430 | FLAC__ASSERT(0 != encoder->private_); | ||
431 | FLAC__ASSERT(0 != encoder->protected_); | ||
432 | FLAC__ASSERT(0 != value); | ||
433 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
434 | return false; | ||
435 | if(0 != encoder->private_->filename) { | ||
436 | free(encoder->private_->filename); | ||
437 | encoder->private_->filename = 0; | ||
438 | } | ||
439 | if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) { | ||
440 | encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
441 | return false; | ||
442 | } | ||
443 | strcpy(encoder->private_->filename, value); | ||
444 | return true; | ||
445 | } | ||
446 | |||
447 | FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value) | ||
448 | { | ||
449 | FLAC__ASSERT(0 != encoder); | ||
450 | FLAC__ASSERT(0 != encoder->private_); | ||
451 | FLAC__ASSERT(0 != encoder->protected_); | ||
452 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
453 | return false; | ||
454 | encoder->private_->progress_callback = value; | ||
455 | return true; | ||
456 | } | ||
457 | |||
458 | FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value) | ||
459 | { | ||
460 | FLAC__ASSERT(0 != encoder); | ||
461 | FLAC__ASSERT(0 != encoder->private_); | ||
462 | FLAC__ASSERT(0 != encoder->protected_); | ||
463 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
464 | return false; | ||
465 | encoder->private_->client_data = value; | ||
466 | return true; | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * These three functions are not static, but not publically exposed in | ||
471 | * include/FLAC/ either. They are used by the test suite. | ||
472 | */ | ||
473 | FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
474 | { | ||
475 | FLAC__ASSERT(0 != encoder); | ||
476 | FLAC__ASSERT(0 != encoder->private_); | ||
477 | FLAC__ASSERT(0 != encoder->protected_); | ||
478 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
479 | return false; | ||
480 | return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value); | ||
481 | } | ||
482 | |||
483 | FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
484 | { | ||
485 | FLAC__ASSERT(0 != encoder); | ||
486 | FLAC__ASSERT(0 != encoder->private_); | ||
487 | FLAC__ASSERT(0 != encoder->protected_); | ||
488 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
489 | return false; | ||
490 | return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value); | ||
491 | } | ||
492 | |||
493 | FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
494 | { | ||
495 | FLAC__ASSERT(0 != encoder); | ||
496 | FLAC__ASSERT(0 != encoder->private_); | ||
497 | FLAC__ASSERT(0 != encoder->protected_); | ||
498 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
499 | return false; | ||
500 | return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value); | ||
501 | } | ||
502 | |||
503 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder) | ||
504 | { | ||
505 | FLAC__ASSERT(0 != encoder); | ||
506 | FLAC__ASSERT(0 != encoder->protected_); | ||
507 | return encoder->protected_->state; | ||
508 | } | ||
509 | |||
510 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder) | ||
511 | { | ||
512 | FLAC__ASSERT(0 != encoder); | ||
513 | FLAC__ASSERT(0 != encoder->private_); | ||
514 | return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder); | ||
515 | } | ||
516 | |||
517 | FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder) | ||
518 | { | ||
519 | FLAC__ASSERT(0 != encoder); | ||
520 | FLAC__ASSERT(0 != encoder->private_); | ||
521 | return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder); | ||
522 | } | ||
523 | |||
524 | FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder) | ||
525 | { | ||
526 | FLAC__ASSERT(0 != encoder); | ||
527 | FLAC__ASSERT(0 != encoder->private_); | ||
528 | return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder); | ||
529 | } | ||
530 | |||
531 | FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder) | ||
532 | { | ||
533 | if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR) | ||
534 | return FLAC__FileEncoderStateString[encoder->protected_->state]; | ||
535 | else | ||
536 | return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder); | ||
537 | } | ||
538 | |||
539 | FLAC_API void FLAC__file_encoder_get_verify_decoder_error_stats(const FLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got) | ||
540 | { | ||
541 | FLAC__ASSERT(0 != encoder); | ||
542 | FLAC__ASSERT(0 != encoder->private_); | ||
543 | FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got); | ||
544 | } | ||
545 | |||
546 | FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder) | ||
547 | { | ||
548 | FLAC__ASSERT(0 != encoder); | ||
549 | FLAC__ASSERT(0 != encoder->private_); | ||
550 | return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder); | ||
551 | } | ||
552 | |||
553 | FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder) | ||
554 | { | ||
555 | FLAC__ASSERT(0 != encoder); | ||
556 | FLAC__ASSERT(0 != encoder->private_); | ||
557 | return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder); | ||
558 | } | ||
559 | |||
560 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder) | ||
561 | { | ||
562 | FLAC__ASSERT(0 != encoder); | ||
563 | FLAC__ASSERT(0 != encoder->private_); | ||
564 | return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder); | ||
565 | } | ||
566 | |||
567 | FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder) | ||
568 | { | ||
569 | FLAC__ASSERT(0 != encoder); | ||
570 | FLAC__ASSERT(0 != encoder->private_); | ||
571 | return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder); | ||
572 | } | ||
573 | |||
574 | FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder) | ||
575 | { | ||
576 | FLAC__ASSERT(0 != encoder); | ||
577 | FLAC__ASSERT(0 != encoder->private_); | ||
578 | return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder); | ||
579 | } | ||
580 | |||
581 | FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder) | ||
582 | { | ||
583 | FLAC__ASSERT(0 != encoder); | ||
584 | FLAC__ASSERT(0 != encoder->private_); | ||
585 | return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder); | ||
586 | } | ||
587 | |||
588 | FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder) | ||
589 | { | ||
590 | FLAC__ASSERT(0 != encoder); | ||
591 | FLAC__ASSERT(0 != encoder->private_); | ||
592 | return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder); | ||
593 | } | ||
594 | |||
595 | FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder) | ||
596 | { | ||
597 | FLAC__ASSERT(0 != encoder); | ||
598 | FLAC__ASSERT(0 != encoder->private_); | ||
599 | return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder); | ||
600 | } | ||
601 | |||
602 | FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder) | ||
603 | { | ||
604 | FLAC__ASSERT(0 != encoder); | ||
605 | FLAC__ASSERT(0 != encoder->private_); | ||
606 | return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder); | ||
607 | } | ||
608 | |||
609 | FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder) | ||
610 | { | ||
611 | FLAC__ASSERT(0 != encoder); | ||
612 | FLAC__ASSERT(0 != encoder->private_); | ||
613 | return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder); | ||
614 | } | ||
615 | |||
616 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder) | ||
617 | { | ||
618 | FLAC__ASSERT(0 != encoder); | ||
619 | FLAC__ASSERT(0 != encoder->private_); | ||
620 | return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder); | ||
621 | } | ||
622 | |||
623 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder) | ||
624 | { | ||
625 | FLAC__ASSERT(0 != encoder); | ||
626 | FLAC__ASSERT(0 != encoder->private_); | ||
627 | return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder); | ||
628 | } | ||
629 | |||
630 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder) | ||
631 | { | ||
632 | FLAC__ASSERT(0 != encoder); | ||
633 | FLAC__ASSERT(0 != encoder->private_); | ||
634 | return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder); | ||
635 | } | ||
636 | |||
637 | FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder) | ||
638 | { | ||
639 | FLAC__ASSERT(0 != encoder); | ||
640 | FLAC__ASSERT(0 != encoder->private_); | ||
641 | return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder); | ||
642 | } | ||
643 | |||
644 | FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder) | ||
645 | { | ||
646 | FLAC__ASSERT(0 != encoder); | ||
647 | FLAC__ASSERT(0 != encoder->private_); | ||
648 | return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder); | ||
649 | } | ||
650 | |||
651 | FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder) | ||
652 | { | ||
653 | FLAC__ASSERT(0 != encoder); | ||
654 | FLAC__ASSERT(0 != encoder->private_); | ||
655 | return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder); | ||
656 | } | ||
657 | |||
658 | FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder) | ||
659 | { | ||
660 | FLAC__ASSERT(0 != encoder); | ||
661 | FLAC__ASSERT(0 != encoder->private_); | ||
662 | return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder); | ||
663 | } | ||
664 | |||
665 | FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) | ||
666 | { | ||
667 | FLAC__ASSERT(0 != encoder); | ||
668 | FLAC__ASSERT(0 != encoder->private_); | ||
669 | if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) { | ||
670 | encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
671 | return false; | ||
672 | } | ||
673 | else | ||
674 | return true; | ||
675 | } | ||
676 | |||
677 | /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ | ||
678 | FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) | ||
679 | { | ||
680 | FLAC__ASSERT(0 != encoder); | ||
681 | FLAC__ASSERT(0 != encoder->private_); | ||
682 | if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) { | ||
683 | encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
684 | return false; | ||
685 | } | ||
686 | else | ||
687 | return true; | ||
688 | } | ||
689 | |||
690 | |||
691 | /*********************************************************************** | ||
692 | * | ||
693 | * Private class methods | ||
694 | * | ||
695 | ***********************************************************************/ | ||
696 | |||
697 | void set_defaults_(FLAC__FileEncoder *encoder) | ||
698 | { | ||
699 | FLAC__ASSERT(0 != encoder); | ||
700 | FLAC__ASSERT(0 != encoder->private_); | ||
701 | |||
702 | encoder->private_->progress_callback = 0; | ||
703 | encoder->private_->client_data = 0; | ||
704 | encoder->private_->total_frames_estimate = 0; | ||
705 | encoder->private_->filename = 0; | ||
706 | } | ||
707 | |||
708 | FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) | ||
709 | { | ||
710 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
711 | |||
712 | (void)encoder; | ||
713 | |||
714 | FLAC__ASSERT(0 != file_encoder); | ||
715 | |||
716 | if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0) | ||
717 | return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR; | ||
718 | else | ||
719 | return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK; | ||
720 | } | ||
721 | |||
722 | FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | ||
723 | { | ||
724 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
725 | long offset; | ||
726 | |||
727 | (void)encoder; | ||
728 | |||
729 | FLAC__ASSERT(0 != file_encoder); | ||
730 | |||
731 | offset = ftell(file_encoder->private_->file); | ||
732 | |||
733 | if(offset < 0) { | ||
734 | return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR; | ||
735 | } | ||
736 | else { | ||
737 | *absolute_byte_offset = (FLAC__uint64)offset; | ||
738 | return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK; | ||
739 | } | ||
740 | } | ||
741 | |||
742 | #ifdef FLAC__VALGRIND_TESTING | ||
743 | static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) | ||
744 | { | ||
745 | size_t ret = fwrite(ptr, size, nmemb, stream); | ||
746 | if(!ferror(stream)) | ||
747 | fflush(stream); | ||
748 | return ret; | ||
749 | } | ||
750 | #else | ||
751 | #define local__fwrite fwrite | ||
752 | #endif | ||
753 | |||
754 | FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) | ||
755 | { | ||
756 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
757 | |||
758 | (void)encoder, (void)samples, (void)current_frame; | ||
759 | |||
760 | FLAC__ASSERT(0 != file_encoder); | ||
761 | |||
762 | if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) { | ||
763 | file_encoder->private_->bytes_written += bytes; | ||
764 | file_encoder->private_->samples_written += samples; | ||
765 | /* we keep a high watermark on the number of frames written because | ||
766 | * when the encoder goes back to write metadata, 'current_frame' | ||
767 | * will drop back to 0. | ||
768 | */ | ||
769 | file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1); | ||
770 | if(0 != file_encoder->private_->progress_callback && samples > 0) | ||
771 | file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data); | ||
772 | return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; | ||
773 | } | ||
774 | else | ||
775 | return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | ||
776 | } | ||
diff --git a/apps/codecs/libFLAC/fixed.c b/apps/codecs/libFLAC/fixed.c new file mode 100644 index 0000000000..c1d4a52baa --- /dev/null +++ b/apps/codecs/libFLAC/fixed.c | |||
@@ -0,0 +1,422 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <math.h> | ||
33 | #include "private/bitmath.h" | ||
34 | #include "private/fixed.h" | ||
35 | #include "FLAC/assert.h" | ||
36 | |||
37 | #ifndef M_LN2 | ||
38 | /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ | ||
39 | #define M_LN2 0.69314718055994530942 | ||
40 | #endif | ||
41 | |||
42 | #ifdef min | ||
43 | #undef min | ||
44 | #endif | ||
45 | #define min(x,y) ((x) < (y)? (x) : (y)) | ||
46 | |||
47 | #ifdef local_abs | ||
48 | #undef local_abs | ||
49 | #endif | ||
50 | #define local_abs(x) ((unsigned)((x)<0? -(x) : (x))) | ||
51 | |||
52 | #ifdef FLAC__INTEGER_ONLY_LIBRARY | ||
53 | /* rbps stands for residual bits per sample | ||
54 | * | ||
55 | * (ln(2) * err) | ||
56 | * rbps = log (-----------) | ||
57 | * 2 ( n ) | ||
58 | */ | ||
59 | static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) | ||
60 | { | ||
61 | FLAC__uint32 rbps; | ||
62 | unsigned bits; /* the number of bits required to represent a number */ | ||
63 | int fracbits; /* the number of bits of rbps that comprise the fractional part */ | ||
64 | |||
65 | FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | ||
66 | FLAC__ASSERT(err > 0); | ||
67 | FLAC__ASSERT(n > 0); | ||
68 | |||
69 | FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | ||
70 | if(err <= n) | ||
71 | return 0; | ||
72 | /* | ||
73 | * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | ||
74 | * These allow us later to know we won't lose too much precision in the | ||
75 | * fixed-point division (err<<fracbits)/n. | ||
76 | */ | ||
77 | |||
78 | fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1); | ||
79 | |||
80 | err <<= fracbits; | ||
81 | err /= n; | ||
82 | /* err now holds err/n with fracbits fractional bits */ | ||
83 | |||
84 | /* | ||
85 | * Whittle err down to 16 bits max. 16 significant bits is enough for | ||
86 | * our purposes. | ||
87 | */ | ||
88 | FLAC__ASSERT(err > 0); | ||
89 | bits = FLAC__bitmath_ilog2(err)+1; | ||
90 | if(bits > 16) { | ||
91 | err >>= (bits-16); | ||
92 | fracbits -= (bits-16); | ||
93 | } | ||
94 | rbps = (FLAC__uint32)err; | ||
95 | |||
96 | /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | ||
97 | rbps *= FLAC__FP_LN2; | ||
98 | fracbits += 16; | ||
99 | FLAC__ASSERT(fracbits >= 0); | ||
100 | |||
101 | /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | ||
102 | { | ||
103 | const int f = fracbits & 3; | ||
104 | if(f) { | ||
105 | rbps >>= f; | ||
106 | fracbits -= f; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); | ||
111 | |||
112 | if(rbps == 0) | ||
113 | return 0; | ||
114 | |||
115 | /* | ||
116 | * The return value must have 16 fractional bits. Since the whole part | ||
117 | * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | ||
118 | * must be >= -3, these assertion allows us to be able to shift rbps | ||
119 | * left if necessary to get 16 fracbits without losing any bits of the | ||
120 | * whole part of rbps. | ||
121 | * | ||
122 | * There is a slight chance due to accumulated error that the whole part | ||
123 | * will require 6 bits, so we use 6 in the assertion. Really though as | ||
124 | * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | ||
125 | */ | ||
126 | FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | ||
127 | FLAC__ASSERT(fracbits >= -3); | ||
128 | |||
129 | /* now shift the decimal point into place */ | ||
130 | if(fracbits < 16) | ||
131 | return rbps << (16-fracbits); | ||
132 | else if(fracbits > 16) | ||
133 | return rbps >> (fracbits-16); | ||
134 | else | ||
135 | return rbps; | ||
136 | } | ||
137 | |||
138 | static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) | ||
139 | { | ||
140 | FLAC__uint32 rbps; | ||
141 | unsigned bits; /* the number of bits required to represent a number */ | ||
142 | int fracbits; /* the number of bits of rbps that comprise the fractional part */ | ||
143 | |||
144 | FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | ||
145 | FLAC__ASSERT(err > 0); | ||
146 | FLAC__ASSERT(n > 0); | ||
147 | |||
148 | FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | ||
149 | if(err <= n) | ||
150 | return 0; | ||
151 | /* | ||
152 | * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | ||
153 | * These allow us later to know we won't lose too much precision in the | ||
154 | * fixed-point division (err<<fracbits)/n. | ||
155 | */ | ||
156 | |||
157 | fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1); | ||
158 | |||
159 | err <<= fracbits; | ||
160 | err /= n; | ||
161 | /* err now holds err/n with fracbits fractional bits */ | ||
162 | |||
163 | /* | ||
164 | * Whittle err down to 16 bits max. 16 significant bits is enough for | ||
165 | * our purposes. | ||
166 | */ | ||
167 | FLAC__ASSERT(err > 0); | ||
168 | bits = FLAC__bitmath_ilog2_wide(err)+1; | ||
169 | if(bits > 16) { | ||
170 | err >>= (bits-16); | ||
171 | fracbits -= (bits-16); | ||
172 | } | ||
173 | rbps = (FLAC__uint32)err; | ||
174 | |||
175 | /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | ||
176 | rbps *= FLAC__FP_LN2; | ||
177 | fracbits += 16; | ||
178 | FLAC__ASSERT(fracbits >= 0); | ||
179 | |||
180 | /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | ||
181 | { | ||
182 | const int f = fracbits & 3; | ||
183 | if(f) { | ||
184 | rbps >>= f; | ||
185 | fracbits -= f; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); | ||
190 | |||
191 | if(rbps == 0) | ||
192 | return 0; | ||
193 | |||
194 | /* | ||
195 | * The return value must have 16 fractional bits. Since the whole part | ||
196 | * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | ||
197 | * must be >= -3, these assertion allows us to be able to shift rbps | ||
198 | * left if necessary to get 16 fracbits without losing any bits of the | ||
199 | * whole part of rbps. | ||
200 | * | ||
201 | * There is a slight chance due to accumulated error that the whole part | ||
202 | * will require 6 bits, so we use 6 in the assertion. Really though as | ||
203 | * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | ||
204 | */ | ||
205 | FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | ||
206 | FLAC__ASSERT(fracbits >= -3); | ||
207 | |||
208 | /* now shift the decimal point into place */ | ||
209 | if(fracbits < 16) | ||
210 | return rbps << (16-fracbits); | ||
211 | else if(fracbits > 16) | ||
212 | return rbps >> (fracbits-16); | ||
213 | else | ||
214 | return rbps; | ||
215 | } | ||
216 | #endif | ||
217 | |||
218 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
219 | unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | ||
220 | #else | ||
221 | unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | ||
222 | #endif | ||
223 | { | ||
224 | FLAC__int32 last_error_0 = data[-1]; | ||
225 | FLAC__int32 last_error_1 = data[-1] - data[-2]; | ||
226 | FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | ||
227 | FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | ||
228 | FLAC__int32 error, save; | ||
229 | FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | ||
230 | unsigned i, order; | ||
231 | |||
232 | for(i = 0; i < data_len; i++) { | ||
233 | error = data[i] ; total_error_0 += local_abs(error); save = error; | ||
234 | error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | ||
235 | error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | ||
236 | error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | ||
237 | error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | ||
238 | } | ||
239 | |||
240 | if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) | ||
241 | order = 0; | ||
242 | else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) | ||
243 | order = 1; | ||
244 | else if(total_error_2 < min(total_error_3, total_error_4)) | ||
245 | order = 2; | ||
246 | else if(total_error_3 < total_error_4) | ||
247 | order = 3; | ||
248 | else | ||
249 | order = 4; | ||
250 | |||
251 | /* Estimate the expected number of bits per residual signal sample. */ | ||
252 | /* 'total_error*' is linearly related to the variance of the residual */ | ||
253 | /* signal, so we use it directly to compute E(|x|) */ | ||
254 | FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | ||
255 | FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | ||
256 | FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | ||
257 | FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | ||
258 | FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | ||
259 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
260 | residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
261 | residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
262 | residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
263 | residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
264 | residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
265 | #else | ||
266 | residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; | ||
267 | residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; | ||
268 | residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; | ||
269 | residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; | ||
270 | residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; | ||
271 | #endif | ||
272 | |||
273 | return order; | ||
274 | } | ||
275 | |||
276 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
277 | unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | ||
278 | #else | ||
279 | unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | ||
280 | #endif | ||
281 | { | ||
282 | FLAC__int32 last_error_0 = data[-1]; | ||
283 | FLAC__int32 last_error_1 = data[-1] - data[-2]; | ||
284 | FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | ||
285 | FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | ||
286 | FLAC__int32 error, save; | ||
287 | /* total_error_* are 64-bits to avoid overflow when encoding | ||
288 | * erratic signals when the bits-per-sample and blocksize are | ||
289 | * large. | ||
290 | */ | ||
291 | FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | ||
292 | unsigned i, order; | ||
293 | |||
294 | for(i = 0; i < data_len; i++) { | ||
295 | error = data[i] ; total_error_0 += local_abs(error); save = error; | ||
296 | error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | ||
297 | error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | ||
298 | error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | ||
299 | error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | ||
300 | } | ||
301 | |||
302 | if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4)) | ||
303 | order = 0; | ||
304 | else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4)) | ||
305 | order = 1; | ||
306 | else if(total_error_2 < min(total_error_3, total_error_4)) | ||
307 | order = 2; | ||
308 | else if(total_error_3 < total_error_4) | ||
309 | order = 3; | ||
310 | else | ||
311 | order = 4; | ||
312 | |||
313 | /* Estimate the expected number of bits per residual signal sample. */ | ||
314 | /* 'total_error*' is linearly related to the variance of the residual */ | ||
315 | /* signal, so we use it directly to compute E(|x|) */ | ||
316 | FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | ||
317 | FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | ||
318 | FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | ||
319 | FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | ||
320 | FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | ||
321 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
322 | #if defined _MSC_VER || defined __MINGW32__ | ||
323 | /* with MSVC you have to spoon feed it the casting */ | ||
324 | residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
325 | residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
326 | residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
327 | residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
328 | residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
329 | #else | ||
330 | residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
331 | residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
332 | residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
333 | residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
334 | residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); | ||
335 | #endif | ||
336 | #else | ||
337 | residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; | ||
338 | residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; | ||
339 | residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; | ||
340 | residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; | ||
341 | residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; | ||
342 | #endif | ||
343 | |||
344 | return order; | ||
345 | } | ||
346 | |||
347 | void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]) | ||
348 | { | ||
349 | const int idata_len = (int)data_len; | ||
350 | int i; | ||
351 | |||
352 | switch(order) { | ||
353 | case 0: | ||
354 | for(i = 0; i < idata_len; i++) { | ||
355 | residual[i] = data[i]; | ||
356 | } | ||
357 | break; | ||
358 | case 1: | ||
359 | for(i = 0; i < idata_len; i++) { | ||
360 | residual[i] = data[i] - data[i-1]; | ||
361 | } | ||
362 | break; | ||
363 | case 2: | ||
364 | for(i = 0; i < idata_len; i++) { | ||
365 | /* == data[i] - 2*data[i-1] + data[i-2] */ | ||
366 | residual[i] = data[i] - (data[i-1] << 1) + data[i-2]; | ||
367 | } | ||
368 | break; | ||
369 | case 3: | ||
370 | for(i = 0; i < idata_len; i++) { | ||
371 | /* == data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3] */ | ||
372 | residual[i] = data[i] - (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) - data[i-3]; | ||
373 | } | ||
374 | break; | ||
375 | case 4: | ||
376 | for(i = 0; i < idata_len; i++) { | ||
377 | /* == data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4] */ | ||
378 | residual[i] = data[i] - ((data[i-1]+data[i-3])<<2) + ((data[i-2]<<2) + (data[i-2]<<1)) + data[i-4]; | ||
379 | } | ||
380 | break; | ||
381 | default: | ||
382 | FLAC__ASSERT(0); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]) | ||
387 | { | ||
388 | int i, idata_len = (int)data_len; | ||
389 | |||
390 | switch(order) { | ||
391 | case 0: | ||
392 | for(i = 0; i < idata_len; i++) { | ||
393 | data[i] = residual[i]; | ||
394 | } | ||
395 | break; | ||
396 | case 1: | ||
397 | for(i = 0; i < idata_len; i++) { | ||
398 | data[i] = residual[i] + data[i-1]; | ||
399 | } | ||
400 | break; | ||
401 | case 2: | ||
402 | for(i = 0; i < idata_len; i++) { | ||
403 | /* == residual[i] + 2*data[i-1] - data[i-2] */ | ||
404 | data[i] = residual[i] + (data[i-1]<<1) - data[i-2]; | ||
405 | } | ||
406 | break; | ||
407 | case 3: | ||
408 | for(i = 0; i < idata_len; i++) { | ||
409 | /* residual[i] + 3*data[i-1] - 3*data[i-2]) + data[i-3] */ | ||
410 | data[i] = residual[i] + (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) + data[i-3]; | ||
411 | } | ||
412 | break; | ||
413 | case 4: | ||
414 | for(i = 0; i < idata_len; i++) { | ||
415 | /* == residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4] */ | ||
416 | data[i] = residual[i] + ((data[i-1]+data[i-3])<<2) - ((data[i-2]<<2) + (data[i-2]<<1)) - data[i-4]; | ||
417 | } | ||
418 | break; | ||
419 | default: | ||
420 | FLAC__ASSERT(0); | ||
421 | } | ||
422 | } | ||
diff --git a/apps/codecs/libFLAC/float.c b/apps/codecs/libFLAC/float.c new file mode 100644 index 0000000000..cbb381d431 --- /dev/null +++ b/apps/codecs/libFLAC/float.c | |||
@@ -0,0 +1,304 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include "FLAC/assert.h" | ||
33 | |||
34 | #include "private/float.h" | ||
35 | |||
36 | #ifdef FLAC__INTEGER_ONLY_LIBRARY | ||
37 | |||
38 | /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | ||
39 | #ifdef _MSC_VER | ||
40 | #define FLAC__U64L(x) x | ||
41 | #else | ||
42 | #define FLAC__U64L(x) x##LLU | ||
43 | #endif | ||
44 | |||
45 | const FLAC__fixedpoint FLAC__FP_ZERO = 0; | ||
46 | const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; | ||
47 | const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; | ||
48 | const FLAC__fixedpoint FLAC__FP_LN2 = 45426; | ||
49 | const FLAC__fixedpoint FLAC__FP_E = 178145; | ||
50 | |||
51 | /* Lookup tables for Knuth's logarithm algorithm */ | ||
52 | #define LOG2_LOOKUP_PRECISION 16 | ||
53 | static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = { | ||
54 | { | ||
55 | /* | ||
56 | * 0 fraction bits | ||
57 | */ | ||
58 | /* undefined */ 0x00000000, | ||
59 | /* lg(2/1) = */ 0x00000001, | ||
60 | /* lg(4/3) = */ 0x00000000, | ||
61 | /* lg(8/7) = */ 0x00000000, | ||
62 | /* lg(16/15) = */ 0x00000000, | ||
63 | /* lg(32/31) = */ 0x00000000, | ||
64 | /* lg(64/63) = */ 0x00000000, | ||
65 | /* lg(128/127) = */ 0x00000000, | ||
66 | /* lg(256/255) = */ 0x00000000, | ||
67 | /* lg(512/511) = */ 0x00000000, | ||
68 | /* lg(1024/1023) = */ 0x00000000, | ||
69 | /* lg(2048/2047) = */ 0x00000000, | ||
70 | /* lg(4096/4095) = */ 0x00000000, | ||
71 | /* lg(8192/8191) = */ 0x00000000, | ||
72 | /* lg(16384/16383) = */ 0x00000000, | ||
73 | /* lg(32768/32767) = */ 0x00000000 | ||
74 | }, | ||
75 | { | ||
76 | /* | ||
77 | * 4 fraction bits | ||
78 | */ | ||
79 | /* undefined */ 0x00000000, | ||
80 | /* lg(2/1) = */ 0x00000010, | ||
81 | /* lg(4/3) = */ 0x00000007, | ||
82 | /* lg(8/7) = */ 0x00000003, | ||
83 | /* lg(16/15) = */ 0x00000001, | ||
84 | /* lg(32/31) = */ 0x00000001, | ||
85 | /* lg(64/63) = */ 0x00000000, | ||
86 | /* lg(128/127) = */ 0x00000000, | ||
87 | /* lg(256/255) = */ 0x00000000, | ||
88 | /* lg(512/511) = */ 0x00000000, | ||
89 | /* lg(1024/1023) = */ 0x00000000, | ||
90 | /* lg(2048/2047) = */ 0x00000000, | ||
91 | /* lg(4096/4095) = */ 0x00000000, | ||
92 | /* lg(8192/8191) = */ 0x00000000, | ||
93 | /* lg(16384/16383) = */ 0x00000000, | ||
94 | /* lg(32768/32767) = */ 0x00000000 | ||
95 | }, | ||
96 | { | ||
97 | /* | ||
98 | * 8 fraction bits | ||
99 | */ | ||
100 | /* undefined */ 0x00000000, | ||
101 | /* lg(2/1) = */ 0x00000100, | ||
102 | /* lg(4/3) = */ 0x0000006a, | ||
103 | /* lg(8/7) = */ 0x00000031, | ||
104 | /* lg(16/15) = */ 0x00000018, | ||
105 | /* lg(32/31) = */ 0x0000000c, | ||
106 | /* lg(64/63) = */ 0x00000006, | ||
107 | /* lg(128/127) = */ 0x00000003, | ||
108 | /* lg(256/255) = */ 0x00000001, | ||
109 | /* lg(512/511) = */ 0x00000001, | ||
110 | /* lg(1024/1023) = */ 0x00000000, | ||
111 | /* lg(2048/2047) = */ 0x00000000, | ||
112 | /* lg(4096/4095) = */ 0x00000000, | ||
113 | /* lg(8192/8191) = */ 0x00000000, | ||
114 | /* lg(16384/16383) = */ 0x00000000, | ||
115 | /* lg(32768/32767) = */ 0x00000000 | ||
116 | }, | ||
117 | { | ||
118 | /* | ||
119 | * 12 fraction bits | ||
120 | */ | ||
121 | /* undefined */ 0x00000000, | ||
122 | /* lg(2/1) = */ 0x00001000, | ||
123 | /* lg(4/3) = */ 0x000006a4, | ||
124 | /* lg(8/7) = */ 0x00000315, | ||
125 | /* lg(16/15) = */ 0x0000017d, | ||
126 | /* lg(32/31) = */ 0x000000bc, | ||
127 | /* lg(64/63) = */ 0x0000005d, | ||
128 | /* lg(128/127) = */ 0x0000002e, | ||
129 | /* lg(256/255) = */ 0x00000017, | ||
130 | /* lg(512/511) = */ 0x0000000c, | ||
131 | /* lg(1024/1023) = */ 0x00000006, | ||
132 | /* lg(2048/2047) = */ 0x00000003, | ||
133 | /* lg(4096/4095) = */ 0x00000001, | ||
134 | /* lg(8192/8191) = */ 0x00000001, | ||
135 | /* lg(16384/16383) = */ 0x00000000, | ||
136 | /* lg(32768/32767) = */ 0x00000000 | ||
137 | }, | ||
138 | { | ||
139 | /* | ||
140 | * 16 fraction bits | ||
141 | */ | ||
142 | /* undefined */ 0x00000000, | ||
143 | /* lg(2/1) = */ 0x00010000, | ||
144 | /* lg(4/3) = */ 0x00006a40, | ||
145 | /* lg(8/7) = */ 0x00003151, | ||
146 | /* lg(16/15) = */ 0x000017d6, | ||
147 | /* lg(32/31) = */ 0x00000bba, | ||
148 | /* lg(64/63) = */ 0x000005d1, | ||
149 | /* lg(128/127) = */ 0x000002e6, | ||
150 | /* lg(256/255) = */ 0x00000172, | ||
151 | /* lg(512/511) = */ 0x000000b9, | ||
152 | /* lg(1024/1023) = */ 0x0000005c, | ||
153 | /* lg(2048/2047) = */ 0x0000002e, | ||
154 | /* lg(4096/4095) = */ 0x00000017, | ||
155 | /* lg(8192/8191) = */ 0x0000000c, | ||
156 | /* lg(16384/16383) = */ 0x00000006, | ||
157 | /* lg(32768/32767) = */ 0x00000003 | ||
158 | }, | ||
159 | { | ||
160 | /* | ||
161 | * 20 fraction bits | ||
162 | */ | ||
163 | /* undefined */ 0x00000000, | ||
164 | /* lg(2/1) = */ 0x00100000, | ||
165 | /* lg(4/3) = */ 0x0006a3fe, | ||
166 | /* lg(8/7) = */ 0x00031513, | ||
167 | /* lg(16/15) = */ 0x00017d60, | ||
168 | /* lg(32/31) = */ 0x0000bb9d, | ||
169 | /* lg(64/63) = */ 0x00005d10, | ||
170 | /* lg(128/127) = */ 0x00002e59, | ||
171 | /* lg(256/255) = */ 0x00001721, | ||
172 | /* lg(512/511) = */ 0x00000b8e, | ||
173 | /* lg(1024/1023) = */ 0x000005c6, | ||
174 | /* lg(2048/2047) = */ 0x000002e3, | ||
175 | /* lg(4096/4095) = */ 0x00000171, | ||
176 | /* lg(8192/8191) = */ 0x000000b9, | ||
177 | /* lg(16384/16383) = */ 0x0000005c, | ||
178 | /* lg(32768/32767) = */ 0x0000002e | ||
179 | }, | ||
180 | { | ||
181 | /* | ||
182 | * 24 fraction bits | ||
183 | */ | ||
184 | /* undefined */ 0x00000000, | ||
185 | /* lg(2/1) = */ 0x01000000, | ||
186 | /* lg(4/3) = */ 0x006a3fe6, | ||
187 | /* lg(8/7) = */ 0x00315130, | ||
188 | /* lg(16/15) = */ 0x0017d605, | ||
189 | /* lg(32/31) = */ 0x000bb9ca, | ||
190 | /* lg(64/63) = */ 0x0005d0fc, | ||
191 | /* lg(128/127) = */ 0x0002e58f, | ||
192 | /* lg(256/255) = */ 0x0001720e, | ||
193 | /* lg(512/511) = */ 0x0000b8d8, | ||
194 | /* lg(1024/1023) = */ 0x00005c61, | ||
195 | /* lg(2048/2047) = */ 0x00002e2d, | ||
196 | /* lg(4096/4095) = */ 0x00001716, | ||
197 | /* lg(8192/8191) = */ 0x00000b8b, | ||
198 | /* lg(16384/16383) = */ 0x000005c5, | ||
199 | /* lg(32768/32767) = */ 0x000002e3 | ||
200 | }, | ||
201 | { | ||
202 | /* | ||
203 | * 28 fraction bits | ||
204 | */ | ||
205 | /* undefined */ 0x00000000, | ||
206 | /* lg(2/1) = */ 0x10000000, | ||
207 | /* lg(4/3) = */ 0x06a3fe5c, | ||
208 | /* lg(8/7) = */ 0x03151301, | ||
209 | /* lg(16/15) = */ 0x017d6049, | ||
210 | /* lg(32/31) = */ 0x00bb9ca6, | ||
211 | /* lg(64/63) = */ 0x005d0fba, | ||
212 | /* lg(128/127) = */ 0x002e58f7, | ||
213 | /* lg(256/255) = */ 0x001720da, | ||
214 | /* lg(512/511) = */ 0x000b8d87, | ||
215 | /* lg(1024/1023) = */ 0x0005c60b, | ||
216 | /* lg(2048/2047) = */ 0x0002e2d7, | ||
217 | /* lg(4096/4095) = */ 0x00017160, | ||
218 | /* lg(8192/8191) = */ 0x0000b8ad, | ||
219 | /* lg(16384/16383) = */ 0x00005c56, | ||
220 | /* lg(32768/32767) = */ 0x00002e2b | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | #if 0 | ||
225 | static const FLAC__uint64 log2_lookup_wide[] = { | ||
226 | { | ||
227 | /* | ||
228 | * 32 fraction bits | ||
229 | */ | ||
230 | /* undefined */ 0x00000000, | ||
231 | /* lg(2/1) = */ FLAC__U64L(0x100000000), | ||
232 | /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), | ||
233 | /* lg(8/7) = */ FLAC__U64L(0x31513015), | ||
234 | /* lg(16/15) = */ FLAC__U64L(0x17d60497), | ||
235 | /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), | ||
236 | /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), | ||
237 | /* lg(128/127) = */ FLAC__U64L(0x02e58f74), | ||
238 | /* lg(256/255) = */ FLAC__U64L(0x01720d9c), | ||
239 | /* lg(512/511) = */ FLAC__U64L(0x00b8d875), | ||
240 | /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), | ||
241 | /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), | ||
242 | /* lg(4096/4095) = */ FLAC__U64L(0x00171600), | ||
243 | /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), | ||
244 | /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), | ||
245 | /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) | ||
246 | }, | ||
247 | { | ||
248 | /* | ||
249 | * 48 fraction bits | ||
250 | */ | ||
251 | /* undefined */ 0x00000000, | ||
252 | /* lg(2/1) = */ FLAC__U64L(0x1000000000000), | ||
253 | /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), | ||
254 | /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), | ||
255 | /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), | ||
256 | /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), | ||
257 | /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), | ||
258 | /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), | ||
259 | /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), | ||
260 | /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), | ||
261 | /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), | ||
262 | /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), | ||
263 | /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), | ||
264 | /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), | ||
265 | /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), | ||
266 | /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) | ||
267 | } | ||
268 | }; | ||
269 | #endif | ||
270 | |||
271 | FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision) | ||
272 | { | ||
273 | const FLAC__uint32 ONE = (1u << fracbits); | ||
274 | const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; | ||
275 | |||
276 | FLAC__ASSERT(fracbits < 32); | ||
277 | FLAC__ASSERT((fracbits & 0x3) == 0); | ||
278 | |||
279 | if(x < ONE) | ||
280 | return 0; | ||
281 | |||
282 | if(precision > LOG2_LOOKUP_PRECISION) | ||
283 | precision = LOG2_LOOKUP_PRECISION; | ||
284 | |||
285 | /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ | ||
286 | { | ||
287 | FLAC__uint32 y = 0; | ||
288 | FLAC__uint32 z = x >> 1, k = 1; | ||
289 | while (x > ONE && k < precision) { | ||
290 | if (x - z >= ONE) { | ||
291 | x -= z; | ||
292 | z = x >> k; | ||
293 | y += table[k]; | ||
294 | } | ||
295 | else { | ||
296 | z >>= 1; | ||
297 | k++; | ||
298 | } | ||
299 | } | ||
300 | return y; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | #endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
diff --git a/apps/codecs/libFLAC/format.c b/apps/codecs/libFLAC/format.c new file mode 100644 index 0000000000..25ec7d98b6 --- /dev/null +++ b/apps/codecs/libFLAC/format.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for qsort() */ | ||
34 | #include "FLAC/assert.h" | ||
35 | #include "FLAC/format.h" | ||
36 | #include "private/format.h" | ||
37 | |||
38 | #ifdef HAVE_CONFIG_H | ||
39 | #include <config.h> | ||
40 | #endif | ||
41 | |||
42 | #ifdef min | ||
43 | #undef min | ||
44 | #endif | ||
45 | #define min(a,b) ((a)<(b)?(a):(b)) | ||
46 | |||
47 | /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | ||
48 | #ifdef _MSC_VER | ||
49 | #define FLAC__U64L(x) x | ||
50 | #else | ||
51 | #define FLAC__U64L(x) x##LLU | ||
52 | #endif | ||
53 | |||
54 | /* VERSION should come from configure */ | ||
55 | FLAC_API const char *FLAC__VERSION_STRING = VERSION; | ||
56 | |||
57 | #if defined _MSC_VER || defined __MINW32__ | ||
58 | /* yet one more hack because of MSVC6: */ | ||
59 | FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.1.2 20050205"; | ||
60 | #else | ||
61 | FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20050205"; | ||
62 | #endif | ||
63 | |||
64 | FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; | ||
65 | FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; | ||
66 | FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */; | ||
67 | |||
68 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ | ||
69 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ | ||
70 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ | ||
71 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ | ||
72 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ | ||
73 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ | ||
74 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ | ||
75 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ | ||
76 | FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ | ||
77 | |||
78 | FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ | ||
79 | |||
80 | FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ | ||
81 | FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ | ||
82 | FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ | ||
83 | |||
84 | FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); | ||
85 | |||
86 | FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ | ||
87 | FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ | ||
88 | |||
89 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ | ||
90 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ | ||
91 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ | ||
92 | |||
93 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ | ||
94 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ | ||
95 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ | ||
96 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ | ||
97 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ | ||
98 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ | ||
99 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ | ||
100 | |||
101 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ | ||
102 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ | ||
103 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ | ||
104 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ | ||
105 | FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ | ||
106 | |||
107 | FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ | ||
108 | FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ | ||
109 | FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ | ||
110 | |||
111 | FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe; | ||
112 | FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ | ||
113 | FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 2; /* bits */ | ||
114 | FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ | ||
115 | FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ | ||
116 | FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ | ||
117 | FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ | ||
118 | FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ | ||
119 | FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ | ||
120 | |||
121 | FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ | ||
122 | |||
123 | FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ | ||
124 | FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ | ||
125 | FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ | ||
126 | FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ | ||
127 | |||
128 | FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ | ||
129 | |||
130 | FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { | ||
131 | "PARTITIONED_RICE" | ||
132 | }; | ||
133 | |||
134 | FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ | ||
135 | FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ | ||
136 | |||
137 | FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ | ||
138 | FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ | ||
139 | FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ | ||
140 | |||
141 | FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; | ||
142 | FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; | ||
143 | FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; | ||
144 | FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; | ||
145 | |||
146 | FLAC_API const char * const FLAC__SubframeTypeString[] = { | ||
147 | "CONSTANT", | ||
148 | "VERBATIM", | ||
149 | "FIXED", | ||
150 | "LPC" | ||
151 | }; | ||
152 | |||
153 | FLAC_API const char * const FLAC__ChannelAssignmentString[] = { | ||
154 | "INDEPENDENT", | ||
155 | "LEFT_SIDE", | ||
156 | "RIGHT_SIDE", | ||
157 | "MID_SIDE" | ||
158 | }; | ||
159 | |||
160 | FLAC_API const char * const FLAC__FrameNumberTypeString[] = { | ||
161 | "FRAME_NUMBER_TYPE_FRAME_NUMBER", | ||
162 | "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" | ||
163 | }; | ||
164 | |||
165 | FLAC_API const char * const FLAC__MetadataTypeString[] = { | ||
166 | "STREAMINFO", | ||
167 | "PADDING", | ||
168 | "APPLICATION", | ||
169 | "SEEKTABLE", | ||
170 | "VORBIS_COMMENT", | ||
171 | "CUESHEET" | ||
172 | }; | ||
173 | |||
174 | FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) | ||
175 | { | ||
176 | if( | ||
177 | sample_rate == 0 || | ||
178 | sample_rate > FLAC__MAX_SAMPLE_RATE || | ||
179 | ( | ||
180 | sample_rate >= (1u << 16) && | ||
181 | !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) | ||
182 | ) | ||
183 | ) { | ||
184 | return false; | ||
185 | } | ||
186 | else | ||
187 | return true; | ||
188 | } | ||
189 | |||
190 | FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) | ||
191 | { | ||
192 | unsigned i; | ||
193 | FLAC__uint64 prev_sample_number = 0; | ||
194 | FLAC__bool got_prev = false; | ||
195 | |||
196 | FLAC__ASSERT(0 != seek_table); | ||
197 | |||
198 | for(i = 0; i < seek_table->num_points; i++) { | ||
199 | if(got_prev) { | ||
200 | if( | ||
201 | seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && | ||
202 | seek_table->points[i].sample_number <= prev_sample_number | ||
203 | ) | ||
204 | return false; | ||
205 | } | ||
206 | prev_sample_number = seek_table->points[i].sample_number; | ||
207 | got_prev = true; | ||
208 | } | ||
209 | |||
210 | return true; | ||
211 | } | ||
212 | |||
213 | /* used as the sort predicate for qsort() */ | ||
214 | static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) | ||
215 | { | ||
216 | /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ | ||
217 | if(l->sample_number == r->sample_number) | ||
218 | return 0; | ||
219 | else if(l->sample_number < r->sample_number) | ||
220 | return -1; | ||
221 | else | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) | ||
226 | { | ||
227 | unsigned i, j; | ||
228 | FLAC__bool first; | ||
229 | |||
230 | FLAC__ASSERT(0 != seek_table); | ||
231 | |||
232 | /* sort the seekpoints */ | ||
233 | qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); | ||
234 | |||
235 | /* uniquify the seekpoints */ | ||
236 | first = true; | ||
237 | for(i = j = 0; i < seek_table->num_points; i++) { | ||
238 | if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { | ||
239 | if(!first) { | ||
240 | if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) | ||
241 | continue; | ||
242 | } | ||
243 | } | ||
244 | first = false; | ||
245 | seek_table->points[j++] = seek_table->points[i]; | ||
246 | } | ||
247 | |||
248 | for(i = j; i < seek_table->num_points; i++) { | ||
249 | seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | ||
250 | seek_table->points[i].stream_offset = 0; | ||
251 | seek_table->points[i].frame_samples = 0; | ||
252 | } | ||
253 | |||
254 | return j; | ||
255 | } | ||
256 | |||
257 | static __inline unsigned utf8len_(const FLAC__byte *utf8) | ||
258 | { | ||
259 | FLAC__ASSERT(0 != utf8); | ||
260 | if ((utf8[0] & 0x80) == 0) | ||
261 | return 1; | ||
262 | else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) | ||
263 | return 2; | ||
264 | else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) | ||
265 | return 3; | ||
266 | else | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) | ||
271 | { | ||
272 | char c; | ||
273 | for(c = *name; c; c = *(++name)) | ||
274 | if(c < 0x20 || c == 0x3d || c > 0x7d) | ||
275 | return false; | ||
276 | return true; | ||
277 | } | ||
278 | |||
279 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length) | ||
280 | { | ||
281 | if(length == (unsigned)(-1)) { | ||
282 | while(*value) { | ||
283 | unsigned n = utf8len_(value); | ||
284 | if(n == 0) | ||
285 | return false; | ||
286 | value += n; | ||
287 | } | ||
288 | } | ||
289 | else { | ||
290 | const FLAC__byte *end = value + length; | ||
291 | while(value < end) { | ||
292 | unsigned n = utf8len_(value); | ||
293 | if(n == 0) | ||
294 | return false; | ||
295 | value += n; | ||
296 | } | ||
297 | if(value != end) | ||
298 | return false; | ||
299 | } | ||
300 | return true; | ||
301 | } | ||
302 | |||
303 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length) | ||
304 | { | ||
305 | const FLAC__byte *s, *end; | ||
306 | |||
307 | for(s = entry, end = s + length; s < end && *s != '='; s++) { | ||
308 | if(*s < 0x20 || *s > 0x7D) | ||
309 | return false; | ||
310 | } | ||
311 | if(s == end) | ||
312 | return false; | ||
313 | |||
314 | s++; /* skip '=' */ | ||
315 | |||
316 | while(s < end) { | ||
317 | unsigned n = utf8len_(s); | ||
318 | if(n == 0) | ||
319 | return false; | ||
320 | s += n; | ||
321 | } | ||
322 | if(s != end) | ||
323 | return false; | ||
324 | |||
325 | return true; | ||
326 | } | ||
327 | |||
328 | FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) | ||
329 | { | ||
330 | unsigned i, j; | ||
331 | |||
332 | if(check_cd_da_subset) { | ||
333 | if(cue_sheet->lead_in < 2 * 44100) { | ||
334 | if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; | ||
335 | return false; | ||
336 | } | ||
337 | if(cue_sheet->lead_in % 588 != 0) { | ||
338 | if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; | ||
339 | return false; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | if(cue_sheet->num_tracks == 0) { | ||
344 | if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; | ||
345 | return false; | ||
346 | } | ||
347 | |||
348 | if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { | ||
349 | if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; | ||
350 | return false; | ||
351 | } | ||
352 | |||
353 | for(i = 0; i < cue_sheet->num_tracks; i++) { | ||
354 | if(cue_sheet->tracks[i].number == 0) { | ||
355 | if(violation) *violation = "cue sheet may not have a track number 0"; | ||
356 | return false; | ||
357 | } | ||
358 | |||
359 | if(check_cd_da_subset) { | ||
360 | if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { | ||
361 | if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; | ||
362 | return false; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { | ||
367 | if(violation) *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; | ||
368 | return false; | ||
369 | } | ||
370 | |||
371 | if(i < cue_sheet->num_tracks - 1) { | ||
372 | if(cue_sheet->tracks[i].num_indices == 0) { | ||
373 | if(violation) *violation = "cue sheet track must have at least one index point"; | ||
374 | return false; | ||
375 | } | ||
376 | |||
377 | if(cue_sheet->tracks[i].indices[0].number > 1) { | ||
378 | if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; | ||
379 | return false; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { | ||
384 | if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { | ||
385 | if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | if(j > 0) { | ||
390 | if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { | ||
391 | if(violation) *violation = "cue sheet track index numbers must increase by 1"; | ||
392 | return false; | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | |||
398 | return true; | ||
399 | } | ||
400 | |||
401 | /* | ||
402 | * These routines are private to libFLAC | ||
403 | */ | ||
404 | unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) | ||
405 | { | ||
406 | return | ||
407 | FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( | ||
408 | FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), | ||
409 | blocksize, | ||
410 | predictor_order | ||
411 | ); | ||
412 | } | ||
413 | |||
414 | unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) | ||
415 | { | ||
416 | unsigned max_rice_partition_order = 0; | ||
417 | while(!(blocksize & 1)) { | ||
418 | max_rice_partition_order++; | ||
419 | blocksize >>= 1; | ||
420 | } | ||
421 | return min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); | ||
422 | } | ||
423 | |||
424 | unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) | ||
425 | { | ||
426 | unsigned max_rice_partition_order = limit; | ||
427 | |||
428 | while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) | ||
429 | max_rice_partition_order--; | ||
430 | |||
431 | FLAC__ASSERT( | ||
432 | (max_rice_partition_order == 0 && blocksize >= predictor_order) || | ||
433 | (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) | ||
434 | ); | ||
435 | |||
436 | return max_rice_partition_order; | ||
437 | } | ||
438 | |||
439 | void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | ||
440 | { | ||
441 | FLAC__ASSERT(0 != object); | ||
442 | |||
443 | object->parameters = 0; | ||
444 | object->raw_bits = 0; | ||
445 | object->capacity_by_order = 0; | ||
446 | } | ||
447 | |||
448 | void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | ||
449 | { | ||
450 | FLAC__ASSERT(0 != object); | ||
451 | |||
452 | if(0 != object->parameters) | ||
453 | free(object->parameters); | ||
454 | if(0 != object->raw_bits) | ||
455 | free(object->raw_bits); | ||
456 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); | ||
457 | } | ||
458 | |||
459 | FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order) | ||
460 | { | ||
461 | FLAC__ASSERT(0 != object); | ||
462 | |||
463 | FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); | ||
464 | |||
465 | if(object->capacity_by_order < max_partition_order) { | ||
466 | if(0 == (object->parameters = (unsigned*)realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) | ||
467 | return false; | ||
468 | if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) | ||
469 | return false; | ||
470 | object->capacity_by_order = max_partition_order; | ||
471 | } | ||
472 | |||
473 | return true; | ||
474 | } | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/all.h b/apps/codecs/libFLAC/include/FLAC/all.h new file mode 100644 index 0000000000..0fd49af6e4 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/all.h | |||
@@ -0,0 +1,158 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__ALL_H | ||
33 | #define FLAC__ALL_H | ||
34 | |||
35 | #include "export.h" | ||
36 | |||
37 | #include "assert.h" | ||
38 | #include "callback.h" | ||
39 | #include "file_decoder.h" | ||
40 | #include "file_encoder.h" | ||
41 | #include "format.h" | ||
42 | #include "metadata.h" | ||
43 | #include "ordinals.h" | ||
44 | #include "seekable_stream_decoder.h" | ||
45 | #include "seekable_stream_encoder.h" | ||
46 | #include "stream_decoder.h" | ||
47 | #include "stream_encoder.h" | ||
48 | |||
49 | /** \mainpage | ||
50 | * | ||
51 | * \section intro Introduction | ||
52 | * | ||
53 | * This is the documentation for the FLAC C and C++ APIs. It is | ||
54 | * highly interconnected; this introduction should give you a top | ||
55 | * level idea of the structure and how to find the information you | ||
56 | * need. As a prerequisite you should have at least a basic | ||
57 | * knowledge of the FLAC format, documented | ||
58 | * <A HREF="../format.html">here</A>. | ||
59 | * | ||
60 | * \section c_api FLAC C API | ||
61 | * | ||
62 | * The FLAC C API is the interface to libFLAC, a set of structures | ||
63 | * describing the components of FLAC streams, and functions for | ||
64 | * encoding and decoding streams, as well as manipulating FLAC | ||
65 | * metadata in files. The public include files will be installed | ||
66 | * in your include area as <include>/FLAC/... | ||
67 | * | ||
68 | * By writing a little code and linking against libFLAC, it is | ||
69 | * relatively easy to add FLAC support to another program. The | ||
70 | * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>. | ||
71 | * Complete source code of libFLAC as well as the command-line | ||
72 | * encoder and plugins is available and is a useful source of | ||
73 | * examples. | ||
74 | * | ||
75 | * Aside from encoders and decoders, libFLAC provides a powerful | ||
76 | * metadata interface for manipulating metadata in FLAC files. It | ||
77 | * allows the user to add, delete, and modify FLAC metadata blocks | ||
78 | * and it can automatically take advantage of PADDING blocks to avoid | ||
79 | * rewriting the entire FLAC file when changing the size of the | ||
80 | * metadata. | ||
81 | * | ||
82 | * libFLAC usually only requires the standard C library and C math | ||
83 | * library. In particular, threading is not used so there is no | ||
84 | * dependency on a thread library. However, libFLAC does not use | ||
85 | * global variables and should be thread-safe. | ||
86 | * | ||
87 | * There is also a new libOggFLAC library which wraps around libFLAC | ||
88 | * to provide routines for encoding to and decoding from FLAC streams | ||
89 | * inside an Ogg container. The interfaces are very similar or identical | ||
90 | * to their counterparts in libFLAC. libOggFLAC is also licensed under | ||
91 | * <A HREF="../license.html">Xiph's BSD license</A>. | ||
92 | * | ||
93 | * \section cpp_api FLAC C++ API | ||
94 | * | ||
95 | * The FLAC C++ API is a set of classes that encapsulate the | ||
96 | * structures and functions in libFLAC. They provide slightly more | ||
97 | * functionality with respect to metadata but are otherwise | ||
98 | * equivalent. For the most part, they share the same usage as | ||
99 | * their counterparts in libFLAC, and the FLAC C API documentation | ||
100 | * can be used as a supplement. The public include files | ||
101 | * for the C++ API will be installed in your include area as | ||
102 | * <include>/FLAC++/... | ||
103 | * | ||
104 | * There is also a new libOggFLAC++ library, which provides classes | ||
105 | * for encoding to and decoding from FLAC streams in an Ogg container. | ||
106 | * The classes are very similar to their counterparts in libFLAC++. | ||
107 | * | ||
108 | * Both libFLAC++ libOggFLAC++ are also licensed under | ||
109 | * <A HREF="../license.html">Xiph's BSD license</A>. | ||
110 | * | ||
111 | * \section getting_started Getting Started | ||
112 | * | ||
113 | * A good starting point for learning the API is to browse through | ||
114 | * the <A HREF="modules.html">modules</A>. Modules are logical | ||
115 | * groupings of related functions or classes, which correspond roughly | ||
116 | * to header files or sections of header files. Each module includes a | ||
117 | * detailed description of the general usage of its functions or | ||
118 | * classes. | ||
119 | * | ||
120 | * From there you can go on to look at the documentation of | ||
121 | * individual functions. You can see different views of the individual | ||
122 | * functions through the links in top bar across this page. | ||
123 | * | ||
124 | * \section embedded_developers Embedded Developers | ||
125 | * | ||
126 | * libFLAC has grown larger over time as more functionality has been | ||
127 | * included, but much of it may be unnecessary for a particular embedded | ||
128 | * implementation. Unused parts may be pruned by some simple editing of | ||
129 | * src/libFLAC/Makefile.am. In general, the decoders, encoders, and | ||
130 | * metadata interface are all independent from each other. | ||
131 | * | ||
132 | * It is easiest to just describe the dependencies: | ||
133 | * | ||
134 | * - All modules depend on the \link flac_format Format \endlink module. | ||
135 | * - The decoders and encoders are independent of each other. | ||
136 | * - The metadata interface requires the file decoder. | ||
137 | * - The decoder and encoder layers depend on the layers below them, but | ||
138 | * not above them; e.g. the seekable stream decoder depends on the stream | ||
139 | * decoder but not the file decoder | ||
140 | * | ||
141 | * For example, if your application only requires the stream decoder, no | ||
142 | * encoders, and no metadata interface, you can remove the seekable stream | ||
143 | * decoder, file decoder, all encoders, and the metadata interface, which | ||
144 | * will greatly reduce the size of the library. | ||
145 | */ | ||
146 | |||
147 | /** \defgroup flac FLAC C API | ||
148 | * | ||
149 | * The FLAC C API is the interface to libFLAC, a set of structures | ||
150 | * describing the components of FLAC streams, and functions for | ||
151 | * encoding and decoding streams, as well as manipulating FLAC | ||
152 | * metadata in files. | ||
153 | * | ||
154 | * You should start with the format components as all other modules | ||
155 | * are dependent on it. | ||
156 | */ | ||
157 | |||
158 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/assert.h b/apps/codecs/libFLAC/include/FLAC/assert.h new file mode 100644 index 0000000000..99e3381fd1 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/assert.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__ASSERT_H | ||
33 | #define FLAC__ASSERT_H | ||
34 | |||
35 | /* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ | ||
36 | #ifdef DEBUG | ||
37 | #include <assert.h> | ||
38 | #define FLAC__ASSERT(x) assert(x) | ||
39 | #define FLAC__ASSERT_DECLARATION(x) x | ||
40 | #else | ||
41 | #define FLAC__ASSERT(x) | ||
42 | #define FLAC__ASSERT_DECLARATION(x) | ||
43 | #endif | ||
44 | |||
45 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/callback.h b/apps/codecs/libFLAC/include/FLAC/callback.h new file mode 100644 index 0000000000..c6f94c0cf4 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/callback.h | |||
@@ -0,0 +1,181 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__CALLBACK_H | ||
33 | #define FLAC__CALLBACK_H | ||
34 | |||
35 | #include "ordinals.h" | ||
36 | #include <stdlib.h> /* for size_t */ | ||
37 | |||
38 | /** \file include/FLAC/callback.h | ||
39 | * | ||
40 | * \brief | ||
41 | * This module defines the structures for describing I/O callbacks | ||
42 | * to the other FLAC interfaces. | ||
43 | * | ||
44 | * See the detailed documentation for callbacks in the | ||
45 | * \link flac_callbacks callbacks \endlink module. | ||
46 | */ | ||
47 | |||
48 | /** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures | ||
49 | * \ingroup flac | ||
50 | * | ||
51 | * \brief | ||
52 | * This module defines the structures for describing I/O callbacks | ||
53 | * to the other FLAC interfaces. | ||
54 | * | ||
55 | * The purpose of the I/O callback functions is to create a common way | ||
56 | * for the metadata interfaces to handle I/O. | ||
57 | * | ||
58 | * Originally the metadata interfaces required filenames as the way of | ||
59 | * specifying FLAC files to operate on. This is problematic in some | ||
60 | * environments so there is an additional option to specify a set of | ||
61 | * callbacks for doing I/O on the FLAC file, instead of the filename. | ||
62 | * | ||
63 | * In addition to the callbacks, a FLAC__IOHandle type is defined as an | ||
64 | * opaque structure for a data source. | ||
65 | * | ||
66 | * The callback function prototypes are similar (but not identical) to the | ||
67 | * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use | ||
68 | * stdio streams to implement the callbacks, you can pass fread, fwrite, and | ||
69 | * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or | ||
70 | * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle | ||
71 | * is required. \warning You generally can NOT directly use fseek or ftell | ||
72 | * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems | ||
73 | * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with | ||
74 | * large files. You will have to find an equivalent function (e.g. ftello), | ||
75 | * or write a wrapper. The same is true for feof() since this is usually | ||
76 | * implemented as a macro, not as a function whose address can be taken. | ||
77 | * | ||
78 | * \{ | ||
79 | */ | ||
80 | |||
81 | #ifdef __cplusplus | ||
82 | extern "C" { | ||
83 | #endif | ||
84 | |||
85 | typedef void* FLAC__IOHandle; | ||
86 | |||
87 | /** Signature for the read callback. | ||
88 | * The signature and semantics match POSIX fread() implementations | ||
89 | * and can generally be used interchangeably. | ||
90 | * | ||
91 | * \param ptr The address of the read buffer. | ||
92 | * \param size The size of the records to be read. | ||
93 | * \param nmemb The number of records to be read. | ||
94 | * \param handle The handle to the data source. | ||
95 | * \retval size_t | ||
96 | * The number of records read. | ||
97 | */ | ||
98 | typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | ||
99 | |||
100 | /** Signature for the write callback. | ||
101 | * The signature and semantics match POSIX fwrite() implementations | ||
102 | * and can generally be used interchangeably. | ||
103 | * | ||
104 | * \param ptr The address of the write buffer. | ||
105 | * \param size The size of the records to be written. | ||
106 | * \param nmemb The number of records to be written. | ||
107 | * \param handle The handle to the data source. | ||
108 | * \retval size_t | ||
109 | * The number of records written. | ||
110 | */ | ||
111 | typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | ||
112 | |||
113 | /** Signature for the seek callback. | ||
114 | * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT | ||
115 | * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' | ||
116 | * and 32-bits wide. | ||
117 | * | ||
118 | * \param handle The handle to the data source. | ||
119 | * \param offset The new position, relative to \a whence | ||
120 | * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END | ||
121 | * \retval int | ||
122 | * \c 0 on success, \c -1 on error. | ||
123 | */ | ||
124 | typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); | ||
125 | |||
126 | /** Signature for the tell callback. | ||
127 | * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT | ||
128 | * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' | ||
129 | * and 32-bits wide. | ||
130 | * | ||
131 | * \param handle The handle to the data source. | ||
132 | * \retval FLAC__int64 | ||
133 | * The current position on success, \c -1 on error. | ||
134 | */ | ||
135 | typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); | ||
136 | |||
137 | /** Signature for the EOF callback. | ||
138 | * The signature and semantics mostly match POSIX feof() but WATCHOUT: | ||
139 | * on many systems, feof() is a macro, so in this case a wrapper function | ||
140 | * must be provided instead. | ||
141 | * | ||
142 | * \param handle The handle to the data source. | ||
143 | * \retval int | ||
144 | * \c 0 if not at end of file, nonzero if at end of file. | ||
145 | */ | ||
146 | typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); | ||
147 | |||
148 | /** Signature for the close callback. | ||
149 | * The signature and semantics match POSIX fclose() implementations | ||
150 | * and can generally be used interchangeably. | ||
151 | * | ||
152 | * \param handle The handle to the data source. | ||
153 | * \retval int | ||
154 | * \c 0 on success, \c EOF on error. | ||
155 | */ | ||
156 | typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); | ||
157 | |||
158 | /** A structure for holding a set of callbacks. | ||
159 | * Each FLAC interface that requires a FLAC__IOCallbacks structure will | ||
160 | * describe which of the callbacks are required. The ones that are not | ||
161 | * required may be set to NULL. | ||
162 | * | ||
163 | * If the seek requirement for an interface is optional, you can signify that | ||
164 | * a data sorce is not seekable by setting the \a seek field to \c NULL. | ||
165 | */ | ||
166 | typedef struct { | ||
167 | FLAC__IOCallback_Read read; | ||
168 | FLAC__IOCallback_Write write; | ||
169 | FLAC__IOCallback_Seek seek; | ||
170 | FLAC__IOCallback_Tell tell; | ||
171 | FLAC__IOCallback_Eof eof; | ||
172 | FLAC__IOCallback_Close close; | ||
173 | } FLAC__IOCallbacks; | ||
174 | |||
175 | /* \} */ | ||
176 | |||
177 | #ifdef __cplusplus | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/export.h b/apps/codecs/libFLAC/include/FLAC/export.h new file mode 100644 index 0000000000..db4ec59d2f --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/export.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__EXPORT_H | ||
33 | #define FLAC__EXPORT_H | ||
34 | |||
35 | #if defined(FLAC__NO_DLL) || !defined(_MSC_VER) | ||
36 | #define FLAC_API | ||
37 | |||
38 | #else | ||
39 | |||
40 | #ifdef FLAC_API_EXPORTS | ||
41 | #define FLAC_API _declspec(dllexport) | ||
42 | #else | ||
43 | #define FLAC_API _declspec(dllimport) | ||
44 | |||
45 | #endif | ||
46 | #endif | ||
47 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/file_decoder.h b/apps/codecs/libFLAC/include/FLAC/file_decoder.h new file mode 100644 index 0000000000..c4b1c6cdb7 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/file_decoder.h | |||
@@ -0,0 +1,660 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__FILE_DECODER_H | ||
33 | #define FLAC__FILE_DECODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "seekable_stream_decoder.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /** \file include/FLAC/file_decoder.h | ||
44 | * | ||
45 | * \brief | ||
46 | * This module contains the functions which implement the file | ||
47 | * decoder. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_file_decoder file decoder \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_file_decoder FLAC/file_decoder.h: file decoder interface | ||
54 | * \ingroup flac_decoder | ||
55 | * | ||
56 | * \brief | ||
57 | * This module contains the functions which implement the file | ||
58 | * decoder. | ||
59 | * | ||
60 | * The basic usage of this decoder is as follows: | ||
61 | * - The program creates an instance of a decoder using | ||
62 | * FLAC__file_decoder_new(). | ||
63 | * - The program overrides the default settings and sets callbacks for | ||
64 | * writing, error reporting, and metadata reporting using | ||
65 | * FLAC__file_decoder_set_*() functions. | ||
66 | * - The program initializes the instance to validate the settings and | ||
67 | * prepare for decoding using FLAC__file_decoder_init(). | ||
68 | * - The program calls the FLAC__file_decoder_process_*() functions | ||
69 | * to decode data, which subsequently calls the callbacks. | ||
70 | * - The program finishes the decoding with FLAC__file_decoder_finish(), | ||
71 | * which flushes the input and output and resets the decoder to the | ||
72 | * uninitialized state. | ||
73 | * - The instance may be used again or deleted with | ||
74 | * FLAC__file_decoder_delete(). | ||
75 | * | ||
76 | * The file decoder is a trivial wrapper around the | ||
77 | * \link flac_seekable_stream_decoder seekable stream decoder \endlink | ||
78 | * meant to simplfy the process of decoding from a standard file. The | ||
79 | * file decoder supplies all but the Write/Metadata/Error callbacks. | ||
80 | * The user needs only to provide the path to the file and the file | ||
81 | * decoder handles the rest. | ||
82 | * | ||
83 | * Like the seekable stream decoder, seeking is exposed through the | ||
84 | * FLAC__file_decoder_seek_absolute() method. At any point after the file | ||
85 | * decoder has been initialized, the user can call this function to seek to | ||
86 | * an exact sample within the file. Subsequently, the first time the write | ||
87 | * callback is called it will be passed a (possibly partial) block starting | ||
88 | * at that sample. | ||
89 | * | ||
90 | * The file decoder also inherits MD5 signature checking from the seekable | ||
91 | * stream decoder. If this is turned on before initialization, | ||
92 | * FLAC__file_decoder_finish() will report when the decoded MD5 signature | ||
93 | * does not match the one stored in the STREAMINFO block. MD5 checking is | ||
94 | * automatically turned off if there is no signature in the STREAMINFO | ||
95 | * block or when a seek is attempted. | ||
96 | * | ||
97 | * Make sure to read the detailed descriptions of the | ||
98 | * \link flac_seekable_stream_decoder seekable stream decoder module \endlink | ||
99 | * and \link flac_stream_decoder stream decoder module \endlink | ||
100 | * since the file decoder inherits much of its behavior from them. | ||
101 | * | ||
102 | * \note | ||
103 | * The "set" functions may only be called when the decoder is in the | ||
104 | * state FLAC__FILE_DECODER_UNINITIALIZED, i.e. after | ||
105 | * FLAC__file_decoder_new() or FLAC__file_decoder_finish(), but | ||
106 | * before FLAC__file_decoder_init(). If this is the case they will | ||
107 | * return \c true, otherwise \c false. | ||
108 | * | ||
109 | * \note | ||
110 | * FLAC__file_decoder_finish() resets all settings to the constructor | ||
111 | * defaults, including the callbacks. | ||
112 | * | ||
113 | * \{ | ||
114 | */ | ||
115 | |||
116 | |||
117 | /** State values for a FLAC__FileDecoder | ||
118 | * | ||
119 | * The decoder's state can be obtained by calling FLAC__file_decoder_get_state(). | ||
120 | */ | ||
121 | typedef enum { | ||
122 | |||
123 | FLAC__FILE_DECODER_OK = 0, | ||
124 | /**< The decoder is in the normal OK state. */ | ||
125 | |||
126 | FLAC__FILE_DECODER_END_OF_FILE, | ||
127 | /**< The decoder has reached the end of the file. */ | ||
128 | |||
129 | FLAC__FILE_DECODER_ERROR_OPENING_FILE, | ||
130 | /**< An error occurred opening the input file. */ | ||
131 | |||
132 | FLAC__FILE_DECODER_MEMORY_ALLOCATION_ERROR, | ||
133 | /**< An error occurred allocating memory. */ | ||
134 | |||
135 | FLAC__FILE_DECODER_SEEK_ERROR, | ||
136 | /**< An error occurred while seeking. */ | ||
137 | |||
138 | FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR, | ||
139 | /**< An error occurred in the underlying seekable stream decoder. */ | ||
140 | |||
141 | FLAC__FILE_DECODER_ALREADY_INITIALIZED, | ||
142 | /**< FLAC__file_decoder_init() was called when the decoder was already | ||
143 | * initialized, usually because FLAC__file_decoder_finish() was not | ||
144 | * called. | ||
145 | */ | ||
146 | |||
147 | FLAC__FILE_DECODER_INVALID_CALLBACK, | ||
148 | /**< FLAC__file_decoder_init() was called without all callbacks | ||
149 | * being set. | ||
150 | */ | ||
151 | |||
152 | FLAC__FILE_DECODER_UNINITIALIZED | ||
153 | /**< The decoder is in the uninitialized state. */ | ||
154 | |||
155 | } FLAC__FileDecoderState; | ||
156 | |||
157 | /** Maps a FLAC__FileDecoderState to a C string. | ||
158 | * | ||
159 | * Using a FLAC__FileDecoderState as the index to this array | ||
160 | * will give the string equivalent. The contents should not be modified. | ||
161 | */ | ||
162 | extern FLAC_API const char * const FLAC__FileDecoderStateString[]; | ||
163 | |||
164 | |||
165 | /*********************************************************************** | ||
166 | * | ||
167 | * class FLAC__FileDecoder : public FLAC__StreamDecoder | ||
168 | * | ||
169 | ***********************************************************************/ | ||
170 | |||
171 | struct FLAC__FileDecoderProtected; | ||
172 | struct FLAC__FileDecoderPrivate; | ||
173 | /** The opaque structure definition for the file decoder type. See the | ||
174 | * \link flac_file_decoder file decoder module \endlink for a detailed | ||
175 | * description. | ||
176 | */ | ||
177 | typedef struct { | ||
178 | struct FLAC__FileDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
179 | struct FLAC__FileDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
180 | } FLAC__FileDecoder; | ||
181 | |||
182 | /** Signature for the write callback. | ||
183 | * See FLAC__file_decoder_set_write_callback() | ||
184 | * and FLAC__SeekableStreamDecoderWriteCallback for more info. | ||
185 | * | ||
186 | * \param decoder The decoder instance calling the callback. | ||
187 | * \param frame The description of the decoded frame. | ||
188 | * \param buffer An array of pointers to decoded channels of data. | ||
189 | * \param client_data The callee's client data set through | ||
190 | * FLAC__file_decoder_set_client_data(). | ||
191 | * \retval FLAC__StreamDecoderWriteStatus | ||
192 | * The callee's return status. | ||
193 | */ | ||
194 | typedef FLAC__StreamDecoderWriteStatus (*FLAC__FileDecoderWriteCallback)(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
195 | |||
196 | /** Signature for the metadata callback. | ||
197 | * See FLAC__file_decoder_set_metadata_callback() | ||
198 | * and FLAC__SeekableStreamDecoderMetadataCallback for more info. | ||
199 | * | ||
200 | * \param decoder The decoder instance calling the callback. | ||
201 | * \param metadata The decoded metadata block. | ||
202 | * \param client_data The callee's client data set through | ||
203 | * FLAC__file_decoder_set_client_data(). | ||
204 | */ | ||
205 | typedef void (*FLAC__FileDecoderMetadataCallback)(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
206 | |||
207 | /** Signature for the error callback. | ||
208 | * See FLAC__file_decoder_set_error_callback() | ||
209 | * and FLAC__SeekableStreamDecoderErrorCallback for more info. | ||
210 | * | ||
211 | * \param decoder The decoder instance calling the callback. | ||
212 | * \param status The error encountered by the decoder. | ||
213 | * \param client_data The callee's client data set through | ||
214 | * FLAC__file_decoder_set_client_data(). | ||
215 | */ | ||
216 | typedef void (*FLAC__FileDecoderErrorCallback)(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
217 | |||
218 | |||
219 | /*********************************************************************** | ||
220 | * | ||
221 | * Class constructor/destructor | ||
222 | * | ||
223 | ***********************************************************************/ | ||
224 | |||
225 | /** Create a new file decoder instance. The instance is created with | ||
226 | * default settings; see the individual FLAC__file_decoder_set_*() | ||
227 | * functions for each setting's default. | ||
228 | * | ||
229 | * \retval FLAC__FileDecoder* | ||
230 | * \c NULL if there was an error allocating memory, else the new instance. | ||
231 | */ | ||
232 | FLAC_API FLAC__FileDecoder *FLAC__file_decoder_new(); | ||
233 | |||
234 | /** Free a decoder instance. Deletes the object pointed to by \a decoder. | ||
235 | * | ||
236 | * \param decoder A pointer to an existing decoder. | ||
237 | * \assert | ||
238 | * \code decoder != NULL \endcode | ||
239 | */ | ||
240 | FLAC_API void FLAC__file_decoder_delete(FLAC__FileDecoder *decoder); | ||
241 | |||
242 | |||
243 | /*********************************************************************** | ||
244 | * | ||
245 | * Public class method prototypes | ||
246 | * | ||
247 | ***********************************************************************/ | ||
248 | |||
249 | /** Set the "MD5 signature checking" flag. | ||
250 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
251 | * FLAC__seekable_stream_decoder_set_md5_checking(). | ||
252 | * | ||
253 | * \default \c false | ||
254 | * \param decoder A decoder instance to set. | ||
255 | * \param value See above. | ||
256 | * \assert | ||
257 | * \code decoder != NULL \endcode | ||
258 | * \retval FLAC__bool | ||
259 | * \c false if the decoder is already initialized, else \c true. | ||
260 | */ | ||
261 | FLAC_API FLAC__bool FLAC__file_decoder_set_md5_checking(FLAC__FileDecoder *decoder, FLAC__bool value); | ||
262 | |||
263 | /** Set the input file name to decode. | ||
264 | * | ||
265 | * \default \c "-" | ||
266 | * \param decoder A decoder instance to set. | ||
267 | * \param value The input file name, or "-" for \c stdin. | ||
268 | * \assert | ||
269 | * \code decoder != NULL \endcode | ||
270 | * \code value != NULL \endcode | ||
271 | * \retval FLAC__bool | ||
272 | * \c false if the decoder is already initialized, or there was a memory | ||
273 | * allocation error, else \c true. | ||
274 | */ | ||
275 | FLAC_API FLAC__bool FLAC__file_decoder_set_filename(FLAC__FileDecoder *decoder, const char *value); | ||
276 | |||
277 | /** Set the write callback. | ||
278 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
279 | * FLAC__seekable_stream_decoder_set_write_callback(). | ||
280 | * | ||
281 | * \note | ||
282 | * The callback is mandatory and must be set before initialization. | ||
283 | * | ||
284 | * \default \c NULL | ||
285 | * \param decoder A decoder instance to set. | ||
286 | * \param value See above. | ||
287 | * \assert | ||
288 | * \code decoder != NULL \endcode | ||
289 | * \code value != NULL \endcode | ||
290 | * \retval FLAC__bool | ||
291 | * \c false if the decoder is already initialized, else \c true. | ||
292 | */ | ||
293 | FLAC_API FLAC__bool FLAC__file_decoder_set_write_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderWriteCallback value); | ||
294 | |||
295 | /** Set the metadata callback. | ||
296 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
297 | * FLAC__seekable_stream_decoder_set_metadata_callback(). | ||
298 | * | ||
299 | * \note | ||
300 | * The callback is mandatory and must be set before initialization. | ||
301 | * | ||
302 | * \default \c NULL | ||
303 | * \param decoder A decoder instance to set. | ||
304 | * \param value See above. | ||
305 | * \assert | ||
306 | * \code decoder != NULL \endcode | ||
307 | * \code value != NULL \endcode | ||
308 | * \retval FLAC__bool | ||
309 | * \c false if the decoder is already initialized, else \c true. | ||
310 | */ | ||
311 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderMetadataCallback value); | ||
312 | |||
313 | /** Set the error callback. | ||
314 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
315 | * FLAC__seekable_stream_decoder_set_error_callback(). | ||
316 | * | ||
317 | * \note | ||
318 | * The callback is mandatory and must be set before initialization. | ||
319 | * | ||
320 | * \default \c NULL | ||
321 | * \param decoder A decoder instance to set. | ||
322 | * \param value See above. | ||
323 | * \assert | ||
324 | * \code decoder != NULL \endcode | ||
325 | * \code value != NULL \endcode | ||
326 | * \retval FLAC__bool | ||
327 | * \c false if the decoder is already initialized, else \c true. | ||
328 | */ | ||
329 | FLAC_API FLAC__bool FLAC__file_decoder_set_error_callback(FLAC__FileDecoder *decoder, FLAC__FileDecoderErrorCallback value); | ||
330 | |||
331 | /** Set the client data to be passed back to callbacks. | ||
332 | * This value will be supplied to callbacks in their \a client_data | ||
333 | * argument. | ||
334 | * | ||
335 | * \default \c NULL | ||
336 | * \param decoder A decoder instance to set. | ||
337 | * \param value See above. | ||
338 | * \assert | ||
339 | * \code decoder != NULL \endcode | ||
340 | * \retval FLAC__bool | ||
341 | * \c false if the decoder is already initialized, else \c true. | ||
342 | */ | ||
343 | FLAC_API FLAC__bool FLAC__file_decoder_set_client_data(FLAC__FileDecoder *decoder, void *value); | ||
344 | |||
345 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
346 | * FLAC__seekable_stream_decoder_set_metadata_respond(). | ||
347 | * | ||
348 | * \default By default, only the \c STREAMINFO block is returned via the | ||
349 | * metadata callback. | ||
350 | * \param decoder A decoder instance to set. | ||
351 | * \param type See above. | ||
352 | * \assert | ||
353 | * \code decoder != NULL \endcode | ||
354 | * \a type is valid | ||
355 | * \retval FLAC__bool | ||
356 | * \c false if the decoder is already initialized, else \c true. | ||
357 | */ | ||
358 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond(FLAC__FileDecoder *decoder, FLAC__MetadataType type); | ||
359 | |||
360 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
361 | * FLAC__seekable_stream_decoder_set_metadata_respond_application(). | ||
362 | * | ||
363 | * \default By default, only the \c STREAMINFO block is returned via the | ||
364 | * metadata callback. | ||
365 | * \param decoder A decoder instance to set. | ||
366 | * \param id See above. | ||
367 | * \assert | ||
368 | * \code decoder != NULL \endcode | ||
369 | * \code id != NULL \endcode | ||
370 | * \retval FLAC__bool | ||
371 | * \c false if the decoder is already initialized, else \c true. | ||
372 | */ | ||
373 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4]); | ||
374 | |||
375 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
376 | * FLAC__seekable_stream_decoder_set_metadata_respond_all(). | ||
377 | * | ||
378 | * \default By default, only the \c STREAMINFO block is returned via the | ||
379 | * metadata callback. | ||
380 | * \param decoder A decoder instance to set. | ||
381 | * \assert | ||
382 | * \code decoder != NULL \endcode | ||
383 | * \retval FLAC__bool | ||
384 | * \c false if the decoder is already initialized, else \c true. | ||
385 | */ | ||
386 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_respond_all(FLAC__FileDecoder *decoder); | ||
387 | |||
388 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
389 | * FLAC__seekable_stream_decoder_set_metadata_ignore(). | ||
390 | * | ||
391 | * \default By default, only the \c STREAMINFO block is returned via the | ||
392 | * metadata callback. | ||
393 | * \param decoder A decoder instance to set. | ||
394 | * \param type See above. | ||
395 | * \assert | ||
396 | * \code decoder != NULL \endcode | ||
397 | * \a type is valid | ||
398 | * \retval FLAC__bool | ||
399 | * \c false if the decoder is already initialized, else \c true. | ||
400 | */ | ||
401 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore(FLAC__FileDecoder *decoder, FLAC__MetadataType type); | ||
402 | |||
403 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
404 | * FLAC__seekable_stream_decoder_set_metadata_ignore_application(). | ||
405 | * | ||
406 | * \default By default, only the \c STREAMINFO block is returned via the | ||
407 | * metadata callback. | ||
408 | * \param decoder A decoder instance to set. | ||
409 | * \param id See above. | ||
410 | * \assert | ||
411 | * \code decoder != NULL \endcode | ||
412 | * \code id != NULL \endcode | ||
413 | * \retval FLAC__bool | ||
414 | * \c false if the decoder is already initialized, else \c true. | ||
415 | */ | ||
416 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_application(FLAC__FileDecoder *decoder, const FLAC__byte id[4]); | ||
417 | |||
418 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
419 | * FLAC__seekable_stream_decoder_set_metadata_ignore_all(). | ||
420 | * | ||
421 | * \default By default, only the \c STREAMINFO block is returned via the | ||
422 | * metadata callback. | ||
423 | * \param decoder A decoder instance to set. | ||
424 | * \assert | ||
425 | * \code decoder != NULL \endcode | ||
426 | * \retval FLAC__bool | ||
427 | * \c false if the decoder is already initialized, else \c true. | ||
428 | */ | ||
429 | FLAC_API FLAC__bool FLAC__file_decoder_set_metadata_ignore_all(FLAC__FileDecoder *decoder); | ||
430 | |||
431 | /** Get the current decoder state. | ||
432 | * | ||
433 | * \param decoder A decoder instance to query. | ||
434 | * \assert | ||
435 | * \code decoder != NULL \endcode | ||
436 | * \retval FLAC__FileDecoderState | ||
437 | * The current decoder state. | ||
438 | */ | ||
439 | FLAC_API FLAC__FileDecoderState FLAC__file_decoder_get_state(const FLAC__FileDecoder *decoder); | ||
440 | |||
441 | /** Get the state of the underlying seekable stream decoder. | ||
442 | * Useful when the file decoder state is | ||
443 | * \c FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR. | ||
444 | * | ||
445 | * \param decoder A decoder instance to query. | ||
446 | * \assert | ||
447 | * \code decoder != NULL \endcode | ||
448 | * \retval FLAC__SeekableStreamDecoderState | ||
449 | * The seekable stream decoder state. | ||
450 | */ | ||
451 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__file_decoder_get_seekable_stream_decoder_state(const FLAC__FileDecoder *decoder); | ||
452 | |||
453 | /** Get the state of the underlying stream decoder. | ||
454 | * Useful when the file decoder state is | ||
455 | * \c FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR and the seekable stream | ||
456 | * decoder state is \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR. | ||
457 | * | ||
458 | * \param decoder A decoder instance to query. | ||
459 | * \assert | ||
460 | * \code decoder != NULL \endcode | ||
461 | * \retval FLAC__StreamDecoderState | ||
462 | * The seekable stream decoder state. | ||
463 | */ | ||
464 | FLAC_API FLAC__StreamDecoderState FLAC__file_decoder_get_stream_decoder_state(const FLAC__FileDecoder *decoder); | ||
465 | |||
466 | /** Get the current decoder state as a C string. | ||
467 | * This version automatically resolves | ||
468 | * \c FLAC__FILE_DECODER_SEEKABLE_STREAM_DECODER_ERROR by getting the | ||
469 | * seekable stream decoder's state. | ||
470 | * | ||
471 | * \param decoder A decoder instance to query. | ||
472 | * \assert | ||
473 | * \code decoder != NULL \endcode | ||
474 | * \retval const char * | ||
475 | * The decoder state as a C string. Do not modify the contents. | ||
476 | */ | ||
477 | FLAC_API const char *FLAC__file_decoder_get_resolved_state_string(const FLAC__FileDecoder *decoder); | ||
478 | |||
479 | /** Get the "MD5 signature checking" flag. | ||
480 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
481 | * FLAC__seekable_stream_decoder_get_md5_checking(). | ||
482 | * | ||
483 | * \param decoder A decoder instance to query. | ||
484 | * \assert | ||
485 | * \code decoder != NULL \endcode | ||
486 | * \retval FLAC__bool | ||
487 | * See above. | ||
488 | */ | ||
489 | FLAC_API FLAC__bool FLAC__file_decoder_get_md5_checking(const FLAC__FileDecoder *decoder); | ||
490 | |||
491 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
492 | * FLAC__seekable_stream_decoder_get_channels(). | ||
493 | * | ||
494 | * \param decoder A decoder instance to query. | ||
495 | * \assert | ||
496 | * \code decoder != NULL \endcode | ||
497 | * \retval unsigned | ||
498 | * See above. | ||
499 | */ | ||
500 | FLAC_API unsigned FLAC__file_decoder_get_channels(const FLAC__FileDecoder *decoder); | ||
501 | |||
502 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
503 | * FLAC__seekable_stream_decoder_get_channel_assignment(). | ||
504 | * | ||
505 | * \param decoder A decoder instance to query. | ||
506 | * \assert | ||
507 | * \code decoder != NULL \endcode | ||
508 | * \retval FLAC__ChannelAssignment | ||
509 | * See above. | ||
510 | */ | ||
511 | FLAC_API FLAC__ChannelAssignment FLAC__file_decoder_get_channel_assignment(const FLAC__FileDecoder *decoder); | ||
512 | |||
513 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
514 | * FLAC__seekable_stream_decoder_get_bits_per_sample(). | ||
515 | * | ||
516 | * \param decoder A decoder instance to query. | ||
517 | * \assert | ||
518 | * \code decoder != NULL \endcode | ||
519 | * \retval unsigned | ||
520 | * See above. | ||
521 | */ | ||
522 | FLAC_API unsigned FLAC__file_decoder_get_bits_per_sample(const FLAC__FileDecoder *decoder); | ||
523 | |||
524 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
525 | * FLAC__seekable_stream_decoder_get_sample_rate(). | ||
526 | * | ||
527 | * \param decoder A decoder instance to query. | ||
528 | * \assert | ||
529 | * \code decoder != NULL \endcode | ||
530 | * \retval unsigned | ||
531 | * See above. | ||
532 | */ | ||
533 | FLAC_API unsigned FLAC__file_decoder_get_sample_rate(const FLAC__FileDecoder *decoder); | ||
534 | |||
535 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
536 | * FLAC__seekable_stream_decoder_get_blocksize(). | ||
537 | * | ||
538 | * \param decoder A decoder instance to query. | ||
539 | * \assert | ||
540 | * \code decoder != NULL \endcode | ||
541 | * \retval unsigned | ||
542 | * See above. | ||
543 | */ | ||
544 | FLAC_API unsigned FLAC__file_decoder_get_blocksize(const FLAC__FileDecoder *decoder); | ||
545 | |||
546 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
547 | * FLAC__seekable_stream_decoder_get_decode_position(). | ||
548 | * | ||
549 | * \param decoder A decoder instance to query. | ||
550 | * \param position Address at which to return the desired position. | ||
551 | * \assert | ||
552 | * \code decoder != NULL \endcode | ||
553 | * \code position != NULL \endcode | ||
554 | * \retval FLAC__bool | ||
555 | * \c true if successful, \c false if there was an error from | ||
556 | * the 'tell' callback. | ||
557 | */ | ||
558 | FLAC_API FLAC__bool FLAC__file_decoder_get_decode_position(const FLAC__FileDecoder *decoder, FLAC__uint64 *position); | ||
559 | |||
560 | /** Initialize the decoder instance. | ||
561 | * Should be called after FLAC__file_decoder_new() and | ||
562 | * FLAC__file_decoder_set_*() but before any of the | ||
563 | * FLAC__file_decoder_process_*() functions. Will set and return | ||
564 | * the decoder state, which will be FLAC__FILE_DECODER_OK if | ||
565 | * initialization succeeded. | ||
566 | * | ||
567 | * \param decoder An uninitialized decoder instance. | ||
568 | * \assert | ||
569 | * \code decoder != NULL \endcode | ||
570 | * \retval FLAC__FileDecoderState | ||
571 | * \c FLAC__FILE_DECODER_OK if initialization was successful; see | ||
572 | * FLAC__FileDecoderState for the meanings of other return values. | ||
573 | */ | ||
574 | FLAC_API FLAC__FileDecoderState FLAC__file_decoder_init(FLAC__FileDecoder *decoder); | ||
575 | |||
576 | /** Finish the decoding process. | ||
577 | * Flushes the decoding buffer, releases resources, resets the decoder | ||
578 | * settings to their defaults, and returns the decoder state to | ||
579 | * FLAC__FILE_DECODER_UNINITIALIZED. | ||
580 | * | ||
581 | * In the event of a prematurely-terminated decode, it is not strictly | ||
582 | * necessary to call this immediately before FLAC__file_decoder_delete() | ||
583 | * but it is good practice to match every FLAC__file_decoder_init() with | ||
584 | * a FLAC__file_decoder_finish(). | ||
585 | * | ||
586 | * \param decoder An uninitialized decoder instance. | ||
587 | * \assert | ||
588 | * \code decoder != NULL \endcode | ||
589 | * \retval FLAC__bool | ||
590 | * \c false if MD5 checking is on AND a STREAMINFO block was available | ||
591 | * AND the MD5 signature in the STREAMINFO block was non-zero AND the | ||
592 | * signature does not match the one computed by the decoder; else | ||
593 | * \c true. | ||
594 | */ | ||
595 | FLAC_API FLAC__bool FLAC__file_decoder_finish(FLAC__FileDecoder *decoder); | ||
596 | |||
597 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
598 | * FLAC__seekable_stream_decoder_process_single(). | ||
599 | * | ||
600 | * \param decoder A decoder instance. | ||
601 | * \assert | ||
602 | * \code decoder != NULL \endcode | ||
603 | * \retval FLAC__bool | ||
604 | * See above. | ||
605 | */ | ||
606 | FLAC_API FLAC__bool FLAC__file_decoder_process_single(FLAC__FileDecoder *decoder); | ||
607 | |||
608 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
609 | * FLAC__seekable_stream_decoder_process_until_end_of_metadata(). | ||
610 | * | ||
611 | * \param decoder A decoder instance. | ||
612 | * \assert | ||
613 | * \code decoder != NULL \endcode | ||
614 | * \retval FLAC__bool | ||
615 | * See above. | ||
616 | */ | ||
617 | FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_metadata(FLAC__FileDecoder *decoder); | ||
618 | |||
619 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
620 | * FLAC__seekable_stream_decoder_process_until_end_of_stream(). | ||
621 | * | ||
622 | * \param decoder A decoder instance. | ||
623 | * \assert | ||
624 | * \code decoder != NULL \endcode | ||
625 | * \retval FLAC__bool | ||
626 | * See above. | ||
627 | */ | ||
628 | FLAC_API FLAC__bool FLAC__file_decoder_process_until_end_of_file(FLAC__FileDecoder *decoder); | ||
629 | |||
630 | /** This is inherited from FLAC__SeekableStreamDecoder; see | ||
631 | * FLAC__seekable_stream_decoder_skip_single_frame(). | ||
632 | * | ||
633 | * \param decoder A decoder instance. | ||
634 | * \assert | ||
635 | * \code decoder != NULL \endcode | ||
636 | * \retval FLAC__bool | ||
637 | * See above. | ||
638 | */ | ||
639 | FLAC_API FLAC__bool FLAC__file_decoder_skip_single_frame(FLAC__FileDecoder *decoder); | ||
640 | |||
641 | /** Flush the input and seek to an absolute sample. | ||
642 | * This is inherited from FLAC__SeekableStreamDecoder; see | ||
643 | * FLAC__seekable_stream_decoder_seek_absolute(). | ||
644 | * | ||
645 | * \param decoder A decoder instance. | ||
646 | * \param sample The target sample number to seek to. | ||
647 | * \assert | ||
648 | * \code decoder != NULL \endcode | ||
649 | * \retval FLAC__bool | ||
650 | * \c true if successful, else \c false. | ||
651 | */ | ||
652 | FLAC_API FLAC__bool FLAC__file_decoder_seek_absolute(FLAC__FileDecoder *decoder, FLAC__uint64 sample); | ||
653 | |||
654 | /* \} */ | ||
655 | |||
656 | #ifdef __cplusplus | ||
657 | } | ||
658 | #endif | ||
659 | |||
660 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/file_encoder.h b/apps/codecs/libFLAC/include/FLAC/file_encoder.h new file mode 100644 index 0000000000..fbbfadb303 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/file_encoder.h | |||
@@ -0,0 +1,871 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__FILE_ENCODER_H | ||
33 | #define FLAC__FILE_ENCODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "seekable_stream_encoder.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /** \file include/FLAC/file_encoder.h | ||
44 | * | ||
45 | * \brief | ||
46 | * This module contains the functions which implement the file | ||
47 | * encoder. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_file_encoder file encoder \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_file_encoder FLAC/file_encoder.h: file encoder interface | ||
54 | * \ingroup flac_encoder | ||
55 | * | ||
56 | * \brief | ||
57 | * This module contains the functions which implement the file | ||
58 | * encoder. | ||
59 | * | ||
60 | * The basic usage of this encoder is as follows: | ||
61 | * - The program creates an instance of an encoder using | ||
62 | * FLAC__file_encoder_new(). | ||
63 | * - The program overrides the default settings using | ||
64 | * FLAC__file_encoder_set_*() functions. | ||
65 | * - The program initializes the instance to validate the settings and | ||
66 | * prepare for encoding using FLAC__file_encoder_init(). | ||
67 | * - The program calls FLAC__file_encoder_process() or | ||
68 | * FLAC__file_encoder_process_interleaved() to encode data, which | ||
69 | * subsequently writes data to the output file. | ||
70 | * - The program finishes the encoding with FLAC__file_encoder_finish(), | ||
71 | * which causes the encoder to encode any data still in its input pipe, | ||
72 | * rewind and write the STREAMINFO metadata to file, and finally reset | ||
73 | * the encoder to the uninitialized state. | ||
74 | * - The instance may be used again or deleted with | ||
75 | * FLAC__file_encoder_delete(). | ||
76 | * | ||
77 | * The file encoder is a wrapper around the | ||
78 | * \link flac_seekable_stream_encoder seekable stream encoder \endlink which supplies all | ||
79 | * callbacks internally; the user need specify only the filename. | ||
80 | * | ||
81 | * Make sure to read the detailed description of the | ||
82 | * \link flac_seekable_stream_encoder seekable stream encoder module \endlink since the | ||
83 | * \link flac_stream_encoder stream encoder module \endlink since the | ||
84 | * file encoder inherits much of its behavior from them. | ||
85 | * | ||
86 | * \note | ||
87 | * The "set" functions may only be called when the encoder is in the | ||
88 | * state FLAC__FILE_ENCODER_UNINITIALIZED, i.e. after | ||
89 | * FLAC__file_encoder_new() or FLAC__file_encoder_finish(), but | ||
90 | * before FLAC__file_encoder_init(). If this is the case they will | ||
91 | * return \c true, otherwise \c false. | ||
92 | * | ||
93 | * \note | ||
94 | * FLAC__file_encoder_finish() resets all settings to the constructor | ||
95 | * defaults. | ||
96 | * | ||
97 | * \{ | ||
98 | */ | ||
99 | |||
100 | |||
101 | /** State values for a FLAC__FileEncoder | ||
102 | * | ||
103 | * The encoder's state can be obtained by calling FLAC__file_encoder_get_state(). | ||
104 | */ | ||
105 | typedef enum { | ||
106 | |||
107 | FLAC__FILE_ENCODER_OK = 0, | ||
108 | /**< The encoder is in the normal OK state. */ | ||
109 | |||
110 | FLAC__FILE_ENCODER_NO_FILENAME, | ||
111 | /**< FLAC__file_encoder_init() was called without first calling | ||
112 | * FLAC__file_encoder_set_filename(). | ||
113 | */ | ||
114 | |||
115 | FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR, | ||
116 | /**< An error occurred in the underlying seekable stream encoder; | ||
117 | * check FLAC__file_encoder_get_seekable_stream_encoder_state(). | ||
118 | */ | ||
119 | |||
120 | FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING, | ||
121 | /**< A fatal error occurred while writing to the encoded file. */ | ||
122 | |||
123 | FLAC__FILE_ENCODER_ERROR_OPENING_FILE, | ||
124 | /**< An error occurred opening the output file for writing. */ | ||
125 | |||
126 | FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR, | ||
127 | /**< Memory allocation failed. */ | ||
128 | |||
129 | FLAC__FILE_ENCODER_ALREADY_INITIALIZED, | ||
130 | /**< FLAC__file_encoder_init() was called when the encoder was | ||
131 | * already initialized, usually because | ||
132 | * FLAC__file_encoder_finish() was not called. | ||
133 | */ | ||
134 | |||
135 | FLAC__FILE_ENCODER_UNINITIALIZED | ||
136 | /**< The encoder is in the uninitialized state. */ | ||
137 | |||
138 | } FLAC__FileEncoderState; | ||
139 | |||
140 | /** Maps a FLAC__FileEncoderState to a C string. | ||
141 | * | ||
142 | * Using a FLAC__FileEncoderState as the index to this array | ||
143 | * will give the string equivalent. The contents should not be modified. | ||
144 | */ | ||
145 | extern FLAC_API const char * const FLAC__FileEncoderStateString[]; | ||
146 | |||
147 | |||
148 | /*********************************************************************** | ||
149 | * | ||
150 | * class FLAC__FileEncoder | ||
151 | * | ||
152 | ***********************************************************************/ | ||
153 | |||
154 | struct FLAC__FileEncoderProtected; | ||
155 | struct FLAC__FileEncoderPrivate; | ||
156 | /** The opaque structure definition for the file encoder type. | ||
157 | * See the \link flac_file_encoder file encoder module \endlink | ||
158 | * for a detailed description. | ||
159 | */ | ||
160 | typedef struct { | ||
161 | struct FLAC__FileEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
162 | struct FLAC__FileEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
163 | } FLAC__FileEncoder; | ||
164 | |||
165 | /** Signature for the progress callback. | ||
166 | * See FLAC__file_encoder_set_progress_callback() for more info. | ||
167 | * | ||
168 | * \param encoder The encoder instance calling the callback. | ||
169 | * \param bytes_written Bytes written so far. | ||
170 | * \param samples_written Samples written so far. | ||
171 | * \param frames_written Frames written so far. | ||
172 | * \param total_frames_estimate The estimate of the total number of | ||
173 | * frames to be written. | ||
174 | * \param client_data The callee's client data set through | ||
175 | * FLAC__file_encoder_set_client_data(). | ||
176 | */ | ||
177 | typedef void (*FLAC__FileEncoderProgressCallback)(const FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); | ||
178 | |||
179 | |||
180 | /*********************************************************************** | ||
181 | * | ||
182 | * Class constructor/destructor | ||
183 | * | ||
184 | ***********************************************************************/ | ||
185 | |||
186 | /** Create a new file encoder instance. The instance is created with | ||
187 | * default settings; see the individual FLAC__file_encoder_set_*() | ||
188 | * functions for each setting's default. | ||
189 | * | ||
190 | * \retval FLAC__FileEncoder* | ||
191 | * \c NULL if there was an error allocating memory, else the new instance. | ||
192 | */ | ||
193 | FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new(); | ||
194 | |||
195 | /** Free an encoder instance. Deletes the object pointed to by \a encoder. | ||
196 | * | ||
197 | * \param encoder A pointer to an existing encoder. | ||
198 | * \assert | ||
199 | * \code encoder != NULL \endcode | ||
200 | */ | ||
201 | FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder); | ||
202 | |||
203 | /*********************************************************************** | ||
204 | * | ||
205 | * Public class method prototypes | ||
206 | * | ||
207 | ***********************************************************************/ | ||
208 | |||
209 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
210 | * FLAC__seekable_stream_encoder_set_verify(). | ||
211 | * | ||
212 | * \default \c true | ||
213 | * \param encoder An encoder instance to set. | ||
214 | * \param value See above. | ||
215 | * \assert | ||
216 | * \code encoder != NULL \endcode | ||
217 | * \retval FLAC__bool | ||
218 | * \c false if the encoder is already initialized, else \c true. | ||
219 | */ | ||
220 | FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
221 | |||
222 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
223 | * FLAC__seekable_stream_encoder_set_streamable_subset(). | ||
224 | * | ||
225 | * \default \c true | ||
226 | * \param encoder An encoder instance to set. | ||
227 | * \param value See above. | ||
228 | * \assert | ||
229 | * \code encoder != NULL \endcode | ||
230 | * \retval FLAC__bool | ||
231 | * \c false if the encoder is already initialized, else \c true. | ||
232 | */ | ||
233 | FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
234 | |||
235 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
236 | * FLAC__seekable_stream_encoder_set_do_mid_side_stereo(). | ||
237 | * | ||
238 | * \default \c false | ||
239 | * \param encoder An encoder instance to set. | ||
240 | * \param value See above. | ||
241 | * \assert | ||
242 | * \code encoder != NULL \endcode | ||
243 | * \retval FLAC__bool | ||
244 | * \c false if the encoder is already initialized, else \c true. | ||
245 | */ | ||
246 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
247 | |||
248 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
249 | * FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(). | ||
250 | * | ||
251 | * \default \c false | ||
252 | * \param encoder An encoder instance to set. | ||
253 | * \param value See above. | ||
254 | * \assert | ||
255 | * \code encoder != NULL \endcode | ||
256 | * \retval FLAC__bool | ||
257 | * \c false if the encoder is already initialized, else \c true. | ||
258 | */ | ||
259 | FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
260 | |||
261 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
262 | * FLAC__seekable_stream_encoder_set_channels(). | ||
263 | * | ||
264 | * \default \c 2 | ||
265 | * \param encoder An encoder instance to set. | ||
266 | * \param value See above. | ||
267 | * \assert | ||
268 | * \code encoder != NULL \endcode | ||
269 | * \retval FLAC__bool | ||
270 | * \c false if the encoder is already initialized, else \c true. | ||
271 | */ | ||
272 | FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value); | ||
273 | |||
274 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
275 | * FLAC__seekable_stream_encoder_set_bits_per_sample(). | ||
276 | * | ||
277 | * \warning | ||
278 | * Do not feed the encoder data that is wider than the value you | ||
279 | * set here or you will generate an invalid stream. | ||
280 | * | ||
281 | * \default \c 16 | ||
282 | * \param encoder An encoder instance to set. | ||
283 | * \param value See above. | ||
284 | * \assert | ||
285 | * \code encoder != NULL \endcode | ||
286 | * \retval FLAC__bool | ||
287 | * \c false if the encoder is already initialized, else \c true. | ||
288 | */ | ||
289 | FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value); | ||
290 | |||
291 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
292 | * FLAC__seekable_stream_encoder_set_sample_rate(). | ||
293 | * | ||
294 | * \default \c 44100 | ||
295 | * \param encoder An encoder instance to set. | ||
296 | * \param value See above. | ||
297 | * \assert | ||
298 | * \code encoder != NULL \endcode | ||
299 | * \retval FLAC__bool | ||
300 | * \c false if the encoder is already initialized, else \c true. | ||
301 | */ | ||
302 | FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value); | ||
303 | |||
304 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
305 | * FLAC__seekable_stream_encoder_set_blocksize(). | ||
306 | * | ||
307 | * \default \c 1152 | ||
308 | * \param encoder An encoder instance to set. | ||
309 | * \param value See above. | ||
310 | * \assert | ||
311 | * \code encoder != NULL \endcode | ||
312 | * \retval FLAC__bool | ||
313 | * \c false if the encoder is already initialized, else \c true. | ||
314 | */ | ||
315 | FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value); | ||
316 | |||
317 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
318 | * FLAC__seekable_stream_encoder_set_max_lpc_order(). | ||
319 | * | ||
320 | * \default \c 0 | ||
321 | * \param encoder An encoder instance to set. | ||
322 | * \param value See above. | ||
323 | * \assert | ||
324 | * \code encoder != NULL \endcode | ||
325 | * \retval FLAC__bool | ||
326 | * \c false if the encoder is already initialized, else \c true. | ||
327 | */ | ||
328 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value); | ||
329 | |||
330 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
331 | * FLAC__seekable_stream_encoder_set_qlp_coeff_precision(). | ||
332 | * | ||
333 | * \note | ||
334 | * In the current implementation, qlp_coeff_precision + bits_per_sample must | ||
335 | * be less than 32. | ||
336 | * | ||
337 | * \default \c 0 | ||
338 | * \param encoder An encoder instance to set. | ||
339 | * \param value See above. | ||
340 | * \assert | ||
341 | * \code encoder != NULL \endcode | ||
342 | * \retval FLAC__bool | ||
343 | * \c false if the encoder is already initialized, else \c true. | ||
344 | */ | ||
345 | FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value); | ||
346 | |||
347 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
348 | * FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(). | ||
349 | * | ||
350 | * \default \c false | ||
351 | * \param encoder An encoder instance to set. | ||
352 | * \param value See above. | ||
353 | * \assert | ||
354 | * \code encoder != NULL \endcode | ||
355 | * \retval FLAC__bool | ||
356 | * \c false if the encoder is already initialized, else \c true. | ||
357 | */ | ||
358 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
359 | |||
360 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
361 | * FLAC__seekable_stream_encoder_set_do_escape_coding(). | ||
362 | * | ||
363 | * \default \c false | ||
364 | * \param encoder An encoder instance to set. | ||
365 | * \param value See above. | ||
366 | * \assert | ||
367 | * \code encoder != NULL \endcode | ||
368 | * \retval FLAC__bool | ||
369 | * \c false if the encoder is already initialized, else \c true. | ||
370 | */ | ||
371 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
372 | |||
373 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
374 | * FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(). | ||
375 | * | ||
376 | * \default \c false | ||
377 | * \param encoder An encoder instance to set. | ||
378 | * \param value See above. | ||
379 | * \assert | ||
380 | * \code encoder != NULL \endcode | ||
381 | * \retval FLAC__bool | ||
382 | * \c false if the encoder is already initialized, else \c true. | ||
383 | */ | ||
384 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value); | ||
385 | |||
386 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
387 | * FLAC__seekable_stream_encoder_set_min_residual_partition_order(). | ||
388 | * | ||
389 | * \default \c 0 | ||
390 | * \param encoder An encoder instance to set. | ||
391 | * \param value See above. | ||
392 | * \assert | ||
393 | * \code encoder != NULL \endcode | ||
394 | * \retval FLAC__bool | ||
395 | * \c false if the encoder is already initialized, else \c true. | ||
396 | */ | ||
397 | FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value); | ||
398 | |||
399 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
400 | * FLAC__seekable_stream_encoder_set_max_residual_partition_order(). | ||
401 | * | ||
402 | * \default \c 0 | ||
403 | * \param encoder An encoder instance to set. | ||
404 | * \param value See above. | ||
405 | * \assert | ||
406 | * \code encoder != NULL \endcode | ||
407 | * \retval FLAC__bool | ||
408 | * \c false if the encoder is already initialized, else \c true. | ||
409 | */ | ||
410 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value); | ||
411 | |||
412 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
413 | * FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(). | ||
414 | * | ||
415 | * \default \c 0 | ||
416 | * \param encoder An encoder instance to set. | ||
417 | * \param value See above. | ||
418 | * \assert | ||
419 | * \code encoder != NULL \endcode | ||
420 | * \retval FLAC__bool | ||
421 | * \c false if the encoder is already initialized, else \c true. | ||
422 | */ | ||
423 | FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value); | ||
424 | |||
425 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
426 | * FLAC__seekable_stream_encoder_set_total_samples_estimate(). | ||
427 | * | ||
428 | * \default \c 0 | ||
429 | * \param encoder An encoder instance to set. | ||
430 | * \param value See above. | ||
431 | * \assert | ||
432 | * \code encoder != NULL \endcode | ||
433 | * \retval FLAC__bool | ||
434 | * \c false if the encoder is already initialized, else \c true. | ||
435 | */ | ||
436 | FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value); | ||
437 | |||
438 | /** This is inherited from FLAC__SeekableStreamEncoder; see | ||
439 | * FLAC__seekable_stream_encoder_set_metadata(). | ||
440 | * | ||
441 | * \default \c NULL, 0 | ||
442 | * \param encoder An encoder instance to set. | ||
443 | * \param metadata See above. | ||
444 | * \param num_blocks See above. | ||
445 | * \assert | ||
446 | * \code encoder != NULL \endcode | ||
447 | * \retval FLAC__bool | ||
448 | * \c false if the encoder is already initialized, else \c true. | ||
449 | */ | ||
450 | FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); | ||
451 | |||
452 | /** Set the output file name encode to. | ||
453 | * | ||
454 | * \note | ||
455 | * The filename is mandatory and must be set before initialization. | ||
456 | * | ||
457 | * \note | ||
458 | * Unlike the FLAC__FileDecoder, the filename does not interpret "-" for | ||
459 | * \c stdout; writing to \c stdout is not relevant in the file encoder. | ||
460 | * | ||
461 | * \default \c NULL | ||
462 | * \param encoder A encoder instance to set. | ||
463 | * \param value The output file name. | ||
464 | * \assert | ||
465 | * \code encoder != NULL \endcode | ||
466 | * \code value != NULL \endcode | ||
467 | * \retval FLAC__bool | ||
468 | * \c false if the encoder is already initialized, or there was a memory | ||
469 | * allocation error, else \c true. | ||
470 | */ | ||
471 | FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value); | ||
472 | |||
473 | /** Set the progress callback. | ||
474 | * The supplied function will be called when the encoder has finished | ||
475 | * writing a frame. The \c total_frames_estimate argument to the callback | ||
476 | * will be based on the value from | ||
477 | * FLAC__file_encoder_set_total_samples_estimate(). | ||
478 | * | ||
479 | * \note | ||
480 | * Unlike most other callbacks, the progress callback is \b not mandatory | ||
481 | * and need not be set before initialization. | ||
482 | * | ||
483 | * \default \c NULL | ||
484 | * \param encoder An encoder instance to set. | ||
485 | * \param value See above. | ||
486 | * \assert | ||
487 | * \code encoder != NULL \endcode | ||
488 | * \code value != NULL \endcode | ||
489 | * \retval FLAC__bool | ||
490 | * \c false if the encoder is already initialized, else \c true. | ||
491 | */ | ||
492 | FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value); | ||
493 | |||
494 | /** Set the client data to be passed back to callbacks. | ||
495 | * This value will be supplied to callbacks in their \a client_data | ||
496 | * argument. | ||
497 | * | ||
498 | * \default \c NULL | ||
499 | * \param encoder An encoder instance to set. | ||
500 | * \param value See above. | ||
501 | * \assert | ||
502 | * \code encoder != NULL \endcode | ||
503 | * \retval FLAC__bool | ||
504 | * \c false if the encoder is already initialized, else \c true. | ||
505 | */ | ||
506 | FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value); | ||
507 | |||
508 | /** Get the current encoder state. | ||
509 | * | ||
510 | * \param encoder An encoder instance to query. | ||
511 | * \assert | ||
512 | * \code encoder != NULL \endcode | ||
513 | * \retval FLAC__FileEncoderState | ||
514 | * The current encoder state. | ||
515 | */ | ||
516 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder); | ||
517 | |||
518 | /** Get the state of the underlying seekable stream encoder. | ||
519 | * Useful when the file encoder state is | ||
520 | * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR. | ||
521 | * | ||
522 | * \param encoder An encoder instance to query. | ||
523 | * \assert | ||
524 | * \code encoder != NULL \endcode | ||
525 | * \retval FLAC__SeekableStreamEncoderState | ||
526 | * The seekable stream encoder state. | ||
527 | */ | ||
528 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder); | ||
529 | |||
530 | /** Get the state of the underlying stream encoder. | ||
531 | * Useful when the file encoder state is | ||
532 | * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR and the seekable stream | ||
533 | * encoder state is \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR. | ||
534 | * | ||
535 | * \param encoder An encoder instance to query. | ||
536 | * \assert | ||
537 | * \code encoder != NULL \endcode | ||
538 | * \retval FLAC__StreamEncoderState | ||
539 | * The seekable stream encoder state. | ||
540 | */ | ||
541 | FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder); | ||
542 | |||
543 | /** Get the state of the underlying stream encoder's verify decoder. | ||
544 | * Useful when the file encoder state is | ||
545 | * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR and the seekable stream | ||
546 | * encoder state is \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR and | ||
547 | * the stream encoder state is \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. | ||
548 | * | ||
549 | * \param encoder An encoder instance to query. | ||
550 | * \assert | ||
551 | * \code encoder != NULL \endcode | ||
552 | * \retval FLAC__StreamDecoderState | ||
553 | * The stream encoder state. | ||
554 | */ | ||
555 | FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder); | ||
556 | |||
557 | /** Get the current encoder state as a C string. | ||
558 | * This version automatically resolves | ||
559 | * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR by getting the | ||
560 | * seekable stream encoder's state. | ||
561 | * | ||
562 | * \param encoder A encoder instance to query. | ||
563 | * \assert | ||
564 | * \code encoder != NULL \endcode | ||
565 | * \retval const char * | ||
566 | * The encoder state as a C string. Do not modify the contents. | ||
567 | */ | ||
568 | FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder); | ||
569 | |||
570 | /** Get relevant values about the nature of a verify decoder error. | ||
571 | * Inherited from FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(). | ||
572 | * Useful when the file encoder state is | ||
573 | * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR and the seekable stream | ||
574 | * encoder state is | ||
575 | * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR and the | ||
576 | * stream encoder state is | ||
577 | * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. | ||
578 | * | ||
579 | * \param encoder An encoder instance to query. | ||
580 | * \param absolute_sample The absolute sample number of the mismatch. | ||
581 | * \param frame_number The number of the frame in which the mismatch occurred. | ||
582 | * \param channel The channel in which the mismatch occurred. | ||
583 | * \param sample The number of the sample (relative to the frame) in | ||
584 | * which the mismatch occurred. | ||
585 | * \param expected The expected value for the sample in question. | ||
586 | * \param got The actual value returned by the decoder. | ||
587 | * \assert | ||
588 | * \code encoder != NULL \endcode | ||
589 | */ | ||
590 | FLAC_API void FLAC__file_encoder_get_verify_decoder_error_stats(const FLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); | ||
591 | |||
592 | /** Get the "verify" flag. | ||
593 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
594 | * FLAC__seekable_stream_encoder_get_verify(). | ||
595 | * | ||
596 | * \param encoder An encoder instance to query. | ||
597 | * \assert | ||
598 | * \code encoder != NULL \endcode | ||
599 | * \retval FLAC__bool | ||
600 | * See FLAC__file_encoder_set_verify(). | ||
601 | */ | ||
602 | FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder); | ||
603 | |||
604 | /** Get the "streamable subset" flag. | ||
605 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
606 | * FLAC__seekable_stream_encoder_get_streamable_subset(). | ||
607 | * | ||
608 | * \param encoder An encoder instance to query. | ||
609 | * \assert | ||
610 | * \code encoder != NULL \endcode | ||
611 | * \retval FLAC__bool | ||
612 | * See FLAC__file_encoder_set_streamable_subset(). | ||
613 | */ | ||
614 | FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder); | ||
615 | |||
616 | /** Get the "mid/side stereo coding" flag. | ||
617 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
618 | * FLAC__seekable_stream_encoder_get_do_mid_side_stereo(). | ||
619 | * | ||
620 | * \param encoder An encoder instance to query. | ||
621 | * \assert | ||
622 | * \code encoder != NULL \endcode | ||
623 | * \retval FLAC__bool | ||
624 | * See FLAC__file_encoder_get_do_mid_side_stereo(). | ||
625 | */ | ||
626 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder); | ||
627 | |||
628 | /** Get the "adaptive mid/side switching" flag. | ||
629 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
630 | * FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(). | ||
631 | * | ||
632 | * \param encoder An encoder instance to query. | ||
633 | * \assert | ||
634 | * \code encoder != NULL \endcode | ||
635 | * \retval FLAC__bool | ||
636 | * See FLAC__file_encoder_set_loose_mid_side_stereo(). | ||
637 | */ | ||
638 | FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder); | ||
639 | |||
640 | /** Get the number of input channels being processed. | ||
641 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
642 | * FLAC__seekable_stream_encoder_get_channels(). | ||
643 | * | ||
644 | * \param encoder An encoder instance to query. | ||
645 | * \assert | ||
646 | * \code encoder != NULL \endcode | ||
647 | * \retval unsigned | ||
648 | * See FLAC__file_encoder_set_channels(). | ||
649 | */ | ||
650 | FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder); | ||
651 | |||
652 | /** Get the input sample resolution setting. | ||
653 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
654 | * FLAC__seekable_stream_encoder_get_bits_per_sample(). | ||
655 | * | ||
656 | * \param encoder An encoder instance to query. | ||
657 | * \assert | ||
658 | * \code encoder != NULL \endcode | ||
659 | * \retval unsigned | ||
660 | * See FLAC__file_encoder_set_bits_per_sample(). | ||
661 | */ | ||
662 | FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder); | ||
663 | |||
664 | /** Get the input sample rate setting. | ||
665 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
666 | * FLAC__seekable_stream_encoder_get_sample_rate(). | ||
667 | * | ||
668 | * \param encoder An encoder instance to query. | ||
669 | * \assert | ||
670 | * \code encoder != NULL \endcode | ||
671 | * \retval unsigned | ||
672 | * See FLAC__file_encoder_set_sample_rate(). | ||
673 | */ | ||
674 | FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder); | ||
675 | |||
676 | /** Get the blocksize setting. | ||
677 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
678 | * FLAC__seekable_stream_encoder_get_blocksize(). | ||
679 | * | ||
680 | * \param encoder An encoder instance to query. | ||
681 | * \assert | ||
682 | * \code encoder != NULL \endcode | ||
683 | * \retval unsigned | ||
684 | * See FLAC__file_encoder_set_blocksize(). | ||
685 | */ | ||
686 | FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder); | ||
687 | |||
688 | /** Get the maximum LPC order setting. | ||
689 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
690 | * FLAC__seekable_stream_encoder_get_max_lpc_order(). | ||
691 | * | ||
692 | * \param encoder An encoder instance to query. | ||
693 | * \assert | ||
694 | * \code encoder != NULL \endcode | ||
695 | * \retval unsigned | ||
696 | * See FLAC__file_encoder_set_max_lpc_order(). | ||
697 | */ | ||
698 | FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder); | ||
699 | |||
700 | /** Get the quantized linear predictor coefficient precision setting. | ||
701 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
702 | * FLAC__seekable_stream_encoder_get_qlp_coeff_precision(). | ||
703 | * | ||
704 | * \param encoder An encoder instance to query. | ||
705 | * \assert | ||
706 | * \code encoder != NULL \endcode | ||
707 | * \retval unsigned | ||
708 | * See FLAC__file_encoder_set_qlp_coeff_precision(). | ||
709 | */ | ||
710 | FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder); | ||
711 | |||
712 | /** Get the qlp coefficient precision search flag. | ||
713 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
714 | * FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(). | ||
715 | * | ||
716 | * \param encoder An encoder instance to query. | ||
717 | * \assert | ||
718 | * \code encoder != NULL \endcode | ||
719 | * \retval FLAC__bool | ||
720 | * See FLAC__file_encoder_set_do_qlp_coeff_prec_search(). | ||
721 | */ | ||
722 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder); | ||
723 | |||
724 | /** Get the "escape coding" flag. | ||
725 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
726 | * FLAC__seekable_stream_encoder_get_do_escape_coding(). | ||
727 | * | ||
728 | * \param encoder An encoder instance to query. | ||
729 | * \assert | ||
730 | * \code encoder != NULL \endcode | ||
731 | * \retval FLAC__bool | ||
732 | * See FLAC__file_encoder_set_do_escape_coding(). | ||
733 | */ | ||
734 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder); | ||
735 | |||
736 | /** Get the exhaustive model search flag. | ||
737 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
738 | * FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(). | ||
739 | * | ||
740 | * \param encoder An encoder instance to query. | ||
741 | * \assert | ||
742 | * \code encoder != NULL \endcode | ||
743 | * \retval FLAC__bool | ||
744 | * See FLAC__file_encoder_set_do_exhaustive_model_search(). | ||
745 | */ | ||
746 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder); | ||
747 | |||
748 | /** Get the minimum residual partition order setting. | ||
749 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
750 | * FLAC__seekable_stream_encoder_get_min_residual_partition_order(). | ||
751 | * | ||
752 | * \param encoder An encoder instance to query. | ||
753 | * \assert | ||
754 | * \code encoder != NULL \endcode | ||
755 | * \retval unsigned | ||
756 | * See FLAC__file_encoder_set_min_residual_partition_order(). | ||
757 | */ | ||
758 | FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder); | ||
759 | |||
760 | /** Get maximum residual partition order setting. | ||
761 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
762 | * FLAC__seekable_stream_encoder_get_max_residual_partition_order(). | ||
763 | * | ||
764 | * \param encoder An encoder instance to query. | ||
765 | * \assert | ||
766 | * \code encoder != NULL \endcode | ||
767 | * \retval unsigned | ||
768 | * See FLAC__file_encoder_set_max_residual_partition_order(). | ||
769 | */ | ||
770 | FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder); | ||
771 | |||
772 | /** Get the Rice parameter search distance setting. | ||
773 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
774 | * FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(). | ||
775 | * | ||
776 | * \param encoder An encoder instance to query. | ||
777 | * \assert | ||
778 | * \code encoder != NULL \endcode | ||
779 | * \retval unsigned | ||
780 | * See FLAC__file_encoder_set_rice_parameter_search_dist(). | ||
781 | */ | ||
782 | FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder); | ||
783 | |||
784 | /** Get the previously set estimate of the total samples to be encoded. | ||
785 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
786 | * FLAC__seekable_stream_encoder_get_total_samples_estimate(). | ||
787 | * | ||
788 | * \param encoder An encoder instance to query. | ||
789 | * \assert | ||
790 | * \code encoder != NULL \endcode | ||
791 | * \retval FLAC__uint64 | ||
792 | * See FLAC__file_encoder_set_total_samples_estimate(). | ||
793 | */ | ||
794 | FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder); | ||
795 | |||
796 | /** Initialize the encoder instance. | ||
797 | * Should be called after FLAC__file_encoder_new() and | ||
798 | * FLAC__file_encoder_set_*() but before FLAC__file_encoder_process() | ||
799 | * or FLAC__file_encoder_process_interleaved(). Will set and return | ||
800 | * the encoder state, which will be FLAC__FILE_ENCODER_OK if | ||
801 | * initialization succeeded. | ||
802 | * | ||
803 | * \param encoder An uninitialized encoder instance. | ||
804 | * \assert | ||
805 | * \code encoder != NULL \endcode | ||
806 | * \retval FLAC__FileEncoderState | ||
807 | * \c FLAC__FILE_ENCODER_OK if initialization was successful; see | ||
808 | * FLAC__FileEncoderState for the meanings of other return values. | ||
809 | */ | ||
810 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder); | ||
811 | |||
812 | /** Finish the encoding process. | ||
813 | * Flushes the encoding buffer, releases resources, resets the encoder | ||
814 | * settings to their defaults, and returns the encoder state to | ||
815 | * FLAC__FILE_ENCODER_UNINITIALIZED. | ||
816 | * | ||
817 | * In the event of a prematurely-terminated encode, it is not strictly | ||
818 | * necessary to call this immediately before FLAC__file_encoder_delete() | ||
819 | * but it is good practice to match every FLAC__file_encoder_init() | ||
820 | * with a FLAC__file_encoder_finish(). | ||
821 | * | ||
822 | * \param encoder An uninitialized encoder instance. | ||
823 | * \assert | ||
824 | * \code encoder != NULL \endcode | ||
825 | */ | ||
826 | FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder); | ||
827 | |||
828 | /** Submit data for encoding. | ||
829 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
830 | * FLAC__seekable_stream_encoder_process(). | ||
831 | * | ||
832 | * \param encoder An initialized encoder instance in the OK state. | ||
833 | * \param buffer An array of pointers to each channel's signal. | ||
834 | * \param samples The number of samples in one channel. | ||
835 | * \assert | ||
836 | * \code encoder != NULL \endcode | ||
837 | * \code FLAC__file_encoder_get_state(encoder) == FLAC__FILE_ENCODER_OK \endcode | ||
838 | * \retval FLAC__bool | ||
839 | * \c true if successful, else \c false; in this case, check the | ||
840 | * encoder state with FLAC__file_encoder_get_state() to see what | ||
841 | * went wrong. | ||
842 | */ | ||
843 | FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); | ||
844 | |||
845 | /** Submit data for encoding. | ||
846 | * This is inherited from FLAC__SeekableStreamEncoder; see | ||
847 | * FLAC__seekable_stream_encoder_process_interleaved(). | ||
848 | * | ||
849 | * \param encoder An initialized encoder instance in the OK state. | ||
850 | * \param buffer An array of channel-interleaved data (see above). | ||
851 | * \param samples The number of samples in one channel, the same as for | ||
852 | * FLAC__file_encoder_process(). For example, if | ||
853 | * encoding two channels, \c 1000 \a samples corresponds | ||
854 | * to a \a buffer of 2000 values. | ||
855 | * \assert | ||
856 | * \code encoder != NULL \endcode | ||
857 | * \code FLAC__file_encoder_get_state(encoder) == FLAC__FILE_ENCODER_OK \endcode | ||
858 | * \retval FLAC__bool | ||
859 | * \c true if successful, else \c false; in this case, check the | ||
860 | * encoder state with FLAC__file_encoder_get_state() to see what | ||
861 | * went wrong. | ||
862 | */ | ||
863 | FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); | ||
864 | |||
865 | /* \} */ | ||
866 | |||
867 | #ifdef __cplusplus | ||
868 | } | ||
869 | #endif | ||
870 | |||
871 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/format.h b/apps/codecs/libFLAC/include/FLAC/format.h new file mode 100644 index 0000000000..26080cbf72 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/format.h | |||
@@ -0,0 +1,861 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__FORMAT_H | ||
33 | #define FLAC__FORMAT_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "ordinals.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | /** \file include/FLAC/format.h | ||
43 | * | ||
44 | * \brief | ||
45 | * This module contains structure definitions for the representation | ||
46 | * of FLAC format components in memory. These are the basic | ||
47 | * structures used by the rest of the interfaces. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_format format \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_format FLAC/format.h: format components | ||
54 | * \ingroup flac | ||
55 | * | ||
56 | * \brief | ||
57 | * This module contains structure definitions for the representation | ||
58 | * of FLAC format components in memory. These are the basic | ||
59 | * structures used by the rest of the interfaces. | ||
60 | * | ||
61 | * First, you should be familiar with the | ||
62 | * <A HREF="../format.html">FLAC format</A>. Many of the values here | ||
63 | * follow directly from the specification. As a user of libFLAC, the | ||
64 | * interesting parts really are the structures that describe the frame | ||
65 | * header and metadata blocks. | ||
66 | * | ||
67 | * The format structures here are very primitive, designed to store | ||
68 | * information in an efficient way. Reading information from the | ||
69 | * structures is easy but creating or modifying them directly is | ||
70 | * more complex. For the most part, as a user of a library, editing | ||
71 | * is not necessary; however, for metadata blocks it is, so there are | ||
72 | * convenience functions provided in the \link flac_metadata metadata | ||
73 | * module \endlink to simplify the manipulation of metadata blocks. | ||
74 | * | ||
75 | * \note | ||
76 | * It's not the best convention, but symbols ending in _LEN are in bits | ||
77 | * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of | ||
78 | * global variables because they are usually used when declaring byte | ||
79 | * arrays and some compilers require compile-time knowledge of array | ||
80 | * sizes when declared on the stack. | ||
81 | * | ||
82 | * \{ | ||
83 | */ | ||
84 | |||
85 | |||
86 | /* | ||
87 | Most of the values described in this file are defined by the FLAC | ||
88 | format specification. There is nothing to tune here. | ||
89 | */ | ||
90 | |||
91 | /** The largest legal metadata type code. */ | ||
92 | #define FLAC__MAX_METADATA_TYPE_CODE (126u) | ||
93 | |||
94 | /** The minimum block size, in samples, permitted by the format. */ | ||
95 | #define FLAC__MIN_BLOCK_SIZE (16u) | ||
96 | |||
97 | /** The maximum block size, in samples, permitted by the format. */ | ||
98 | #define FLAC__MAX_BLOCK_SIZE (65535u) | ||
99 | |||
100 | /** The maximum number of channels permitted by the format. */ | ||
101 | #define FLAC__MAX_CHANNELS (8u) | ||
102 | |||
103 | /** The minimum sample resolution permitted by the format. */ | ||
104 | #define FLAC__MIN_BITS_PER_SAMPLE (4u) | ||
105 | |||
106 | /** The maximum sample resolution permitted by the format. */ | ||
107 | #define FLAC__MAX_BITS_PER_SAMPLE (32u) | ||
108 | |||
109 | /** The maximum sample resolution permitted by libFLAC. | ||
110 | * | ||
111 | * \warning | ||
112 | * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, | ||
113 | * the reference encoder/decoder is currently limited to 24 bits because | ||
114 | * of prevalent 32-bit math, so make sure and use this value when | ||
115 | * appropriate. | ||
116 | */ | ||
117 | #define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) | ||
118 | |||
119 | /** The maximum sample rate permitted by the format. The value is | ||
120 | * ((2 ^ 16) - 1) * 10; see <A HREF="../format.html">FLAC format</A> | ||
121 | * as to why. | ||
122 | */ | ||
123 | #define FLAC__MAX_SAMPLE_RATE (655350u) | ||
124 | |||
125 | /** The maximum LPC order permitted by the format. */ | ||
126 | #define FLAC__MAX_LPC_ORDER (32u) | ||
127 | |||
128 | /** The minimum quantized linear predictor coefficient precision | ||
129 | * permitted by the format. | ||
130 | */ | ||
131 | #define FLAC__MIN_QLP_COEFF_PRECISION (5u) | ||
132 | |||
133 | /** The maximum quantized linear predictor coefficient precision | ||
134 | * permitted by the format. | ||
135 | */ | ||
136 | #define FLAC__MAX_QLP_COEFF_PRECISION (15u) | ||
137 | |||
138 | /** The maximum order of the fixed predictors permitted by the format. */ | ||
139 | #define FLAC__MAX_FIXED_ORDER (4u) | ||
140 | |||
141 | /** The maximum Rice partition order permitted by the format. */ | ||
142 | #define FLAC__MAX_RICE_PARTITION_ORDER (15u) | ||
143 | |||
144 | /** The maximum Rice partition order permitted by the FLAC Subset. */ | ||
145 | #define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) | ||
146 | |||
147 | /** The version string of the release, stamped onto the libraries and binaries. | ||
148 | * | ||
149 | * \note | ||
150 | * This does not correspond to the shared library version number, which | ||
151 | * is used to determine binary compatibility. | ||
152 | */ | ||
153 | extern FLAC_API const char *FLAC__VERSION_STRING; | ||
154 | |||
155 | /** The vendor string inserted by the encoder into the VORBIS_COMMENT block. | ||
156 | * This is a nulL-terminated ASCII string; when inserted into the | ||
157 | * VORBIS_COMMENT the trailing null is stripped. | ||
158 | */ | ||
159 | extern FLAC_API const char *FLAC__VENDOR_STRING; | ||
160 | |||
161 | /** The byte string representation of the beginning of a FLAC stream. */ | ||
162 | extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ | ||
163 | |||
164 | /** The 32-bit integer big-endian representation of the beginning of | ||
165 | * a FLAC stream. | ||
166 | */ | ||
167 | extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */ | ||
168 | |||
169 | /** The length of the FLAC signature in bits. */ | ||
170 | extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */ | ||
171 | |||
172 | /** The length of the FLAC signature in bytes. */ | ||
173 | #define FLAC__STREAM_SYNC_LENGTH (4u) | ||
174 | |||
175 | |||
176 | /***************************************************************************** | ||
177 | * | ||
178 | * Subframe structures | ||
179 | * | ||
180 | *****************************************************************************/ | ||
181 | |||
182 | /*****************************************************************************/ | ||
183 | |||
184 | /** An enumeration of the available entropy coding methods. */ | ||
185 | typedef enum { | ||
186 | FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0 | ||
187 | /**< Residual is coded by partitioning into contexts, each with it's own | ||
188 | * Rice parameter. */ | ||
189 | } FLAC__EntropyCodingMethodType; | ||
190 | |||
191 | /** Maps a FLAC__EntropyCodingMethodType to a C string. | ||
192 | * | ||
193 | * Using a FLAC__EntropyCodingMethodType as the index to this array will | ||
194 | * give the string equivalent. The contents should not be modified. | ||
195 | */ | ||
196 | extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; | ||
197 | |||
198 | |||
199 | /** Contents of a Rice partitioned residual | ||
200 | */ | ||
201 | typedef struct { | ||
202 | |||
203 | unsigned *parameters; | ||
204 | /**< The Rice parameters for each context. */ | ||
205 | |||
206 | unsigned *raw_bits; | ||
207 | /**< Widths for escape-coded partitions. */ | ||
208 | |||
209 | unsigned capacity_by_order; | ||
210 | /**< The capacity of the \a parameters and \a raw_bits arrays | ||
211 | * specified as an order, i.e. the number of array elements | ||
212 | * allocated is 2 ^ \a capacity_by_order. | ||
213 | */ | ||
214 | } FLAC__EntropyCodingMethod_PartitionedRiceContents; | ||
215 | |||
216 | /** Header for a Rice partitioned residual. (c.f. <A HREF="../format.html#partitioned_rice">format specification</A>) | ||
217 | */ | ||
218 | typedef struct { | ||
219 | |||
220 | unsigned order; | ||
221 | /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ | ||
222 | |||
223 | const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; | ||
224 | /**< The context's Rice parameters and/or raw bits. */ | ||
225 | |||
226 | } FLAC__EntropyCodingMethod_PartitionedRice; | ||
227 | |||
228 | extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */ | ||
229 | extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */ | ||
230 | extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */ | ||
231 | |||
232 | extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; | ||
233 | /**< == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ | ||
234 | |||
235 | /** Header for the entropy coding method. (c.f. <A HREF="../format.html#residual">format specification</A>) | ||
236 | */ | ||
237 | typedef struct { | ||
238 | FLAC__EntropyCodingMethodType type; | ||
239 | union { | ||
240 | FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; | ||
241 | } data; | ||
242 | } FLAC__EntropyCodingMethod; | ||
243 | |||
244 | extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ | ||
245 | |||
246 | /*****************************************************************************/ | ||
247 | |||
248 | /** An enumeration of the available subframe types. */ | ||
249 | typedef enum { | ||
250 | FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ | ||
251 | FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ | ||
252 | FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ | ||
253 | FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ | ||
254 | } FLAC__SubframeType; | ||
255 | |||
256 | /** Maps a FLAC__SubframeType to a C string. | ||
257 | * | ||
258 | * Using a FLAC__SubframeType as the index to this array will | ||
259 | * give the string equivalent. The contents should not be modified. | ||
260 | */ | ||
261 | extern FLAC_API const char * const FLAC__SubframeTypeString[]; | ||
262 | |||
263 | |||
264 | /** CONSTANT subframe. (c.f. <A HREF="../format.html#subframe_constant">format specification</A>) | ||
265 | */ | ||
266 | typedef struct { | ||
267 | FLAC__int32 value; /**< The constant signal value. */ | ||
268 | } FLAC__Subframe_Constant; | ||
269 | |||
270 | |||
271 | /** VERBATIM subframe. (c.f. <A HREF="../format.html#subframe_verbatim">format specification</A>) | ||
272 | */ | ||
273 | typedef struct { | ||
274 | const FLAC__int32 *data; /**< A pointer to verbatim signal. */ | ||
275 | } FLAC__Subframe_Verbatim; | ||
276 | |||
277 | |||
278 | /** FIXED subframe. (c.f. <A HREF="../format.html#subframe_fixed">format specification</A>) | ||
279 | */ | ||
280 | typedef struct { | ||
281 | FLAC__EntropyCodingMethod entropy_coding_method; | ||
282 | /**< The residual coding method. */ | ||
283 | |||
284 | unsigned order; | ||
285 | /**< The polynomial order. */ | ||
286 | |||
287 | FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; | ||
288 | /**< Warmup samples to prime the predictor, length == order. */ | ||
289 | |||
290 | const FLAC__int32 *residual; | ||
291 | /**< The residual signal, length == (blocksize minus order) samples. */ | ||
292 | } FLAC__Subframe_Fixed; | ||
293 | |||
294 | |||
295 | /** LPC subframe. (c.f. <A HREF="../format.html#subframe_lpc">format specification</A>) | ||
296 | */ | ||
297 | typedef struct { | ||
298 | FLAC__EntropyCodingMethod entropy_coding_method; | ||
299 | /**< The residual coding method. */ | ||
300 | |||
301 | unsigned order; | ||
302 | /**< The FIR order. */ | ||
303 | |||
304 | unsigned qlp_coeff_precision; | ||
305 | /**< Quantized FIR filter coefficient precision in bits. */ | ||
306 | |||
307 | int quantization_level; | ||
308 | /**< The qlp coeff shift needed. */ | ||
309 | |||
310 | FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; | ||
311 | /**< FIR filter coefficients. */ | ||
312 | |||
313 | FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; | ||
314 | /**< Warmup samples to prime the predictor, length == order. */ | ||
315 | |||
316 | const FLAC__int32 *residual; | ||
317 | /**< The residual signal, length == (blocksize minus order) samples. */ | ||
318 | } FLAC__Subframe_LPC; | ||
319 | |||
320 | extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ | ||
321 | extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ | ||
322 | |||
323 | |||
324 | /** FLAC subframe structure. (c.f. <A HREF="../format.html#subframe">format specification</A>) | ||
325 | */ | ||
326 | typedef struct { | ||
327 | FLAC__SubframeType type; | ||
328 | union { | ||
329 | FLAC__Subframe_Constant constant; | ||
330 | FLAC__Subframe_Fixed fixed; | ||
331 | FLAC__Subframe_LPC lpc; | ||
332 | FLAC__Subframe_Verbatim verbatim; | ||
333 | } data; | ||
334 | unsigned wasted_bits; | ||
335 | } FLAC__Subframe; | ||
336 | |||
337 | extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; /**< == 1 (bit) */ | ||
338 | extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ | ||
339 | extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ | ||
340 | |||
341 | extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /* = 0x00 */ | ||
342 | extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /* = 0x02 */ | ||
343 | extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /* = 0x10 */ | ||
344 | extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /* = 0x40 */ | ||
345 | |||
346 | /*****************************************************************************/ | ||
347 | |||
348 | |||
349 | /***************************************************************************** | ||
350 | * | ||
351 | * Frame structures | ||
352 | * | ||
353 | *****************************************************************************/ | ||
354 | |||
355 | /** An enumeration of the available channel assignments. */ | ||
356 | typedef enum { | ||
357 | FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ | ||
358 | FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ | ||
359 | FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ | ||
360 | FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ | ||
361 | } FLAC__ChannelAssignment; | ||
362 | |||
363 | /** Maps a FLAC__ChannelAssignment to a C string. | ||
364 | * | ||
365 | * Using a FLAC__ChannelAssignment as the index to this array will | ||
366 | * give the string equivalent. The contents should not be modified. | ||
367 | */ | ||
368 | extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; | ||
369 | |||
370 | /** An enumeration of the possible frame numbering methods. */ | ||
371 | typedef enum { | ||
372 | FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ | ||
373 | FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ | ||
374 | } FLAC__FrameNumberType; | ||
375 | |||
376 | /** Maps a FLAC__FrameNumberType to a C string. | ||
377 | * | ||
378 | * Using a FLAC__FrameNumberType as the index to this array will | ||
379 | * give the string equivalent. The contents should not be modified. | ||
380 | */ | ||
381 | extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; | ||
382 | |||
383 | |||
384 | /** FLAC frame header structure. (c.f. <A HREF="../format.html#frame_header">format specification</A>) | ||
385 | */ | ||
386 | typedef struct { | ||
387 | unsigned blocksize; | ||
388 | /**< The number of samples per subframe. */ | ||
389 | |||
390 | unsigned sample_rate; | ||
391 | /**< The sample rate in Hz. */ | ||
392 | |||
393 | unsigned channels; | ||
394 | /**< The number of channels (== number of subframes). */ | ||
395 | |||
396 | FLAC__ChannelAssignment channel_assignment; | ||
397 | /**< The channel assignment for the frame. */ | ||
398 | |||
399 | unsigned bits_per_sample; | ||
400 | /**< The sample resolution. */ | ||
401 | |||
402 | FLAC__FrameNumberType number_type; | ||
403 | /**< The numbering scheme used for the frame. */ | ||
404 | |||
405 | union { | ||
406 | FLAC__uint32 frame_number; | ||
407 | FLAC__uint64 sample_number; | ||
408 | } number; | ||
409 | /**< The frame number or sample number of first sample in frame; | ||
410 | * use the \a number_type value to determine which to use. */ | ||
411 | |||
412 | FLAC__uint8 crc; | ||
413 | /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) | ||
414 | * of the raw frame header bytes, meaning everything before the CRC byte | ||
415 | * including the sync code. | ||
416 | */ | ||
417 | } FLAC__FrameHeader; | ||
418 | |||
419 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ | ||
420 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */ | ||
421 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 2 (bits) */ | ||
422 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */ | ||
423 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */ | ||
424 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */ | ||
425 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */ | ||
426 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */ | ||
427 | extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ | ||
428 | |||
429 | |||
430 | /** FLAC frame footer structure. (c.f. <A HREF="../format.html#frame_footer">format specification</A>) | ||
431 | */ | ||
432 | typedef struct { | ||
433 | FLAC__uint16 crc; | ||
434 | /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with | ||
435 | * 0) of the bytes before the crc, back to and including the frame header | ||
436 | * sync code. | ||
437 | */ | ||
438 | } FLAC__FrameFooter; | ||
439 | |||
440 | extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ | ||
441 | |||
442 | |||
443 | /** FLAC frame structure. (c.f. <A HREF="../format.html#frame">format specification</A>) | ||
444 | */ | ||
445 | typedef struct { | ||
446 | FLAC__FrameHeader header; | ||
447 | FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; | ||
448 | FLAC__FrameFooter footer; | ||
449 | } FLAC__Frame; | ||
450 | |||
451 | /*****************************************************************************/ | ||
452 | |||
453 | |||
454 | /***************************************************************************** | ||
455 | * | ||
456 | * Meta-data structures | ||
457 | * | ||
458 | *****************************************************************************/ | ||
459 | |||
460 | /** An enumeration of the available metadata block types. */ | ||
461 | typedef enum { | ||
462 | |||
463 | FLAC__METADATA_TYPE_STREAMINFO = 0, | ||
464 | /**< <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block */ | ||
465 | |||
466 | FLAC__METADATA_TYPE_PADDING = 1, | ||
467 | /**< <A HREF="../format.html#metadata_block_padding">PADDING</A> block */ | ||
468 | |||
469 | FLAC__METADATA_TYPE_APPLICATION = 2, | ||
470 | /**< <A HREF="../format.html#metadata_block_application">APPLICATION</A> block */ | ||
471 | |||
472 | FLAC__METADATA_TYPE_SEEKTABLE = 3, | ||
473 | /**< <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block */ | ||
474 | |||
475 | FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, | ||
476 | /**< <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block */ | ||
477 | |||
478 | FLAC__METADATA_TYPE_CUESHEET = 5, | ||
479 | /**< <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block */ | ||
480 | |||
481 | FLAC__METADATA_TYPE_UNDEFINED = 6 | ||
482 | /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ | ||
483 | |||
484 | } FLAC__MetadataType; | ||
485 | |||
486 | /** Maps a FLAC__MetadataType to a C string. | ||
487 | * | ||
488 | * Using a FLAC__MetadataType as the index to this array will | ||
489 | * give the string equivalent. The contents should not be modified. | ||
490 | */ | ||
491 | extern FLAC_API const char * const FLAC__MetadataTypeString[]; | ||
492 | |||
493 | |||
494 | /** FLAC STREAMINFO structure. (c.f. <A HREF="../format.html#metadata_block_streaminfo">format specification</A>) | ||
495 | */ | ||
496 | typedef struct { | ||
497 | unsigned min_blocksize, max_blocksize; | ||
498 | unsigned min_framesize, max_framesize; | ||
499 | unsigned sample_rate; | ||
500 | unsigned channels; | ||
501 | unsigned bits_per_sample; | ||
502 | FLAC__uint64 total_samples; | ||
503 | FLAC__byte md5sum[16]; | ||
504 | } FLAC__StreamMetadata_StreamInfo; | ||
505 | |||
506 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ | ||
507 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */ | ||
508 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */ | ||
509 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */ | ||
510 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */ | ||
511 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */ | ||
512 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */ | ||
513 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */ | ||
514 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */ | ||
515 | |||
516 | /** The total stream length of the STREAMINFO block in bytes. */ | ||
517 | #define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) | ||
518 | |||
519 | /** FLAC PADDING structure. (c.f. <A HREF="../format.html#metadata_block_padding">format specification</A>) | ||
520 | */ | ||
521 | typedef struct { | ||
522 | int dummy; | ||
523 | /**< Conceptually this is an empty struct since we don't store the | ||
524 | * padding bytes. Empty structs are not allowed by some C compilers, | ||
525 | * hence the dummy. | ||
526 | */ | ||
527 | } FLAC__StreamMetadata_Padding; | ||
528 | |||
529 | |||
530 | /** FLAC APPLICATION structure. (c.f. <A HREF="../format.html#metadata_block_application">format specification</A>) | ||
531 | */ | ||
532 | typedef struct { | ||
533 | FLAC__byte id[4]; | ||
534 | FLAC__byte *data; | ||
535 | } FLAC__StreamMetadata_Application; | ||
536 | |||
537 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ | ||
538 | |||
539 | /** SeekPoint structure used in SEEKTABLE blocks. (c.f. <A HREF="../format.html#seekpoint">format specification</A>) | ||
540 | */ | ||
541 | typedef struct { | ||
542 | FLAC__uint64 sample_number; | ||
543 | /**< The sample number of the target frame. */ | ||
544 | |||
545 | FLAC__uint64 stream_offset; | ||
546 | /**< The offset, in bytes, of the target frame with respect to | ||
547 | * beginning of the first frame. */ | ||
548 | |||
549 | unsigned frame_samples; | ||
550 | /**< The number of samples in the target frame. */ | ||
551 | } FLAC__StreamMetadata_SeekPoint; | ||
552 | |||
553 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ | ||
554 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */ | ||
555 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */ | ||
556 | |||
557 | /** The total stream length of a seek point in bytes. */ | ||
558 | #define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) | ||
559 | |||
560 | /** The value used in the \a sample_number field of | ||
561 | * FLAC__StreamMetadataSeekPoint used to indicate a placeholder | ||
562 | * point (== 0xffffffffffffffff). | ||
563 | */ | ||
564 | extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | ||
565 | |||
566 | |||
567 | /** FLAC SEEKTABLE structure. (c.f. <A HREF="../format.html#metadata_block_seektable">format specification</A>) | ||
568 | * | ||
569 | * \note From the format specification: | ||
570 | * - The seek points must be sorted by ascending sample number. | ||
571 | * - Each seek point's sample number must be the first sample of the | ||
572 | * target frame. | ||
573 | * - Each seek point's sample number must be unique within the table. | ||
574 | * - Existence of a SEEKTABLE block implies a correct setting of | ||
575 | * total_samples in the stream_info block. | ||
576 | * - Behavior is undefined when more than one SEEKTABLE block is | ||
577 | * present in a stream. | ||
578 | */ | ||
579 | typedef struct { | ||
580 | unsigned num_points; | ||
581 | FLAC__StreamMetadata_SeekPoint *points; | ||
582 | } FLAC__StreamMetadata_SeekTable; | ||
583 | |||
584 | |||
585 | /** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) | ||
586 | * | ||
587 | * For convenience, the APIs maintain a trailing NUL character at the end of | ||
588 | * \a entry which is not counted toward \a length, i.e. | ||
589 | * \code strlen(entry) == length \endcode | ||
590 | */ | ||
591 | typedef struct { | ||
592 | FLAC__uint32 length; | ||
593 | FLAC__byte *entry; | ||
594 | } FLAC__StreamMetadata_VorbisComment_Entry; | ||
595 | |||
596 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ | ||
597 | |||
598 | |||
599 | /** FLAC VORBIS_COMMENT structure. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>) | ||
600 | */ | ||
601 | typedef struct { | ||
602 | FLAC__StreamMetadata_VorbisComment_Entry vendor_string; | ||
603 | FLAC__uint32 num_comments; | ||
604 | FLAC__StreamMetadata_VorbisComment_Entry *comments; | ||
605 | } FLAC__StreamMetadata_VorbisComment; | ||
606 | |||
607 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ | ||
608 | |||
609 | |||
610 | /** FLAC CUESHEET track index structure. (See the | ||
611 | * <A HREF="../format.html#cuesheet_track_index">format specification</A> for | ||
612 | * the full description of each field.) | ||
613 | */ | ||
614 | typedef struct { | ||
615 | FLAC__uint64 offset; | ||
616 | /**< Offset in samples, relative to the track offset, of the index | ||
617 | * point. | ||
618 | */ | ||
619 | |||
620 | FLAC__byte number; | ||
621 | /**< The index point number. */ | ||
622 | } FLAC__StreamMetadata_CueSheet_Index; | ||
623 | |||
624 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ | ||
625 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */ | ||
626 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */ | ||
627 | |||
628 | |||
629 | /** FLAC CUESHEET track structure. (See the | ||
630 | * <A HREF="../format.html#cuesheet_track">format specification</A> for | ||
631 | * the full description of each field.) | ||
632 | */ | ||
633 | typedef struct { | ||
634 | FLAC__uint64 offset; | ||
635 | /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ | ||
636 | |||
637 | FLAC__byte number; | ||
638 | /**< The track number. */ | ||
639 | |||
640 | char isrc[13]; | ||
641 | /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing '\0' */ | ||
642 | |||
643 | unsigned type:1; | ||
644 | /**< The track type: 0 for audio, 1 for non-audio. */ | ||
645 | |||
646 | unsigned pre_emphasis:1; | ||
647 | /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ | ||
648 | |||
649 | FLAC__byte num_indices; | ||
650 | /**< The number of track index points. */ | ||
651 | |||
652 | FLAC__StreamMetadata_CueSheet_Index *indices; | ||
653 | /**< NULL if num_indices == 0, else pointer to array of index points. */ | ||
654 | |||
655 | } FLAC__StreamMetadata_CueSheet_Track; | ||
656 | |||
657 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */ | ||
658 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */ | ||
659 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */ | ||
660 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */ | ||
661 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */ | ||
662 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */ | ||
663 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */ | ||
664 | |||
665 | |||
666 | /** FLAC CUESHEET structure. (See the | ||
667 | * <A HREF="../format.html#metadata_block_cuesheet">format specification</A> | ||
668 | * for the full description of each field.) | ||
669 | */ | ||
670 | typedef struct { | ||
671 | char media_catalog_number[129]; | ||
672 | /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In | ||
673 | * general, the media catalog number may be 0 to 128 bytes long; any | ||
674 | * unused characters should be right-padded with NUL characters. | ||
675 | */ | ||
676 | |||
677 | FLAC__uint64 lead_in; | ||
678 | /**< The number of lead-in samples. */ | ||
679 | |||
680 | FLAC__bool is_cd; | ||
681 | /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false */ | ||
682 | |||
683 | unsigned num_tracks; | ||
684 | /**< The number of tracks. */ | ||
685 | |||
686 | FLAC__StreamMetadata_CueSheet_Track *tracks; | ||
687 | /**< NULL if num_tracks == 0, else pointer to array of tracks. */ | ||
688 | |||
689 | } FLAC__StreamMetadata_CueSheet; | ||
690 | |||
691 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */ | ||
692 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */ | ||
693 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */ | ||
694 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */ | ||
695 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */ | ||
696 | |||
697 | |||
698 | /** Structure that is used when a metadata block of unknown type is loaded. | ||
699 | * The contents are opaque. The structure is used only internally to | ||
700 | * correctly handle unknown metadata. | ||
701 | */ | ||
702 | typedef struct { | ||
703 | FLAC__byte *data; | ||
704 | } FLAC__StreamMetadata_Unknown; | ||
705 | |||
706 | |||
707 | /** FLAC metadata block structure. (c.f. <A HREF="../format.html#metadata_block">format specification</A>) | ||
708 | */ | ||
709 | typedef struct { | ||
710 | FLAC__MetadataType type; | ||
711 | /**< The type of the metadata block; used determine which member of the | ||
712 | * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED | ||
713 | * then \a data.unknown must be used. */ | ||
714 | |||
715 | FLAC__bool is_last; | ||
716 | /**< \c true if this metadata block is the last, else \a false */ | ||
717 | |||
718 | unsigned length; | ||
719 | /**< Length, in bytes, of the block data as it appears in the stream. */ | ||
720 | |||
721 | union { | ||
722 | FLAC__StreamMetadata_StreamInfo stream_info; | ||
723 | FLAC__StreamMetadata_Padding padding; | ||
724 | FLAC__StreamMetadata_Application application; | ||
725 | FLAC__StreamMetadata_SeekTable seek_table; | ||
726 | FLAC__StreamMetadata_VorbisComment vorbis_comment; | ||
727 | FLAC__StreamMetadata_CueSheet cue_sheet; | ||
728 | FLAC__StreamMetadata_Unknown unknown; | ||
729 | } data; | ||
730 | /**< Polymorphic block data; use the \a type value to determine which | ||
731 | * to use. */ | ||
732 | } FLAC__StreamMetadata; | ||
733 | |||
734 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ | ||
735 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */ | ||
736 | extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */ | ||
737 | |||
738 | /** The total stream length of a metadata block header in bytes. */ | ||
739 | #define FLAC__STREAM_METADATA_HEADER_LENGTH (4u) | ||
740 | |||
741 | /*****************************************************************************/ | ||
742 | |||
743 | |||
744 | /***************************************************************************** | ||
745 | * | ||
746 | * Utility functions | ||
747 | * | ||
748 | *****************************************************************************/ | ||
749 | |||
750 | /** Tests that a sample rate is valid for FLAC. Since the rules for valid | ||
751 | * sample rates are slightly complex, they are encapsulated in this function. | ||
752 | * | ||
753 | * \param sample_rate The sample rate to test for compliance. | ||
754 | * \retval FLAC__bool | ||
755 | * \c true if the given sample rate conforms to the specification, else | ||
756 | * \c false. | ||
757 | */ | ||
758 | FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); | ||
759 | |||
760 | /** Check a Vorbis comment entry name to see if it conforms to the Vorbis | ||
761 | * comment specification. | ||
762 | * | ||
763 | * Vorbis comment names must be composed only of characters from | ||
764 | * [0x20-0x3C,0x3E-0x7D]. | ||
765 | * | ||
766 | * \param name A NUL-terminated string to be checked. | ||
767 | * \assert | ||
768 | * \code name != NULL \endcode | ||
769 | * \retval FLAC__bool | ||
770 | * \c false if entry name is illegal, else \c true. | ||
771 | */ | ||
772 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); | ||
773 | |||
774 | /** Check a Vorbis comment entry value to see if it conforms to the Vorbis | ||
775 | * comment specification. | ||
776 | * | ||
777 | * Vorbis comment values must be valid UTF-8 sequences. | ||
778 | * | ||
779 | * \param value A string to be checked. | ||
780 | * \param length A the length of \a value in bytes. May be | ||
781 | * \c (unsigned)(-1) to indicate that \a value is a plain | ||
782 | * UTF-8 NUL-terminated string. | ||
783 | * \assert | ||
784 | * \code value != NULL \endcode | ||
785 | * \retval FLAC__bool | ||
786 | * \c false if entry name is illegal, else \c true. | ||
787 | */ | ||
788 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length); | ||
789 | |||
790 | /** Check a Vorbis comment entry to see if it conforms to the Vorbis | ||
791 | * comment specification. | ||
792 | * | ||
793 | * Vorbis comment entries must be of the form 'name=value', and 'name' and | ||
794 | * 'value' must be legal according to | ||
795 | * FLAC__format_vorbiscomment_entry_name_is_legal() and | ||
796 | * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. | ||
797 | * | ||
798 | * \param value A string to be checked. | ||
799 | * \assert | ||
800 | * \code value != NULL \endcode | ||
801 | * \retval FLAC__bool | ||
802 | * \c false if entry name is illegal, else \c true. | ||
803 | */ | ||
804 | FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length); | ||
805 | |||
806 | /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | ||
807 | /** Check a seek table to see if it conforms to the FLAC specification. | ||
808 | * See the format specification for limits on the contents of the | ||
809 | * seek table. | ||
810 | * | ||
811 | * \param seek_table A pointer to a seek table to be checked. | ||
812 | * \assert | ||
813 | * \code seek_table != NULL \endcode | ||
814 | * \retval FLAC__bool | ||
815 | * \c false if seek table is illegal, else \c true. | ||
816 | */ | ||
817 | FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); | ||
818 | |||
819 | /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | ||
820 | /** Sort a seek table's seek points according to the format specification. | ||
821 | * This includes a "unique-ification" step to remove duplicates, i.e. | ||
822 | * seek points with identical \a sample_number values. Duplicate seek | ||
823 | * points are converted into placeholder points and sorted to the end of | ||
824 | * the table. | ||
825 | * | ||
826 | * \param seek_table A pointer to a seek table to be sorted. | ||
827 | * \assert | ||
828 | * \code seek_table != NULL \endcode | ||
829 | * \retval unsigned | ||
830 | * The number of duplicate seek points converted into placeholders. | ||
831 | */ | ||
832 | FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); | ||
833 | |||
834 | /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | ||
835 | /** Check a cue sheet to see if it conforms to the FLAC specification. | ||
836 | * See the format specification for limits on the contents of the | ||
837 | * cue sheet. | ||
838 | * | ||
839 | * \param cue_sheet A pointer to an existing cue sheet to be checked. | ||
840 | * \param check_cd_da_subset If \c true, check CUESHEET against more | ||
841 | * stringent requirements for a CD-DA (audio) disc. | ||
842 | * \param violation Address of a pointer to a string. If there is a | ||
843 | * violation, a pointer to a string explanation of the | ||
844 | * violation will be returned here. \a violation may be | ||
845 | * \c NULL if you don't need the returned string. Do not | ||
846 | * free the returned string; it will always point to static | ||
847 | * data. | ||
848 | * \assert | ||
849 | * \code cue_sheet != NULL \endcode | ||
850 | * \retval FLAC__bool | ||
851 | * \c false if cue sheet is illegal, else \c true. | ||
852 | */ | ||
853 | FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); | ||
854 | |||
855 | /* \} */ | ||
856 | |||
857 | #ifdef __cplusplus | ||
858 | } | ||
859 | #endif | ||
860 | |||
861 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/metadata.h b/apps/codecs/libFLAC/include/FLAC/metadata.h new file mode 100644 index 0000000000..ff40e6d5ed --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/metadata.h | |||
@@ -0,0 +1,1858 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__METADATA_H | ||
33 | #define FLAC__METADATA_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "callback.h" | ||
37 | #include "format.h" | ||
38 | |||
39 | /****************************************************************************** | ||
40 | (For an example of how all these routines are used, see the source | ||
41 | code for the unit tests in src/test_libFLAC/metadata_*.c, or metaflac | ||
42 | in src/metaflac/) | ||
43 | ******************************************************************************/ | ||
44 | |||
45 | /** \file include/FLAC/metadata.h | ||
46 | * | ||
47 | * \brief | ||
48 | * This module provides functions for creating and manipulating FLAC | ||
49 | * metadata blocks in memory, and three progressively more powerful | ||
50 | * interfaces for traversing and editing metadata in FLAC files. | ||
51 | * | ||
52 | * See the detailed documentation for each interface in the | ||
53 | * \link flac_metadata metadata \endlink module. | ||
54 | */ | ||
55 | |||
56 | /** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces | ||
57 | * \ingroup flac | ||
58 | * | ||
59 | * \brief | ||
60 | * This module provides functions for creating and manipulating FLAC | ||
61 | * metadata blocks in memory, and three progressively more powerful | ||
62 | * interfaces for traversing and editing metadata in FLAC files. | ||
63 | * | ||
64 | * There are three metadata interfaces of increasing complexity: | ||
65 | * | ||
66 | * Level 0: | ||
67 | * Read-only access to the STREAMINFO and VORBIS_COMMENT blocks. | ||
68 | * | ||
69 | * Level 1: | ||
70 | * Read-write access to all metadata blocks. This level is write- | ||
71 | * efficient in most cases (more on this below), and uses less memory | ||
72 | * than level 2. | ||
73 | * | ||
74 | * Level 2: | ||
75 | * Read-write access to all metadata blocks. This level is write- | ||
76 | * efficient in all cases, but uses more memory since all metadata for | ||
77 | * the whole file is read into memory and manipulated before writing | ||
78 | * out again. | ||
79 | * | ||
80 | * What do we mean by efficient? Since FLAC metadata appears at the | ||
81 | * beginning of the file, when writing metadata back to a FLAC file | ||
82 | * it is possible to grow or shrink the metadata such that the entire | ||
83 | * file must be rewritten. However, if the size remains the same during | ||
84 | * changes or PADDING blocks are utilized, only the metadata needs to be | ||
85 | * overwritten, which is much faster. | ||
86 | * | ||
87 | * Efficient means the whole file is rewritten at most one time, and only | ||
88 | * when necessary. Level 1 is not efficient only in the case that you | ||
89 | * cause more than one metadata block to grow or shrink beyond what can | ||
90 | * be accomodated by padding. In this case you should probably use level | ||
91 | * 2, which allows you to edit all the metadata for a file in memory and | ||
92 | * write it out all at once. | ||
93 | * | ||
94 | * All levels know how to skip over and not disturb an ID3v2 tag at the | ||
95 | * front of the file. | ||
96 | * | ||
97 | * All levels access files via their filenames. In addition, level 2 | ||
98 | * has additional alternative read and write functions that take an I/O | ||
99 | * handle and callbacks, for times when access by filename is not possible. | ||
100 | * | ||
101 | * In addition to the three interfaces, this module defines functions for | ||
102 | * creating and manipulating various metadata objects in memory. As we see | ||
103 | * from the Format module, FLAC metadata blocks in memory are very primitive | ||
104 | * structures for storing information in an efficient way. Reading | ||
105 | * information from the structures is easy but creating or modifying them | ||
106 | * directly is more complex. The metadata object routines here facilitate | ||
107 | * this by taking care of the consistency and memory management drudgery. | ||
108 | * | ||
109 | * Unless you will be using the level 1 or 2 interfaces to modify existing | ||
110 | * metadata however, you will not probably not need these. | ||
111 | * | ||
112 | * From a dependency standpoint, none of the encoders or decoders require | ||
113 | * the metadata module. This is so that embedded users can strip out the | ||
114 | * metadata module from libFLAC to reduce the size and complexity. | ||
115 | */ | ||
116 | |||
117 | #ifdef __cplusplus | ||
118 | extern "C" { | ||
119 | #endif | ||
120 | |||
121 | |||
122 | /** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface | ||
123 | * \ingroup flac_metadata | ||
124 | * | ||
125 | * \brief | ||
126 | * The level 0 interface consists of individual routines to read the | ||
127 | * STREAMINFO and VORBIS_COMMENT blocks, requiring only a filename. | ||
128 | * | ||
129 | * It skips any ID3v2 tag at the head of the file. | ||
130 | * | ||
131 | * \{ | ||
132 | */ | ||
133 | |||
134 | /** Read the STREAMINFO metadata block of the given FLAC file. This function | ||
135 | * will skip any ID3v2 tag at the head of the file. | ||
136 | * | ||
137 | * \param filename The path to the FLAC file to read. | ||
138 | * \param streaminfo A pointer to space for the STREAMINFO block. Since | ||
139 | * FLAC__StreamMetadata is a simple structure with no | ||
140 | * memory allocation involved, you pass the address of | ||
141 | * an existing structure. It need not be initialized. | ||
142 | * \assert | ||
143 | * \code filename != NULL \endcode | ||
144 | * \code streaminfo != NULL \endcode | ||
145 | * \retval FLAC__bool | ||
146 | * \c true if a valid STREAMINFO block was read from \a filename. Returns | ||
147 | * \c false if there was a memory allocation error, a file decoder error, | ||
148 | * or the file contained no STREAMINFO block. (A memory allocation error | ||
149 | * is possible because this function must set up a file decoder.) | ||
150 | */ | ||
151 | FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); | ||
152 | |||
153 | /** Read the VORBIS_COMMENT metadata block of the given FLAC file. This | ||
154 | * function will skip any ID3v2 tag at the head of the file. | ||
155 | * | ||
156 | * \param filename The path to the FLAC file to read. | ||
157 | * \param tags The address where the returned pointer will be | ||
158 | * stored. The \a tags object must be deleted by | ||
159 | * the caller using FLAC__metadata_object_delete(). | ||
160 | * \assert | ||
161 | * \code filename != NULL \endcode | ||
162 | * \code streaminfo != NULL \endcode | ||
163 | * \retval FLAC__bool | ||
164 | * \c true if a valid VORBIS_COMMENT block was read from \a filename, | ||
165 | * and \a *tags will be set to the address of the tag structure. | ||
166 | * Returns \c false if there was a memory allocation error, a file | ||
167 | * decoder error, or the file contained no VORBIS_COMMENT block, and | ||
168 | * \a *tags will be set to \c NULL. | ||
169 | */ | ||
170 | FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); | ||
171 | |||
172 | /* \} */ | ||
173 | |||
174 | |||
175 | /** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface | ||
176 | * \ingroup flac_metadata | ||
177 | * | ||
178 | * \brief | ||
179 | * The level 1 interface provides read-write access to FLAC file metadata and | ||
180 | * operates directly on the FLAC file. | ||
181 | * | ||
182 | * The general usage of this interface is: | ||
183 | * | ||
184 | * - Create an iterator using FLAC__metadata_simple_iterator_new() | ||
185 | * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check | ||
186 | * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to | ||
187 | * see if the file is writable, or read-only access is allowed. | ||
188 | * - Use FLAC__metadata_simple_iterator_next() and | ||
189 | * FLAC__metadata_simple_iterator_prev() to move around the blocks. | ||
190 | * This is does not read the actual blocks themselves. | ||
191 | * FLAC__metadata_simple_iterator_next() is relatively fast. | ||
192 | * FLAC__metadata_simple_iterator_prev() is slower since it needs to search | ||
193 | * forward from the front of the file. | ||
194 | * - Use FLAC__metadata_simple_iterator_get_block_type() or | ||
195 | * FLAC__metadata_simple_iterator_get_block() to access the actual data at | ||
196 | * the current iterator position. The returned object is yours to modify | ||
197 | * and free. | ||
198 | * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block | ||
199 | * back. You must have write permission to the original file. Make sure to | ||
200 | * read the whole comment to FLAC__metadata_simple_iterator_set_block() | ||
201 | * below. | ||
202 | * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. | ||
203 | * Use the object creation functions from | ||
204 | * \link flac_metadata_object here \endlink to generate new objects. | ||
205 | * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block | ||
206 | * currently referred to by the iterator, or replace it with padding. | ||
207 | * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when | ||
208 | * finished. | ||
209 | * | ||
210 | * \note | ||
211 | * The FLAC file remains open the whole time between | ||
212 | * FLAC__metadata_simple_iterator_init() and | ||
213 | * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering | ||
214 | * the file during this time. | ||
215 | * | ||
216 | * \note | ||
217 | * Do not modify the \a is_last, \a length, or \a type fields of returned | ||
218 | * FLAC__StreamMetadata objects. These are managed automatically. | ||
219 | * | ||
220 | * \note | ||
221 | * If any of the modification functions | ||
222 | * (FLAC__metadata_simple_iterator_set_block(), | ||
223 | * FLAC__metadata_simple_iterator_delete_block(), | ||
224 | * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, | ||
225 | * you should delete the iterator as it may no longer be valid. | ||
226 | * | ||
227 | * \{ | ||
228 | */ | ||
229 | |||
230 | struct FLAC__Metadata_SimpleIterator; | ||
231 | /** The opaque structure definition for the level 1 iterator type. | ||
232 | * See the | ||
233 | * \link flac_metadata_level1 metadata level 1 module \endlink | ||
234 | * for a detailed description. | ||
235 | */ | ||
236 | typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; | ||
237 | |||
238 | /** Status type for FLAC__Metadata_SimpleIterator. | ||
239 | * | ||
240 | * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). | ||
241 | */ | ||
242 | typedef enum { | ||
243 | |||
244 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, | ||
245 | /**< The iterator is in the normal OK state */ | ||
246 | |||
247 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, | ||
248 | /**< The data passed into a function violated the function's usage criteria */ | ||
249 | |||
250 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, | ||
251 | /**< The iterator could not open the target file */ | ||
252 | |||
253 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, | ||
254 | /**< The iterator could not find the FLAC signature at the start of the file */ | ||
255 | |||
256 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, | ||
257 | /**< The iterator tried to write to a file that was not writable */ | ||
258 | |||
259 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, | ||
260 | /**< The iterator encountered input that does not conform to the FLAC metadata specification */ | ||
261 | |||
262 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, | ||
263 | /**< The iterator encountered an error while reading the FLAC file */ | ||
264 | |||
265 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, | ||
266 | /**< The iterator encountered an error while seeking in the FLAC file */ | ||
267 | |||
268 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, | ||
269 | /**< The iterator encountered an error while writing the FLAC file */ | ||
270 | |||
271 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, | ||
272 | /**< The iterator encountered an error renaming the FLAC file */ | ||
273 | |||
274 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, | ||
275 | /**< The iterator encountered an error removing the temporary file */ | ||
276 | |||
277 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, | ||
278 | /**< Memory allocation failed */ | ||
279 | |||
280 | FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR | ||
281 | /**< The caller violated an assertion or an unexpected error occurred */ | ||
282 | |||
283 | } FLAC__Metadata_SimpleIteratorStatus; | ||
284 | |||
285 | /** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. | ||
286 | * | ||
287 | * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array | ||
288 | * will give the string equivalent. The contents should not be modified. | ||
289 | */ | ||
290 | extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; | ||
291 | |||
292 | |||
293 | /** Create a new iterator instance. | ||
294 | * | ||
295 | * \retval FLAC__Metadata_SimpleIterator* | ||
296 | * \c NULL if there was an error allocating memory, else the new instance. | ||
297 | */ | ||
298 | FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(); | ||
299 | |||
300 | /** Free an iterator instance. Deletes the object pointed to by \a iterator. | ||
301 | * | ||
302 | * \param iterator A pointer to an existing iterator. | ||
303 | * \assert | ||
304 | * \code iterator != NULL \endcode | ||
305 | */ | ||
306 | FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); | ||
307 | |||
308 | /** Get the current status of the iterator. Call this after a function | ||
309 | * returns \c false to get the reason for the error. Also resets the status | ||
310 | * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. | ||
311 | * | ||
312 | * \param iterator A pointer to an existing iterator. | ||
313 | * \assert | ||
314 | * \code iterator != NULL \endcode | ||
315 | * \retval FLAC__Metadata_SimpleIteratorStatus | ||
316 | * The current status of the iterator. | ||
317 | */ | ||
318 | FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); | ||
319 | |||
320 | /** Initialize the iterator to point to the first metadata block in the | ||
321 | * given FLAC file. | ||
322 | * | ||
323 | * \param iterator A pointer to an existing iterator. | ||
324 | * \param filename The path to the FLAC file. | ||
325 | * \param read_only If \c true, the FLAC file will be opened | ||
326 | * in read-only mode; if \c false, the FLAC | ||
327 | * file will be opened for edit even if no | ||
328 | * edits are performed. | ||
329 | * \param preserve_file_stats If \c true, the owner and modification | ||
330 | * time will be preserved even if the FLAC | ||
331 | * file is written to. | ||
332 | * \assert | ||
333 | * \code iterator != NULL \endcode | ||
334 | * \code filename != NULL \endcode | ||
335 | * \retval FLAC__bool | ||
336 | * \c false if a memory allocation error occurs, the file can't be | ||
337 | * opened, or another error occurs, else \c true. | ||
338 | */ | ||
339 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); | ||
340 | |||
341 | /** Returns \c true if the FLAC file is writable. If \c false, calls to | ||
342 | * FLAC__metadata_simple_iterator_set_block() and | ||
343 | * FLAC__metadata_simple_iterator_insert_block_after() will fail. | ||
344 | * | ||
345 | * \param iterator A pointer to an existing iterator. | ||
346 | * \assert | ||
347 | * \code iterator != NULL \endcode | ||
348 | * \retval FLAC__bool | ||
349 | * See above. | ||
350 | */ | ||
351 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); | ||
352 | |||
353 | /** Moves the iterator forward one metadata block, returning \c false if | ||
354 | * already at the end. | ||
355 | * | ||
356 | * \param iterator A pointer to an existing initialized iterator. | ||
357 | * \assert | ||
358 | * \code iterator != NULL \endcode | ||
359 | * \a iterator has been successfully initialized with | ||
360 | * FLAC__metadata_simple_iterator_init() | ||
361 | * \retval FLAC__bool | ||
362 | * \c false if already at the last metadata block of the chain, else | ||
363 | * \c true. | ||
364 | */ | ||
365 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); | ||
366 | |||
367 | /** Moves the iterator backward one metadata block, returning \c false if | ||
368 | * already at the beginning. | ||
369 | * | ||
370 | * \param iterator A pointer to an existing initialized iterator. | ||
371 | * \assert | ||
372 | * \code iterator != NULL \endcode | ||
373 | * \a iterator has been successfully initialized with | ||
374 | * FLAC__metadata_simple_iterator_init() | ||
375 | * \retval FLAC__bool | ||
376 | * \c false if already at the first metadata block of the chain, else | ||
377 | * \c true. | ||
378 | */ | ||
379 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); | ||
380 | |||
381 | /** Get the type of the metadata block at the current position. This | ||
382 | * avoids reading the actual block data which can save time for large | ||
383 | * blocks. | ||
384 | * | ||
385 | * \param iterator A pointer to an existing initialized iterator. | ||
386 | * \assert | ||
387 | * \code iterator != NULL \endcode | ||
388 | * \a iterator has been successfully initialized with | ||
389 | * FLAC__metadata_simple_iterator_init() | ||
390 | * \retval FLAC__MetadataType | ||
391 | * The type of the metadata block at the current iterator position. | ||
392 | */ | ||
393 | |||
394 | FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); | ||
395 | |||
396 | /** Get the metadata block at the current position. You can modify the | ||
397 | * block but must use FLAC__metadata_simple_iterator_set_block() to | ||
398 | * write it back to the FLAC file. | ||
399 | * | ||
400 | * You must call FLAC__metadata_object_delete() on the returned object | ||
401 | * when you are finished with it. | ||
402 | * | ||
403 | * \param iterator A pointer to an existing initialized iterator. | ||
404 | * \assert | ||
405 | * \code iterator != NULL \endcode | ||
406 | * \a iterator has been successfully initialized with | ||
407 | * FLAC__metadata_simple_iterator_init() | ||
408 | * \retval FLAC__StreamMetadata* | ||
409 | * The current metadata block. | ||
410 | */ | ||
411 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); | ||
412 | |||
413 | /** Write a block back to the FLAC file. This function tries to be | ||
414 | * as efficient as possible; how the block is actually written is | ||
415 | * shown by the following: | ||
416 | * | ||
417 | * Existing block is a STREAMINFO block and the new block is a | ||
418 | * STREAMINFO block: the new block is written in place. Make sure | ||
419 | * you know what you're doing when changing the values of a | ||
420 | * STREAMINFO block. | ||
421 | * | ||
422 | * Existing block is a STREAMINFO block and the new block is a | ||
423 | * not a STREAMINFO block: this is an error since the first block | ||
424 | * must be a STREAMINFO block. Returns \c false without altering the | ||
425 | * file. | ||
426 | * | ||
427 | * Existing block is not a STREAMINFO block and the new block is a | ||
428 | * STREAMINFO block: this is an error since there may be only one | ||
429 | * STREAMINFO block. Returns \c false without altering the file. | ||
430 | * | ||
431 | * Existing block and new block are the same length: the existing | ||
432 | * block will be replaced by the new block, written in place. | ||
433 | * | ||
434 | * Existing block is longer than new block: if use_padding is \c true, | ||
435 | * the existing block will be overwritten in place with the new | ||
436 | * block followed by a PADDING block, if possible, to make the total | ||
437 | * size the same as the existing block. Remember that a padding | ||
438 | * block requires at least four bytes so if the difference in size | ||
439 | * between the new block and existing block is less than that, the | ||
440 | * entire file will have to be rewritten, using the new block's | ||
441 | * exact size. If use_padding is \c false, the entire file will be | ||
442 | * rewritten, replacing the existing block by the new block. | ||
443 | * | ||
444 | * Existing block is shorter than new block: if use_padding is \c true, | ||
445 | * the function will try and expand the new block into the following | ||
446 | * PADDING block, if it exists and doing so won't shrink the PADDING | ||
447 | * block to less than 4 bytes. If there is no following PADDING | ||
448 | * block, or it will shrink to less than 4 bytes, or use_padding is | ||
449 | * \c false, the entire file is rewritten, replacing the existing block | ||
450 | * with the new block. Note that in this case any following PADDING | ||
451 | * block is preserved as is. | ||
452 | * | ||
453 | * After writing the block, the iterator will remain in the same | ||
454 | * place, i.e. pointing to the new block. | ||
455 | * | ||
456 | * \param iterator A pointer to an existing initialized iterator. | ||
457 | * \param block The block to set. | ||
458 | * \param use_padding See above. | ||
459 | * \assert | ||
460 | * \code iterator != NULL \endcode | ||
461 | * \a iterator has been successfully initialized with | ||
462 | * FLAC__metadata_simple_iterator_init() | ||
463 | * \code block != NULL \endcode | ||
464 | * \retval FLAC__bool | ||
465 | * \c true if successful, else \c false. | ||
466 | */ | ||
467 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); | ||
468 | |||
469 | /** This is similar to FLAC__metadata_simple_iterator_set_block() | ||
470 | * except that instead of writing over an existing block, it appends | ||
471 | * a block after the existing block. \a use_padding is again used to | ||
472 | * tell the function to try an expand into following padding in an | ||
473 | * attempt to avoid rewriting the entire file. | ||
474 | * | ||
475 | * This function will fail and return \c false if given a STREAMINFO | ||
476 | * block. | ||
477 | * | ||
478 | * After writing the block, the iterator will be pointing to the | ||
479 | * new block. | ||
480 | * | ||
481 | * \param iterator A pointer to an existing initialized iterator. | ||
482 | * \param block The block to set. | ||
483 | * \param use_padding See above. | ||
484 | * \assert | ||
485 | * \code iterator != NULL \endcode | ||
486 | * \a iterator has been successfully initialized with | ||
487 | * FLAC__metadata_simple_iterator_init() | ||
488 | * \code block != NULL \endcode | ||
489 | * \retval FLAC__bool | ||
490 | * \c true if successful, else \c false. | ||
491 | */ | ||
492 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); | ||
493 | |||
494 | /** Deletes the block at the current position. This will cause the | ||
495 | * entire FLAC file to be rewritten, unless \a use_padding is \c true, | ||
496 | * in which case the block will be replaced by an equal-sized PADDING | ||
497 | * block. The iterator will be left pointing to the block before the | ||
498 | * one just deleted. | ||
499 | * | ||
500 | * You may not delete the STREAMINFO block. | ||
501 | * | ||
502 | * \param iterator A pointer to an existing initialized iterator. | ||
503 | * \param use_padding See above. | ||
504 | * \assert | ||
505 | * \code iterator != NULL \endcode | ||
506 | * \a iterator has been successfully initialized with | ||
507 | * FLAC__metadata_simple_iterator_init() | ||
508 | * \retval FLAC__bool | ||
509 | * \c true if successful, else \c false. | ||
510 | */ | ||
511 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); | ||
512 | |||
513 | /* \} */ | ||
514 | |||
515 | |||
516 | /** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface | ||
517 | * \ingroup flac_metadata | ||
518 | * | ||
519 | * \brief | ||
520 | * The level 2 interface provides read-write access to FLAC file metadata; | ||
521 | * all metadata is read into memory, operated on in memory, and then written | ||
522 | * to file, which is more efficient than level 1 when editing multiple blocks. | ||
523 | * | ||
524 | * The general usage of this interface is: | ||
525 | * | ||
526 | * - Create a new chain using FLAC__metadata_chain_new(). A chain is a | ||
527 | * linked list of FLAC metadata blocks. | ||
528 | * - Read all metadata into the the chain from a FLAC file using | ||
529 | * FLAC__metadata_chain_read() and check the status. | ||
530 | * - Optionally, consolidate the padding using | ||
531 | * FLAC__metadata_chain_merge_padding() or | ||
532 | * FLAC__metadata_chain_sort_padding(). | ||
533 | * - Create a new iterator using FLAC__metadata_iterator_new() | ||
534 | * - Initialize the iterator to point to the first element in the chain | ||
535 | * using FLAC__metadata_iterator_init() | ||
536 | * - Traverse the chain using FLAC__metadata_iterator_next and | ||
537 | * FLAC__metadata_iterator_prev(). | ||
538 | * - Get a block for reading or modification using | ||
539 | * FLAC__metadata_iterator_get_block(). The pointer to the object | ||
540 | * inside the chain is returned, so the block is yours to modify. | ||
541 | * Changes will be reflected in the FLAC file when you write the | ||
542 | * chain. You can also add and delete blocks (see functions below). | ||
543 | * - When done, write out the chain using FLAC__metadata_chain_write(). | ||
544 | * Make sure to read the whole comment to the function below. | ||
545 | * - Delete the chain using FLAC__metadata_chain_delete(). | ||
546 | * | ||
547 | * \note | ||
548 | * Even though the FLAC file is not open while the chain is being | ||
549 | * manipulated, you must not alter the file externally during | ||
550 | * this time. The chain assumes the FLAC file will not change | ||
551 | * between the time of FLAC__metadata_chain_read() and | ||
552 | * FLAC__metadata_chain_write(). | ||
553 | * | ||
554 | * \note | ||
555 | * Do not modify the is_last, length, or type fields of returned | ||
556 | * FLAC__StreamMetadata objects. These are managed automatically. | ||
557 | * | ||
558 | * \note | ||
559 | * The metadata objects returned by FLAC__metadata_iterator_get_block() | ||
560 | * are owned by the chain; do not FLAC__metadata_object_delete() them. | ||
561 | * In the same way, blocks passed to FLAC__metadata_iterator_set_block() | ||
562 | * become owned by the chain and they will be deleted when the chain is | ||
563 | * deleted. | ||
564 | * | ||
565 | * \{ | ||
566 | */ | ||
567 | |||
568 | struct FLAC__Metadata_Chain; | ||
569 | /** The opaque structure definition for the level 2 chain type. | ||
570 | */ | ||
571 | typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; | ||
572 | |||
573 | struct FLAC__Metadata_Iterator; | ||
574 | /** The opaque structure definition for the level 2 iterator type. | ||
575 | */ | ||
576 | typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; | ||
577 | |||
578 | typedef enum { | ||
579 | FLAC__METADATA_CHAIN_STATUS_OK = 0, | ||
580 | /**< The chain is in the normal OK state */ | ||
581 | |||
582 | FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, | ||
583 | /**< The data passed into a function violated the function's usage criteria */ | ||
584 | |||
585 | FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, | ||
586 | /**< The chain could not open the target file */ | ||
587 | |||
588 | FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, | ||
589 | /**< The chain could not find the FLAC signature at the start of the file */ | ||
590 | |||
591 | FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, | ||
592 | /**< The chain tried to write to a file that was not writable */ | ||
593 | |||
594 | FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, | ||
595 | /**< The chain encountered input that does not conform to the FLAC metadata specification */ | ||
596 | |||
597 | FLAC__METADATA_CHAIN_STATUS_READ_ERROR, | ||
598 | /**< The chain encountered an error while reading the FLAC file */ | ||
599 | |||
600 | FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, | ||
601 | /**< The chain encountered an error while seeking in the FLAC file */ | ||
602 | |||
603 | FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, | ||
604 | /**< The chain encountered an error while writing the FLAC file */ | ||
605 | |||
606 | FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, | ||
607 | /**< The chain encountered an error renaming the FLAC file */ | ||
608 | |||
609 | FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, | ||
610 | /**< The chain encountered an error removing the temporary file */ | ||
611 | |||
612 | FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, | ||
613 | /**< Memory allocation failed */ | ||
614 | |||
615 | FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, | ||
616 | /**< The caller violated an assertion or an unexpected error occurred */ | ||
617 | |||
618 | FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, | ||
619 | /**< One or more of the required callbacks was NULL */ | ||
620 | |||
621 | FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, | ||
622 | /**< FLAC__metadata_chain_write() was called on a chain read by | ||
623 | * FLAC__metadata_chain_read_with_callbacks(), or | ||
624 | * FLAC__metadata_chain_write_with_callbacks() or | ||
625 | * FLAC__metadata_chain_write_with_callbacks_and_tempfile() was | ||
626 | * called on a chain read by FLAC__metadata_chain_read(). Matching | ||
627 | * read/write methods must always be used. */ | ||
628 | |||
629 | FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL | ||
630 | /**< FLAC__metadata_chain_write_with_callbacks() was called when the | ||
631 | * chain write requires a tempfile; use | ||
632 | * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. | ||
633 | * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was | ||
634 | * called when the chain write does not require a tempfile; use | ||
635 | * FLAC__metadata_chain_write_with_callbacks() instead. | ||
636 | * Always check FLAC__metadata_chain_check_if_tempfile_needed() | ||
637 | * before writing via callbacks. */ | ||
638 | |||
639 | } FLAC__Metadata_ChainStatus; | ||
640 | |||
641 | /** Maps a FLAC__Metadata_ChainStatus to a C string. | ||
642 | * | ||
643 | * Using a FLAC__Metadata_ChainStatus as the index to this array | ||
644 | * will give the string equivalent. The contents should not be modified. | ||
645 | */ | ||
646 | extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; | ||
647 | |||
648 | /*********** FLAC__Metadata_Chain ***********/ | ||
649 | |||
650 | /** Create a new chain instance. | ||
651 | * | ||
652 | * \retval FLAC__Metadata_Chain* | ||
653 | * \c NULL if there was an error allocating memory, else the new instance. | ||
654 | */ | ||
655 | FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(); | ||
656 | |||
657 | /** Free a chain instance. Deletes the object pointed to by \a chain. | ||
658 | * | ||
659 | * \param chain A pointer to an existing chain. | ||
660 | * \assert | ||
661 | * \code chain != NULL \endcode | ||
662 | */ | ||
663 | FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); | ||
664 | |||
665 | /** Get the current status of the chain. Call this after a function | ||
666 | * returns \c false to get the reason for the error. Also resets the | ||
667 | * status to FLAC__METADATA_CHAIN_STATUS_OK. | ||
668 | * | ||
669 | * \param chain A pointer to an existing chain. | ||
670 | * \assert | ||
671 | * \code chain != NULL \endcode | ||
672 | * \retval FLAC__Metadata_ChainStatus | ||
673 | * The current status of the chain. | ||
674 | */ | ||
675 | FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); | ||
676 | |||
677 | /** Read all metadata from a FLAC file into the chain. | ||
678 | * | ||
679 | * \param chain A pointer to an existing chain. | ||
680 | * \param filename The path to the FLAC file to read. | ||
681 | * \assert | ||
682 | * \code chain != NULL \endcode | ||
683 | * \code filename != NULL \endcode | ||
684 | * \retval FLAC__bool | ||
685 | * \c true if a valid list of metadata blocks was read from | ||
686 | * \a filename, else \c false. On failure, check the status with | ||
687 | * FLAC__metadata_chain_status(). | ||
688 | */ | ||
689 | FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); | ||
690 | |||
691 | /** Read all metadata from a FLAC stream into the chain via I/O callbacks. | ||
692 | * | ||
693 | * The \a handle need only be open for reading, but must be seekable. | ||
694 | * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" | ||
695 | * for Windows). | ||
696 | * | ||
697 | * \param chain A pointer to an existing chain. | ||
698 | * \param handle The I/O handle of the FLAC stream to read. The | ||
699 | * handle will NOT be closed after the metadata is read; | ||
700 | * that is the duty of the caller. | ||
701 | * \param callbacks | ||
702 | * A set of callbacks to use for I/O. The mandatory | ||
703 | * callbacks are \a read, \a seek, and \a tell. | ||
704 | * \assert | ||
705 | * \code chain != NULL \endcode | ||
706 | * \retval FLAC__bool | ||
707 | * \c true if a valid list of metadata blocks was read from | ||
708 | * \a handle, else \c false. On failure, check the status with | ||
709 | * FLAC__metadata_chain_status(). | ||
710 | */ | ||
711 | FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); | ||
712 | |||
713 | /** Checks if writing the given chain would require the use of a | ||
714 | * temporary file, or if it could be written in place. | ||
715 | * | ||
716 | * Under certain conditions, padding can be utilized so that writing | ||
717 | * edited metadata back to the FLAC file does not require rewriting the | ||
718 | * entire file. If rewriting is required, then a temporary workfile is | ||
719 | * required. When writing metadata using callbacks, you must check | ||
720 | * this function to know whether to call | ||
721 | * FLAC__metadata_chain_write_with_callbacks() or | ||
722 | * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When | ||
723 | * writing with FLAC__metadata_chain_write(), the temporary file is | ||
724 | * handled internally. | ||
725 | * | ||
726 | * \param chain A pointer to an existing chain. | ||
727 | * \param use_padding | ||
728 | * Whether or not padding will be allowed to be used | ||
729 | * during the write. The value of \a use_padding given | ||
730 | * here must match the value later passed to | ||
731 | * FLAC__metadata_chain_write_with_callbacks() or | ||
732 | * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). | ||
733 | * \assert | ||
734 | * \code chain != NULL \endcode | ||
735 | * \retval FLAC__bool | ||
736 | * \c true if writing the current chain would require a tempfile, or | ||
737 | * \c false if metadata can be written in place. | ||
738 | */ | ||
739 | FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); | ||
740 | |||
741 | /** Write all metadata out to the FLAC file. This function tries to be as | ||
742 | * efficient as possible; how the metadata is actually written is shown by | ||
743 | * the following: | ||
744 | * | ||
745 | * If the current chain is the same size as the existing metadata, the new | ||
746 | * data is written in place. | ||
747 | * | ||
748 | * If the current chain is longer than the existing metadata, and | ||
749 | * \a use_padding is \c true, and the last block is a PADDING block of | ||
750 | * sufficient length, the function will truncate the final padding block | ||
751 | * so that the overall size of the metadata is the same as the existing | ||
752 | * metadata, and then just rewrite the metadata. Otherwise, if not all of | ||
753 | * the above conditions are met, the entire FLAC file must be rewritten. | ||
754 | * If you want to use padding this way it is a good idea to call | ||
755 | * FLAC__metadata_chain_sort_padding() first so that you have the maximum | ||
756 | * amount of padding to work with, unless you need to preserve ordering | ||
757 | * of the PADDING blocks for some reason. | ||
758 | * | ||
759 | * If the current chain is shorter than the existing metadata, and | ||
760 | * \a use_padding is \c true, and the final block is a PADDING block, the padding | ||
761 | * is extended to make the overall size the same as the existing data. If | ||
762 | * \a use_padding is \c true and the last block is not a PADDING block, a new | ||
763 | * PADDING block is added to the end of the new data to make it the same | ||
764 | * size as the existing data (if possible, see the note to | ||
765 | * FLAC__metadata_simple_iterator_set_block() about the four byte limit) | ||
766 | * and the new data is written in place. If none of the above apply or | ||
767 | * \a use_padding is \c false, the entire FLAC file is rewritten. | ||
768 | * | ||
769 | * If \a preserve_file_stats is \c true, the owner and modification time will | ||
770 | * be preserved even if the FLAC file is written. | ||
771 | * | ||
772 | * For this write function to be used, the chain must have been read with | ||
773 | * FLAC__metadata_chain_read(), not FLAC__metadata_chain_read_with_callbacks(). | ||
774 | * | ||
775 | * \param chain A pointer to an existing chain. | ||
776 | * \param use_padding See above. | ||
777 | * \param preserve_file_stats See above. | ||
778 | * \assert | ||
779 | * \code chain != NULL \endcode | ||
780 | * \retval FLAC__bool | ||
781 | * \c true if the write succeeded, else \c false. On failure, | ||
782 | * check the status with FLAC__metadata_chain_status(). | ||
783 | */ | ||
784 | FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); | ||
785 | |||
786 | /** Write all metadata out to a FLAC stream via callbacks. | ||
787 | * | ||
788 | * (See FLAC__metadata_chain_write() for the details on how padding is | ||
789 | * used to write metadata in place if possible.) | ||
790 | * | ||
791 | * The \a handle must be open for updating and be seekable. The | ||
792 | * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" | ||
793 | * for Windows). | ||
794 | * | ||
795 | * For this write function to be used, the chain must have been read with | ||
796 | * FLAC__metadata_chain_read_with_callbacks(), not FLAC__metadata_chain_read(). | ||
797 | * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned | ||
798 | * \c false. | ||
799 | * | ||
800 | * \param chain A pointer to an existing chain. | ||
801 | * \param use_padding See FLAC__metadata_chain_write() | ||
802 | * \param handle The I/O handle of the FLAC stream to write. The | ||
803 | * handle will NOT be closed after the metadata is | ||
804 | * written; that is the duty of the caller. | ||
805 | * \param callbacks A set of callbacks to use for I/O. The mandatory | ||
806 | * callbacks are \a write and \a seek. | ||
807 | * \assert | ||
808 | * \code chain != NULL \endcode | ||
809 | * \retval FLAC__bool | ||
810 | * \c true if the write succeeded, else \c false. On failure, | ||
811 | * check the status with FLAC__metadata_chain_status(). | ||
812 | */ | ||
813 | FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); | ||
814 | |||
815 | /** Write all metadata out to a FLAC stream via callbacks. | ||
816 | * | ||
817 | * (See FLAC__metadata_chain_write() for the details on how padding is | ||
818 | * used to write metadata in place if possible.) | ||
819 | * | ||
820 | * This version of the write-with-callbacks function must be used when | ||
821 | * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In | ||
822 | * this function, you must supply an I/O handle corresponding to the | ||
823 | * FLAC file to edit, and a temporary handle to which the new FLAC | ||
824 | * file will be written. It is the caller's job to move this temporary | ||
825 | * FLAC file on top of the original FLAC file to complete the metadata | ||
826 | * edit. | ||
827 | * | ||
828 | * The \a handle must be open for reading and be seekable. The | ||
829 | * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" | ||
830 | * for Windows). | ||
831 | * | ||
832 | * The \a temp_handle must be open for writing. The | ||
833 | * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" | ||
834 | * for Windows). It should be an empty stream, or at least positioned | ||
835 | * at the start-of-file (in which case it is the caller's duty to | ||
836 | * truncate it on return). | ||
837 | * | ||
838 | * For this write function to be used, the chain must have been read with | ||
839 | * FLAC__metadata_chain_read_with_callbacks(), not FLAC__metadata_chain_read(). | ||
840 | * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned | ||
841 | * \c true. | ||
842 | * | ||
843 | * \param chain A pointer to an existing chain. | ||
844 | * \param use_padding See FLAC__metadata_chain_write() | ||
845 | * \param handle The I/O handle of the original FLAC stream to read. | ||
846 | * The handle will NOT be closed after the metadata is | ||
847 | * written; that is the duty of the caller. | ||
848 | * \param callbacks A set of callbacks to use for I/O on \a handle. | ||
849 | * The mandatory callbacks are \a read, \a seek, and | ||
850 | * \a eof. | ||
851 | * \param temp_handle The I/O handle of the FLAC stream to write. The | ||
852 | * handle will NOT be closed after the metadata is | ||
853 | * written; that is the duty of the caller. | ||
854 | * \param temp_callbacks | ||
855 | * A set of callbacks to use for I/O on temp_handle. | ||
856 | * The only mandatory callback is \a write. | ||
857 | * \assert | ||
858 | * \code chain != NULL \endcode | ||
859 | * \retval FLAC__bool | ||
860 | * \c true if the write succeeded, else \c false. On failure, | ||
861 | * check the status with FLAC__metadata_chain_status(). | ||
862 | */ | ||
863 | FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); | ||
864 | |||
865 | /** Merge adjacent PADDING blocks into a single block. | ||
866 | * | ||
867 | * \note This function does not write to the FLAC file, it only | ||
868 | * modifies the chain. | ||
869 | * | ||
870 | * \warning Any iterator on the current chain will become invalid after this | ||
871 | * call. You should delete the iterator and get a new one. | ||
872 | * | ||
873 | * \param chain A pointer to an existing chain. | ||
874 | * \assert | ||
875 | * \code chain != NULL \endcode | ||
876 | */ | ||
877 | FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); | ||
878 | |||
879 | /** This function will move all PADDING blocks to the end on the metadata, | ||
880 | * then merge them into a single block. | ||
881 | * | ||
882 | * \note This function does not write to the FLAC file, it only | ||
883 | * modifies the chain. | ||
884 | * | ||
885 | * \warning Any iterator on the current chain will become invalid after this | ||
886 | * call. You should delete the iterator and get a new one. | ||
887 | * | ||
888 | * \param chain A pointer to an existing chain. | ||
889 | * \assert | ||
890 | * \code chain != NULL \endcode | ||
891 | */ | ||
892 | FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); | ||
893 | |||
894 | |||
895 | /*********** FLAC__Metadata_Iterator ***********/ | ||
896 | |||
897 | /** Create a new iterator instance. | ||
898 | * | ||
899 | * \retval FLAC__Metadata_Iterator* | ||
900 | * \c NULL if there was an error allocating memory, else the new instance. | ||
901 | */ | ||
902 | FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(); | ||
903 | |||
904 | /** Free an iterator instance. Deletes the object pointed to by \a iterator. | ||
905 | * | ||
906 | * \param iterator A pointer to an existing iterator. | ||
907 | * \assert | ||
908 | * \code iterator != NULL \endcode | ||
909 | */ | ||
910 | FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); | ||
911 | |||
912 | /** Initialize the iterator to point to the first metadata block in the | ||
913 | * given chain. | ||
914 | * | ||
915 | * \param iterator A pointer to an existing iterator. | ||
916 | * \param chain A pointer to an existing and initialized (read) chain. | ||
917 | * \assert | ||
918 | * \code iterator != NULL \endcode | ||
919 | * \code chain != NULL \endcode | ||
920 | */ | ||
921 | FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); | ||
922 | |||
923 | /** Moves the iterator forward one metadata block, returning \c false if | ||
924 | * already at the end. | ||
925 | * | ||
926 | * \param iterator A pointer to an existing initialized iterator. | ||
927 | * \assert | ||
928 | * \code iterator != NULL \endcode | ||
929 | * \a iterator has been successfully initialized with | ||
930 | * FLAC__metadata_iterator_init() | ||
931 | * \retval FLAC__bool | ||
932 | * \c false if already at the last metadata block of the chain, else | ||
933 | * \c true. | ||
934 | */ | ||
935 | FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); | ||
936 | |||
937 | /** Moves the iterator backward one metadata block, returning \c false if | ||
938 | * already at the beginning. | ||
939 | * | ||
940 | * \param iterator A pointer to an existing initialized iterator. | ||
941 | * \assert | ||
942 | * \code iterator != NULL \endcode | ||
943 | * \a iterator has been successfully initialized with | ||
944 | * FLAC__metadata_iterator_init() | ||
945 | * \retval FLAC__bool | ||
946 | * \c false if already at the first metadata block of the chain, else | ||
947 | * \c true. | ||
948 | */ | ||
949 | FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); | ||
950 | |||
951 | /** Get the type of the metadata block at the current position. | ||
952 | * | ||
953 | * \param iterator A pointer to an existing initialized iterator. | ||
954 | * \assert | ||
955 | * \code iterator != NULL \endcode | ||
956 | * \a iterator has been successfully initialized with | ||
957 | * FLAC__metadata_iterator_init() | ||
958 | * \retval FLAC__MetadataType | ||
959 | * The type of the metadata block at the current iterator position. | ||
960 | */ | ||
961 | FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); | ||
962 | |||
963 | /** Get the metadata block at the current position. You can modify | ||
964 | * the block in place but must write the chain before the changes | ||
965 | * are reflected to the FLAC file. You do not need to call | ||
966 | * FLAC__metadata_iterator_set_block() to reflect the changes; | ||
967 | * the pointer returned by FLAC__metadata_iterator_get_block() | ||
968 | * points directly into the chain. | ||
969 | * | ||
970 | * \warning | ||
971 | * Do not call FLAC__metadata_object_delete() on the returned object; | ||
972 | * to delete a block use FLAC__metadata_iterator_delete_block(). | ||
973 | * | ||
974 | * \param iterator A pointer to an existing initialized iterator. | ||
975 | * \assert | ||
976 | * \code iterator != NULL \endcode | ||
977 | * \a iterator has been successfully initialized with | ||
978 | * FLAC__metadata_iterator_init() | ||
979 | * \retval FLAC__StreamMetadata* | ||
980 | * The current metadata block. | ||
981 | */ | ||
982 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); | ||
983 | |||
984 | /** Set the metadata block at the current position, replacing the existing | ||
985 | * block. The new block passed in becomes owned by the chain and it will be | ||
986 | * deleted when the chain is deleted. | ||
987 | * | ||
988 | * \param iterator A pointer to an existing initialized iterator. | ||
989 | * \param block A pointer to a metadata block. | ||
990 | * \assert | ||
991 | * \code iterator != NULL \endcode | ||
992 | * \a iterator has been successfully initialized with | ||
993 | * FLAC__metadata_iterator_init() | ||
994 | * \code block != NULL \endcode | ||
995 | * \retval FLAC__bool | ||
996 | * \c false if the conditions in the above description are not met, or | ||
997 | * a memory allocation error occurs, otherwise \c true. | ||
998 | */ | ||
999 | FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); | ||
1000 | |||
1001 | /** Removes the current block from the chain. If \a replace_with_padding is | ||
1002 | * \c true, the block will instead be replaced with a padding block of equal | ||
1003 | * size. You can not delete the STREAMINFO block. The iterator will be | ||
1004 | * left pointing to the block before the one just "deleted", even if | ||
1005 | * \a replace_with_padding is \c true. | ||
1006 | * | ||
1007 | * \param iterator A pointer to an existing initialized iterator. | ||
1008 | * \param replace_with_padding See above. | ||
1009 | * \assert | ||
1010 | * \code iterator != NULL \endcode | ||
1011 | * \a iterator has been successfully initialized with | ||
1012 | * FLAC__metadata_iterator_init() | ||
1013 | * \retval FLAC__bool | ||
1014 | * \c false if the conditions in the above description are not met, | ||
1015 | * otherwise \c true. | ||
1016 | */ | ||
1017 | FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); | ||
1018 | |||
1019 | /** Insert a new block before the current block. You cannot insert a block | ||
1020 | * before the first STREAMINFO block. You cannot insert a STREAMINFO block | ||
1021 | * as there can be only one, the one that already exists at the head when you | ||
1022 | * read in a chain. The chain takes ownership of the new block and it will be | ||
1023 | * deleted when the chain is deleted. The iterator will be left pointing to | ||
1024 | * the new block. | ||
1025 | * | ||
1026 | * \param iterator A pointer to an existing initialized iterator. | ||
1027 | * \param block A pointer to a metadata block to insert. | ||
1028 | * \assert | ||
1029 | * \code iterator != NULL \endcode | ||
1030 | * \a iterator has been successfully initialized with | ||
1031 | * FLAC__metadata_iterator_init() | ||
1032 | * \retval FLAC__bool | ||
1033 | * \c false if the conditions in the above description are not met, or | ||
1034 | * a memory allocation error occurs, otherwise \c true. | ||
1035 | */ | ||
1036 | FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); | ||
1037 | |||
1038 | /** Insert a new block after the current block. You cannot insert a STREAMINFO | ||
1039 | * block as there can be only one, the one that already exists at the head when | ||
1040 | * you read in a chain. The chain takes ownership of the new block and it will | ||
1041 | * be deleted when the chain is deleted. The iterator will be left pointing to | ||
1042 | * the new block. | ||
1043 | * | ||
1044 | * \param iterator A pointer to an existing initialized iterator. | ||
1045 | * \param block A pointer to a metadata block to insert. | ||
1046 | * \assert | ||
1047 | * \code iterator != NULL \endcode | ||
1048 | * \a iterator has been successfully initialized with | ||
1049 | * FLAC__metadata_iterator_init() | ||
1050 | * \retval FLAC__bool | ||
1051 | * \c false if the conditions in the above description are not met, or | ||
1052 | * a memory allocation error occurs, otherwise \c true. | ||
1053 | */ | ||
1054 | FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); | ||
1055 | |||
1056 | /* \} */ | ||
1057 | |||
1058 | |||
1059 | /** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods | ||
1060 | * \ingroup flac_metadata | ||
1061 | * | ||
1062 | * \brief | ||
1063 | * This module contains methods for manipulating FLAC metadata objects. | ||
1064 | * | ||
1065 | * Since many are variable length we have to be careful about the memory | ||
1066 | * management. We decree that all pointers to data in the object are | ||
1067 | * owned by the object and memory-managed by the object. | ||
1068 | * | ||
1069 | * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() | ||
1070 | * functions to create all instances. When using the | ||
1071 | * FLAC__metadata_object_set_*() functions to set pointers to data, set | ||
1072 | * \a copy to \c true to have the function make it's own copy of the data, or | ||
1073 | * to \c false to give the object ownership of your data. In the latter case | ||
1074 | * your pointer must be freeable by free() and will be free()d when the object | ||
1075 | * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as | ||
1076 | * the data pointer to a FLAC__metadata_object_set_*() function as long as | ||
1077 | * the length argument is 0 and the \a copy argument is \c false. | ||
1078 | * | ||
1079 | * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function | ||
1080 | * will return \c NULL in the case of a memory allocation error, otherwise a new | ||
1081 | * object. The FLAC__metadata_object_set_*() functions return \c false in the | ||
1082 | * case of a memory allocation error. | ||
1083 | * | ||
1084 | * We don't have the convenience of C++ here, so note that the library relies | ||
1085 | * on you to keep the types straight. In other words, if you pass, for | ||
1086 | * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to | ||
1087 | * FLAC__metadata_object_application_set_data(), you will get an assertion | ||
1088 | * failure. | ||
1089 | * | ||
1090 | * For convenience the FLAC__metadata_object_vorbiscomment_*() functions | ||
1091 | * maintain a trailing NUL on each Vorbis comment entry. This is not counted | ||
1092 | * toward the length or stored in the stream, but it can make working with plain | ||
1093 | * comments (those that don't contain embedded-NULs in the value) easier. | ||
1094 | * Entries passed into these functions have trailing NULs added if missing, and | ||
1095 | * returned entries are guaranteed to have a trailing NUL. | ||
1096 | * | ||
1097 | * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis | ||
1098 | * comment entry/name/value will first validate that it complies with the Vorbis | ||
1099 | * comment specification and return false if it does not. | ||
1100 | * | ||
1101 | * There is no need to recalculate the length field on metadata blocks you | ||
1102 | * have modified. They will be calculated automatically before they are | ||
1103 | * written back to a file. | ||
1104 | * | ||
1105 | * \{ | ||
1106 | */ | ||
1107 | |||
1108 | |||
1109 | /** Create a new metadata object instance of the given type. | ||
1110 | * | ||
1111 | * The object will be "empty"; i.e. values and data pointers will be \c 0, | ||
1112 | * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have | ||
1113 | * the vendor string set (but zero comments). | ||
1114 | * | ||
1115 | * Do not pass in a value greater than or equal to | ||
1116 | * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're | ||
1117 | * doing. | ||
1118 | * | ||
1119 | * \param type Type of object to create | ||
1120 | * \retval FLAC__StreamMetadata* | ||
1121 | * \c NULL if there was an error allocating memory or the type code is | ||
1122 | * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. | ||
1123 | */ | ||
1124 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); | ||
1125 | |||
1126 | /** Create a copy of an existing metadata object. | ||
1127 | * | ||
1128 | * The copy is a "deep" copy, i.e. dynamically allocated data within the | ||
1129 | * object is also copied. The caller takes ownership of the new block and | ||
1130 | * is responsible for freeing it with FLAC__metadata_object_delete(). | ||
1131 | * | ||
1132 | * \param object Pointer to object to copy. | ||
1133 | * \assert | ||
1134 | * \code object != NULL \endcode | ||
1135 | * \retval FLAC__StreamMetadata* | ||
1136 | * \c NULL if there was an error allocating memory, else the new instance. | ||
1137 | */ | ||
1138 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); | ||
1139 | |||
1140 | /** Free a metadata object. Deletes the object pointed to by \a object. | ||
1141 | * | ||
1142 | * The delete is a "deep" delete, i.e. dynamically allocated data within the | ||
1143 | * object is also deleted. | ||
1144 | * | ||
1145 | * \param object A pointer to an existing object. | ||
1146 | * \assert | ||
1147 | * \code object != NULL \endcode | ||
1148 | */ | ||
1149 | FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); | ||
1150 | |||
1151 | /** Compares two metadata objects. | ||
1152 | * | ||
1153 | * The compare is "deep", i.e. dynamically allocated data within the | ||
1154 | * object is also compared. | ||
1155 | * | ||
1156 | * \param block1 A pointer to an existing object. | ||
1157 | * \param block2 A pointer to an existing object. | ||
1158 | * \assert | ||
1159 | * \code block1 != NULL \endcode | ||
1160 | * \code block2 != NULL \endcode | ||
1161 | * \retval FLAC__bool | ||
1162 | * \c true if objects are identical, else \c false. | ||
1163 | */ | ||
1164 | FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); | ||
1165 | |||
1166 | /** Sets the application data of an APPLICATION block. | ||
1167 | * | ||
1168 | * If \a copy is \c true, a copy of the data is stored; otherwise, the object | ||
1169 | * takes ownership of the pointer. | ||
1170 | * | ||
1171 | * \param object A pointer to an existing APPLICATION object. | ||
1172 | * \param data A pointer to the data to set. | ||
1173 | * \param length The length of \a data in bytes. | ||
1174 | * \param copy See above. | ||
1175 | * \assert | ||
1176 | * \code object != NULL \endcode | ||
1177 | * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode | ||
1178 | * \code (data != NULL && length > 0) || | ||
1179 | * (data == NULL && length == 0 && copy == false) \endcode | ||
1180 | * \retval FLAC__bool | ||
1181 | * \c false if \a copy is \c true and malloc() fails, else \c true. | ||
1182 | */ | ||
1183 | FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy); | ||
1184 | |||
1185 | /** Resize the seekpoint array. | ||
1186 | * | ||
1187 | * If the size shrinks, elements will truncated; if it grows, new placeholder | ||
1188 | * points will be added to the end. | ||
1189 | * | ||
1190 | * \param object A pointer to an existing SEEKTABLE object. | ||
1191 | * \param new_num_points The desired length of the array; may be \c 0. | ||
1192 | * \assert | ||
1193 | * \code object != NULL \endcode | ||
1194 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1195 | * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || | ||
1196 | * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode | ||
1197 | * \retval FLAC__bool | ||
1198 | * \c false if memory allocation error, else \c true. | ||
1199 | */ | ||
1200 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points); | ||
1201 | |||
1202 | /** Set a seekpoint in a seektable. | ||
1203 | * | ||
1204 | * \param object A pointer to an existing SEEKTABLE object. | ||
1205 | * \param point_num Index into seekpoint array to set. | ||
1206 | * \param point The point to set. | ||
1207 | * \assert | ||
1208 | * \code object != NULL \endcode | ||
1209 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1210 | * \code object->data.seek_table.num_points > point_num \endcode | ||
1211 | */ | ||
1212 | FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); | ||
1213 | |||
1214 | /** Insert a seekpoint into a seektable. | ||
1215 | * | ||
1216 | * \param object A pointer to an existing SEEKTABLE object. | ||
1217 | * \param point_num Index into seekpoint array to set. | ||
1218 | * \param point The point to set. | ||
1219 | * \assert | ||
1220 | * \code object != NULL \endcode | ||
1221 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1222 | * \code object->data.seek_table.num_points >= point_num \endcode | ||
1223 | * \retval FLAC__bool | ||
1224 | * \c false if memory allocation error, else \c true. | ||
1225 | */ | ||
1226 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); | ||
1227 | |||
1228 | /** Delete a seekpoint from a seektable. | ||
1229 | * | ||
1230 | * \param object A pointer to an existing SEEKTABLE object. | ||
1231 | * \param point_num Index into seekpoint array to set. | ||
1232 | * \assert | ||
1233 | * \code object != NULL \endcode | ||
1234 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1235 | * \code object->data.seek_table.num_points > point_num \endcode | ||
1236 | * \retval FLAC__bool | ||
1237 | * \c false if memory allocation error, else \c true. | ||
1238 | */ | ||
1239 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num); | ||
1240 | |||
1241 | /** Check a seektable to see if it conforms to the FLAC specification. | ||
1242 | * See the format specification for limits on the contents of the | ||
1243 | * seektable. | ||
1244 | * | ||
1245 | * \param object A pointer to an existing SEEKTABLE object. | ||
1246 | * \assert | ||
1247 | * \code object != NULL \endcode | ||
1248 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1249 | * \retval FLAC__bool | ||
1250 | * \c false if seek table is illegal, else \c true. | ||
1251 | */ | ||
1252 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); | ||
1253 | |||
1254 | /** Append a number of placeholder points to the end of a seek table. | ||
1255 | * | ||
1256 | * \note | ||
1257 | * As with the other ..._seektable_template_... functions, you should | ||
1258 | * call FLAC__metadata_object_seektable_template_sort() when finished | ||
1259 | * to make the seek table legal. | ||
1260 | * | ||
1261 | * \param object A pointer to an existing SEEKTABLE object. | ||
1262 | * \param num The number of placeholder points to append. | ||
1263 | * \assert | ||
1264 | * \code object != NULL \endcode | ||
1265 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1266 | * \retval FLAC__bool | ||
1267 | * \c false if memory allocation fails, else \c true. | ||
1268 | */ | ||
1269 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num); | ||
1270 | |||
1271 | /** Append a specific seek point template to the end of a seek table. | ||
1272 | * | ||
1273 | * \note | ||
1274 | * As with the other ..._seektable_template_... functions, you should | ||
1275 | * call FLAC__metadata_object_seektable_template_sort() when finished | ||
1276 | * to make the seek table legal. | ||
1277 | * | ||
1278 | * \param object A pointer to an existing SEEKTABLE object. | ||
1279 | * \param sample_number The sample number of the seek point template. | ||
1280 | * \assert | ||
1281 | * \code object != NULL \endcode | ||
1282 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1283 | * \retval FLAC__bool | ||
1284 | * \c false if memory allocation fails, else \c true. | ||
1285 | */ | ||
1286 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); | ||
1287 | |||
1288 | /** Append specific seek point templates to the end of a seek table. | ||
1289 | * | ||
1290 | * \note | ||
1291 | * As with the other ..._seektable_template_... functions, you should | ||
1292 | * call FLAC__metadata_object_seektable_template_sort() when finished | ||
1293 | * to make the seek table legal. | ||
1294 | * | ||
1295 | * \param object A pointer to an existing SEEKTABLE object. | ||
1296 | * \param sample_numbers An array of sample numbers for the seek points. | ||
1297 | * \param num The number of seek point templates to append. | ||
1298 | * \assert | ||
1299 | * \code object != NULL \endcode | ||
1300 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1301 | * \retval FLAC__bool | ||
1302 | * \c false if memory allocation fails, else \c true. | ||
1303 | */ | ||
1304 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num); | ||
1305 | |||
1306 | /** Append a set of evenly-spaced seek point templates to the end of a | ||
1307 | * seek table. | ||
1308 | * | ||
1309 | * \note | ||
1310 | * As with the other ..._seektable_template_... functions, you should | ||
1311 | * call FLAC__metadata_object_seektable_template_sort() when finished | ||
1312 | * to make the seek table legal. | ||
1313 | * | ||
1314 | * \param object A pointer to an existing SEEKTABLE object. | ||
1315 | * \param num The number of placeholder points to append. | ||
1316 | * \param total_samples The total number of samples to be encoded; | ||
1317 | * the seekpoints will be spaced approximately | ||
1318 | * \a total_samples / \a num samples apart. | ||
1319 | * \assert | ||
1320 | * \code object != NULL \endcode | ||
1321 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1322 | * \retval FLAC__bool | ||
1323 | * \c false if memory allocation fails, else \c true. | ||
1324 | */ | ||
1325 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples); | ||
1326 | |||
1327 | /** Sort a seek table's seek points according to the format specification, | ||
1328 | * removing duplicates. | ||
1329 | * | ||
1330 | * \param object A pointer to a seek table to be sorted. | ||
1331 | * \param compact If \c false, behaves like FLAC__format_seektable_sort(). | ||
1332 | * If \c true, duplicates are deleted and the seek table is | ||
1333 | * shrunk appropriately; the number of placeholder points | ||
1334 | * present in the seek table will be the same after the call | ||
1335 | * as before. | ||
1336 | * \assert | ||
1337 | * \code object != NULL \endcode | ||
1338 | * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode | ||
1339 | * \retval FLAC__bool | ||
1340 | * \c false if realloc() fails, else \c true. | ||
1341 | */ | ||
1342 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); | ||
1343 | |||
1344 | /** Sets the vendor string in a VORBIS_COMMENT block. | ||
1345 | * | ||
1346 | * For convenience, a trailing NUL is added to the entry if it doesn't have | ||
1347 | * one already. | ||
1348 | * | ||
1349 | * If \a copy is \c true, a copy of the entry is stored; otherwise, the object | ||
1350 | * takes ownership of the \c entry.entry pointer. | ||
1351 | * | ||
1352 | * \note If this function returns \c false, the caller still owns the | ||
1353 | * pointer. | ||
1354 | * | ||
1355 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1356 | * \param entry The entry to set the vendor string to. | ||
1357 | * \param copy See above. | ||
1358 | * \assert | ||
1359 | * \code object != NULL \endcode | ||
1360 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1361 | * \code (entry.entry != NULL && entry.length > 0) || | ||
1362 | * (entry.entry == NULL && entry.length == 0) \endcode | ||
1363 | * \retval FLAC__bool | ||
1364 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1365 | * Vorbis comment specification, else \c true. | ||
1366 | */ | ||
1367 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); | ||
1368 | |||
1369 | /** Resize the comment array. | ||
1370 | * | ||
1371 | * If the size shrinks, elements will truncated; if it grows, new empty | ||
1372 | * fields will be added to the end. | ||
1373 | * | ||
1374 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1375 | * \param new_num_comments The desired length of the array; may be \c 0. | ||
1376 | * \assert | ||
1377 | * \code object != NULL \endcode | ||
1378 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1379 | * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || | ||
1380 | * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode | ||
1381 | * \retval FLAC__bool | ||
1382 | * \c false if memory allocation fails, else \c true. | ||
1383 | */ | ||
1384 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments); | ||
1385 | |||
1386 | /** Sets a comment in a VORBIS_COMMENT block. | ||
1387 | * | ||
1388 | * For convenience, a trailing NUL is added to the entry if it doesn't have | ||
1389 | * one already. | ||
1390 | * | ||
1391 | * If \a copy is \c true, a copy of the entry is stored; otherwise, the object | ||
1392 | * takes ownership of the \c entry.entry pointer. | ||
1393 | * | ||
1394 | * \note If this function returns \c false, the caller still owns the | ||
1395 | * pointer. | ||
1396 | * | ||
1397 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1398 | * \param comment_num Index into comment array to set. | ||
1399 | * \param entry The entry to set the comment to. | ||
1400 | * \param copy See above. | ||
1401 | * \assert | ||
1402 | * \code object != NULL \endcode | ||
1403 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1404 | * \code comment_num < object->data.vorbis_comment.num_comments \endcode | ||
1405 | * \code (entry.entry != NULL && entry.length > 0) || | ||
1406 | * (entry.entry == NULL && entry.length == 0) \endcode | ||
1407 | * \retval FLAC__bool | ||
1408 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1409 | * Vorbis comment specification, else \c true. | ||
1410 | */ | ||
1411 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); | ||
1412 | |||
1413 | /** Insert a comment in a VORBIS_COMMENT block at the given index. | ||
1414 | * | ||
1415 | * For convenience, a trailing NUL is added to the entry if it doesn't have | ||
1416 | * one already. | ||
1417 | * | ||
1418 | * If \a copy is \c true, a copy of the entry is stored; otherwise, the object | ||
1419 | * takes ownership of the \c entry.entry pointer. | ||
1420 | * | ||
1421 | * \note If this function returns \c false, the caller still owns the | ||
1422 | * pointer. | ||
1423 | * | ||
1424 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1425 | * \param comment_num The index at which to insert the comment. The comments | ||
1426 | * at and after \a comment_num move right one position. | ||
1427 | * To append a comment to the end, set \a comment_num to | ||
1428 | * \c object->data.vorbis_comment.num_comments . | ||
1429 | * \param entry The comment to insert. | ||
1430 | * \param copy See above. | ||
1431 | * \assert | ||
1432 | * \code object != NULL \endcode | ||
1433 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1434 | * \code object->data.vorbis_comment.num_comments >= comment_num \endcode | ||
1435 | * \code (entry.entry != NULL && entry.length > 0) || | ||
1436 | * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode | ||
1437 | * \retval FLAC__bool | ||
1438 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1439 | * Vorbis comment specification, else \c true. | ||
1440 | */ | ||
1441 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); | ||
1442 | |||
1443 | /** Appends a comment to a VORBIS_COMMENT block. | ||
1444 | * | ||
1445 | * For convenience, a trailing NUL is added to the entry if it doesn't have | ||
1446 | * one already. | ||
1447 | * | ||
1448 | * If \a copy is \c true, a copy of the entry is stored; otherwise, the object | ||
1449 | * takes ownership of the \c entry.entry pointer. | ||
1450 | * | ||
1451 | * \note If this function returns \c false, the caller still owns the | ||
1452 | * pointer. | ||
1453 | * | ||
1454 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1455 | * \param entry The comment to insert. | ||
1456 | * \param copy See above. | ||
1457 | * \assert | ||
1458 | * \code object != NULL \endcode | ||
1459 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1460 | * \code (entry.entry != NULL && entry.length > 0) || | ||
1461 | * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode | ||
1462 | * \retval FLAC__bool | ||
1463 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1464 | * Vorbis comment specification, else \c true. | ||
1465 | */ | ||
1466 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); | ||
1467 | |||
1468 | /** Replaces comments in a VORBIS_COMMENT block with a new one. | ||
1469 | * | ||
1470 | * For convenience, a trailing NUL is added to the entry if it doesn't have | ||
1471 | * one already. | ||
1472 | * | ||
1473 | * Depending on the the value of \a all, either all or just the first comment | ||
1474 | * whose field name(s) match the given entry's name will be replaced by the | ||
1475 | * given entry. If no comments match, \a entry will simply be appended. | ||
1476 | * | ||
1477 | * If \a copy is \c true, a copy of the entry is stored; otherwise, the object | ||
1478 | * takes ownership of the \c entry.entry pointer. | ||
1479 | * | ||
1480 | * \note If this function returns \c false, the caller still owns the | ||
1481 | * pointer. | ||
1482 | * | ||
1483 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1484 | * \param entry The comment to insert. | ||
1485 | * \param all If \c true, all comments whose field name matches | ||
1486 | * \a entry's field name will be removed, and \a entry will | ||
1487 | * be inserted at the position of the first matching | ||
1488 | * comment. If \c false, only the first comment whose | ||
1489 | * field name matches \a entry's field name will be | ||
1490 | * replaced with \a entry. | ||
1491 | * \param copy See above. | ||
1492 | * \assert | ||
1493 | * \code object != NULL \endcode | ||
1494 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1495 | * \code (entry.entry != NULL && entry.length > 0) || | ||
1496 | * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode | ||
1497 | * \retval FLAC__bool | ||
1498 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1499 | * Vorbis comment specification, else \c true. | ||
1500 | */ | ||
1501 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); | ||
1502 | |||
1503 | /** Delete a comment in a VORBIS_COMMENT block at the given index. | ||
1504 | * | ||
1505 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1506 | * \param comment_num The index of the comment to delete. | ||
1507 | * \assert | ||
1508 | * \code object != NULL \endcode | ||
1509 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1510 | * \code object->data.vorbis_comment.num_comments > comment_num \endcode | ||
1511 | * \retval FLAC__bool | ||
1512 | * \c false if realloc() fails, else \c true. | ||
1513 | */ | ||
1514 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num); | ||
1515 | |||
1516 | /** Creates a Vorbis comment entry from NUL-terminated name and value strings. | ||
1517 | * | ||
1518 | * On return, the filled-in \a entry->entry pointer will point to malloc()ed | ||
1519 | * memory and shall be owned by the caller. For convenience the entry will | ||
1520 | * have a terminating NUL. | ||
1521 | * | ||
1522 | * \param entry A pointer to a Vorbis comment entry. The entry's | ||
1523 | * \c entry pointer should not point to allocated | ||
1524 | * memory as it will be overwritten. | ||
1525 | * \param field_name The field name in ASCII, \c NUL terminated. | ||
1526 | * \param field_value The field value in UTF-8, \c NUL terminated. | ||
1527 | * \assert | ||
1528 | * \code entry != NULL \endcode | ||
1529 | * \code field_name != NULL \endcode | ||
1530 | * \code field_value != NULL \endcode | ||
1531 | * \retval FLAC__bool | ||
1532 | * \c false if malloc() fails, or if \a field_name or \a field_value does | ||
1533 | * not comply with the Vorbis comment specification, else \c true. | ||
1534 | */ | ||
1535 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); | ||
1536 | |||
1537 | /** Splits a Vorbis comment entry into NUL-terminated name and value strings. | ||
1538 | * | ||
1539 | * The returned pointers to name and value will be allocated by malloc() | ||
1540 | * and shall be owned by the caller. | ||
1541 | * | ||
1542 | * \param entry An existing Vorbis comment entry. | ||
1543 | * \param field_name The address of where the returned pointer to the | ||
1544 | * field name will be stored. | ||
1545 | * \param field_value The address of where the returned pointer to the | ||
1546 | * field value will be stored. | ||
1547 | * \assert | ||
1548 | * \code (entry.entry != NULL && entry.length > 0) \endcode | ||
1549 | * \code memchr(entry.entry, '=', entry.length) != NULL \endcode | ||
1550 | * \code field_name != NULL \endcode | ||
1551 | * \code field_value != NULL \endcode | ||
1552 | * \retval FLAC__bool | ||
1553 | * \c false if memory allocation fails or \a entry does not comply with the | ||
1554 | * Vorbis comment specification, else \c true. | ||
1555 | */ | ||
1556 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); | ||
1557 | |||
1558 | /** Check if the given Vorbis comment entry's field name matches the given | ||
1559 | * field name. | ||
1560 | * | ||
1561 | * \param entry An existing Vorbis comment entry. | ||
1562 | * \param field_name The field name to check. | ||
1563 | * \param field_name_length The length of \a field_name, not including the | ||
1564 | * terminating \c NUL. | ||
1565 | * \assert | ||
1566 | * \code (entry.entry != NULL && entry.length > 0) \endcode | ||
1567 | * \retval FLAC__bool | ||
1568 | * \c true if the field names match, else \c false | ||
1569 | */ | ||
1570 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length); | ||
1571 | |||
1572 | /** Find a Vorbis comment with the given field name. | ||
1573 | * | ||
1574 | * The search begins at entry number \a offset; use an offset of 0 to | ||
1575 | * search from the beginning of the comment array. | ||
1576 | * | ||
1577 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1578 | * \param offset The offset into the comment array from where to start | ||
1579 | * the search. | ||
1580 | * \param field_name The field name of the comment to find. | ||
1581 | * \assert | ||
1582 | * \code object != NULL \endcode | ||
1583 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1584 | * \code field_name != NULL \endcode | ||
1585 | * \retval int | ||
1586 | * The offset in the comment array of the first comment whose field | ||
1587 | * name matches \a field_name, or \c -1 if no match was found. | ||
1588 | */ | ||
1589 | FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name); | ||
1590 | |||
1591 | /** Remove first Vorbis comment matching the given field name. | ||
1592 | * | ||
1593 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1594 | * \param field_name The field name of comment to delete. | ||
1595 | * \assert | ||
1596 | * \code object != NULL \endcode | ||
1597 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1598 | * \retval int | ||
1599 | * \c -1 for memory allocation error, \c 0 for no matching entries, | ||
1600 | * \c 1 for one matching entry deleted. | ||
1601 | */ | ||
1602 | FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); | ||
1603 | |||
1604 | /** Remove all Vorbis comments matching the given field name. | ||
1605 | * | ||
1606 | * \param object A pointer to an existing VORBIS_COMMENT object. | ||
1607 | * \param field_name The field name of comments to delete. | ||
1608 | * \assert | ||
1609 | * \code object != NULL \endcode | ||
1610 | * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode | ||
1611 | * \retval int | ||
1612 | * \c -1 for memory allocation error, \c 0 for no matching entries, | ||
1613 | * else the number of matching entries deleted. | ||
1614 | */ | ||
1615 | FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); | ||
1616 | |||
1617 | /** Create a new CUESHEET track instance. | ||
1618 | * | ||
1619 | * The object will be "empty"; i.e. values and data pointers will be \c 0. | ||
1620 | * | ||
1621 | * \retval FLAC__StreamMetadata_CueSheet_Track* | ||
1622 | * \c NULL if there was an error allocating memory, else the new instance. | ||
1623 | */ | ||
1624 | FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(); | ||
1625 | |||
1626 | /** Create a copy of an existing CUESHEET track object. | ||
1627 | * | ||
1628 | * The copy is a "deep" copy, i.e. dynamically allocated data within the | ||
1629 | * object is also copied. The caller takes ownership of the new object and | ||
1630 | * is responsible for freeing it with | ||
1631 | * FLAC__metadata_object_cuesheet_track_delete(). | ||
1632 | * | ||
1633 | * \param object Pointer to object to copy. | ||
1634 | * \assert | ||
1635 | * \code object != NULL \endcode | ||
1636 | * \retval FLAC__StreamMetadata_CueSheet_Track* | ||
1637 | * \c NULL if there was an error allocating memory, else the new instance. | ||
1638 | */ | ||
1639 | FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); | ||
1640 | |||
1641 | /** Delete a CUESHEET track object | ||
1642 | * | ||
1643 | * \param object A pointer to an existing CUESHEET track object. | ||
1644 | * \assert | ||
1645 | * \code object != NULL \endcode | ||
1646 | */ | ||
1647 | FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); | ||
1648 | |||
1649 | /** Resize a track's index point array. | ||
1650 | * | ||
1651 | * If the size shrinks, elements will truncated; if it grows, new blank | ||
1652 | * indices will be added to the end. | ||
1653 | * | ||
1654 | * \param object A pointer to an existing CUESHEET object. | ||
1655 | * \param track_num The index of the track to modify. NOTE: this is not | ||
1656 | * necessarily the same as the track's \a number field. | ||
1657 | * \param new_num_indices The desired length of the array; may be \c 0. | ||
1658 | * \assert | ||
1659 | * \code object != NULL \endcode | ||
1660 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1661 | * \code object->data.cue_sheet.num_tracks > track_num \endcode | ||
1662 | * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || | ||
1663 | * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode | ||
1664 | * \retval FLAC__bool | ||
1665 | * \c false if memory allocation error, else \c true. | ||
1666 | */ | ||
1667 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices); | ||
1668 | |||
1669 | /** Insert an index point in a CUESHEET track at the given index. | ||
1670 | * | ||
1671 | * \param object A pointer to an existing CUESHEET object. | ||
1672 | * \param track_num The index of the track to modify. NOTE: this is not | ||
1673 | * necessarily the same as the track's \a number field. | ||
1674 | * \param index_num The index into the track's index array at which to | ||
1675 | * insert the index point. NOTE: this is not necessarily | ||
1676 | * the same as the index point's \a number field. The | ||
1677 | * indices at and after \a index_num move right one | ||
1678 | * position. To append an index point to the end, set | ||
1679 | * \a index_num to | ||
1680 | * \c object->data.cue_sheet.tracks[track_num].num_indices . | ||
1681 | * \param index The index point to insert. | ||
1682 | * \assert | ||
1683 | * \code object != NULL \endcode | ||
1684 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1685 | * \code object->data.cue_sheet.num_tracks > track_num \endcode | ||
1686 | * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode | ||
1687 | * \retval FLAC__bool | ||
1688 | * \c false if realloc() fails, else \c true. | ||
1689 | */ | ||
1690 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index); | ||
1691 | |||
1692 | /** Insert a blank index point in a CUESHEET track at the given index. | ||
1693 | * | ||
1694 | * A blank index point is one in which all field values are zero. | ||
1695 | * | ||
1696 | * \param object A pointer to an existing CUESHEET object. | ||
1697 | * \param track_num The index of the track to modify. NOTE: this is not | ||
1698 | * necessarily the same as the track's \a number field. | ||
1699 | * \param index_num The index into the track's index array at which to | ||
1700 | * insert the index point. NOTE: this is not necessarily | ||
1701 | * the same as the index point's \a number field. The | ||
1702 | * indices at and after \a index_num move right one | ||
1703 | * position. To append an index point to the end, set | ||
1704 | * \a index_num to | ||
1705 | * \c object->data.cue_sheet.tracks[track_num].num_indices . | ||
1706 | * \assert | ||
1707 | * \code object != NULL \endcode | ||
1708 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1709 | * \code object->data.cue_sheet.num_tracks > track_num \endcode | ||
1710 | * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode | ||
1711 | * \retval FLAC__bool | ||
1712 | * \c false if realloc() fails, else \c true. | ||
1713 | */ | ||
1714 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); | ||
1715 | |||
1716 | /** Delete an index point in a CUESHEET track at the given index. | ||
1717 | * | ||
1718 | * \param object A pointer to an existing CUESHEET object. | ||
1719 | * \param track_num The index into the track array of the track to | ||
1720 | * modify. NOTE: this is not necessarily the same | ||
1721 | * as the track's \a number field. | ||
1722 | * \param index_num The index into the track's index array of the index | ||
1723 | * to delete. NOTE: this is not necessarily the same | ||
1724 | * as the index's \a number field. | ||
1725 | * \assert | ||
1726 | * \code object != NULL \endcode | ||
1727 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1728 | * \code object->data.cue_sheet.num_tracks > track_num \endcode | ||
1729 | * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode | ||
1730 | * \retval FLAC__bool | ||
1731 | * \c false if realloc() fails, else \c true. | ||
1732 | */ | ||
1733 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); | ||
1734 | |||
1735 | /** Resize the track array. | ||
1736 | * | ||
1737 | * If the size shrinks, elements will truncated; if it grows, new blank | ||
1738 | * tracks will be added to the end. | ||
1739 | * | ||
1740 | * \param object A pointer to an existing CUESHEET object. | ||
1741 | * \param new_num_tracks The desired length of the array; may be \c 0. | ||
1742 | * \assert | ||
1743 | * \code object != NULL \endcode | ||
1744 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1745 | * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || | ||
1746 | * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode | ||
1747 | * \retval FLAC__bool | ||
1748 | * \c false if memory allocation error, else \c true. | ||
1749 | */ | ||
1750 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks); | ||
1751 | |||
1752 | /** Sets a track in a CUESHEET block. | ||
1753 | * | ||
1754 | * If \a copy is \c true, a copy of the track is stored; otherwise, the object | ||
1755 | * takes ownership of the \a track pointer. | ||
1756 | * | ||
1757 | * \param object A pointer to an existing CUESHEET object. | ||
1758 | * \param track_num Index into track array to set. NOTE: this is not | ||
1759 | * necessarily the same as the track's \a number field. | ||
1760 | * \param track The track to set the track to. You may safely pass in | ||
1761 | * a const pointer if \a copy is \c true. | ||
1762 | * \param copy See above. | ||
1763 | * \assert | ||
1764 | * \code object != NULL \endcode | ||
1765 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1766 | * \code track_num < object->data.cue_sheet.num_tracks \endcode | ||
1767 | * \code (track->indices != NULL && track->num_indices > 0) || | ||
1768 | * (track->indices == NULL && track->num_indices == 0) | ||
1769 | * \retval FLAC__bool | ||
1770 | * \c false if \a copy is \c true and malloc() fails, else \c true. | ||
1771 | */ | ||
1772 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); | ||
1773 | |||
1774 | /** Insert a track in a CUESHEET block at the given index. | ||
1775 | * | ||
1776 | * If \a copy is \c true, a copy of the track is stored; otherwise, the object | ||
1777 | * takes ownership of the \a track pointer. | ||
1778 | * | ||
1779 | * \param object A pointer to an existing CUESHEET object. | ||
1780 | * \param track_num The index at which to insert the track. NOTE: this | ||
1781 | * is not necessarily the same as the track's \a number | ||
1782 | * field. The tracks at and after \a track_num move right | ||
1783 | * one position. To append a track to the end, set | ||
1784 | * \a track_num to \c object->data.cue_sheet.num_tracks . | ||
1785 | * \param track The track to insert. You may safely pass in a const | ||
1786 | * pointer if \a copy is \c true. | ||
1787 | * \param copy See above. | ||
1788 | * \assert | ||
1789 | * \code object != NULL \endcode | ||
1790 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1791 | * \code object->data.cue_sheet.num_tracks >= track_num \endcode | ||
1792 | * \retval FLAC__bool | ||
1793 | * \c false if \a copy is \c true and malloc() fails, else \c true. | ||
1794 | */ | ||
1795 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); | ||
1796 | |||
1797 | /** Insert a blank track in a CUESHEET block at the given index. | ||
1798 | * | ||
1799 | * A blank track is one in which all field values are zero. | ||
1800 | * | ||
1801 | * \param object A pointer to an existing CUESHEET object. | ||
1802 | * \param track_num The index at which to insert the track. NOTE: this | ||
1803 | * is not necessarily the same as the track's \a number | ||
1804 | * field. The tracks at and after \a track_num move right | ||
1805 | * one position. To append a track to the end, set | ||
1806 | * \a track_num to \c object->data.cue_sheet.num_tracks . | ||
1807 | * \assert | ||
1808 | * \code object != NULL \endcode | ||
1809 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1810 | * \code object->data.cue_sheet.num_tracks >= track_num \endcode | ||
1811 | * \retval FLAC__bool | ||
1812 | * \c false if \a copy is \c true and malloc() fails, else \c true. | ||
1813 | */ | ||
1814 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num); | ||
1815 | |||
1816 | /** Delete a track in a CUESHEET block at the given index. | ||
1817 | * | ||
1818 | * \param object A pointer to an existing CUESHEET object. | ||
1819 | * \param track_num The index into the track array of the track to | ||
1820 | * delete. NOTE: this is not necessarily the same | ||
1821 | * as the track's \a number field. | ||
1822 | * \assert | ||
1823 | * \code object != NULL \endcode | ||
1824 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1825 | * \code object->data.cue_sheet.num_tracks > track_num \endcode | ||
1826 | * \retval FLAC__bool | ||
1827 | * \c false if realloc() fails, else \c true. | ||
1828 | */ | ||
1829 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num); | ||
1830 | |||
1831 | /** Check a cue sheet to see if it conforms to the FLAC specification. | ||
1832 | * See the format specification for limits on the contents of the | ||
1833 | * cue sheet. | ||
1834 | * | ||
1835 | * \param object A pointer to an existing CUESHEET object. | ||
1836 | * \param check_cd_da_subset If \c true, check CUESHEET against more | ||
1837 | * stringent requirements for a CD-DA (audio) disc. | ||
1838 | * \param violation Address of a pointer to a string. If there is a | ||
1839 | * violation, a pointer to a string explanation of the | ||
1840 | * violation will be returned here. \a violation may be | ||
1841 | * \c NULL if you don't need the returned string. Do not | ||
1842 | * free the returned string; it will always point to static | ||
1843 | * data. | ||
1844 | * \assert | ||
1845 | * \code object != NULL \endcode | ||
1846 | * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode | ||
1847 | * \retval FLAC__bool | ||
1848 | * \c false if cue sheet is illegal, else \c true. | ||
1849 | */ | ||
1850 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); | ||
1851 | |||
1852 | /* \} */ | ||
1853 | |||
1854 | #ifdef __cplusplus | ||
1855 | } | ||
1856 | #endif | ||
1857 | |||
1858 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/ordinals.h b/apps/codecs/libFLAC/include/FLAC/ordinals.h new file mode 100644 index 0000000000..10bc25d5f1 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/ordinals.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__ORDINALS_H | ||
33 | #define FLAC__ORDINALS_H | ||
34 | |||
35 | #ifndef _MSC_VER | ||
36 | #include <inttypes.h> | ||
37 | #endif | ||
38 | |||
39 | typedef signed char FLAC__int8; | ||
40 | typedef unsigned char FLAC__uint8; | ||
41 | |||
42 | #if defined _MSC_VER | ||
43 | typedef __int16 FLAC__int16; | ||
44 | typedef __int32 FLAC__int32; | ||
45 | typedef __int64 FLAC__int64; | ||
46 | typedef unsigned __int16 FLAC__uint16; | ||
47 | typedef unsigned __int32 FLAC__uint32; | ||
48 | typedef unsigned __int64 FLAC__uint64; | ||
49 | #else | ||
50 | typedef int16_t FLAC__int16; | ||
51 | typedef int32_t FLAC__int32; | ||
52 | typedef int64_t FLAC__int64; | ||
53 | typedef uint16_t FLAC__uint16; | ||
54 | typedef uint32_t FLAC__uint32; | ||
55 | typedef uint64_t FLAC__uint64; | ||
56 | #endif | ||
57 | |||
58 | typedef int FLAC__bool; | ||
59 | |||
60 | typedef FLAC__uint8 FLAC__byte; | ||
61 | |||
62 | #ifdef true | ||
63 | #undef true | ||
64 | #endif | ||
65 | #ifdef false | ||
66 | #undef false | ||
67 | #endif | ||
68 | #ifndef __cplusplus | ||
69 | #define true 1 | ||
70 | #define false 0 | ||
71 | #endif | ||
72 | |||
73 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/seekable_stream_decoder.h b/apps/codecs/libFLAC/include/FLAC/seekable_stream_decoder.h new file mode 100644 index 0000000000..dee5a89cef --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/seekable_stream_decoder.h | |||
@@ -0,0 +1,931 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__SEEKABLE_STREAM_DECODER_H | ||
33 | #define FLAC__SEEKABLE_STREAM_DECODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "stream_decoder.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /** \file include/FLAC/seekable_stream_decoder.h | ||
44 | * | ||
45 | * \brief | ||
46 | * This module contains the functions which implement the seekable stream | ||
47 | * decoder. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_seekable_stream_decoder seekable stream decoder \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_seekable_stream_decoder FLAC/seekable_stream_decoder.h: seekable stream decoder interface | ||
54 | * \ingroup flac_decoder | ||
55 | * | ||
56 | * \brief | ||
57 | * This module contains the functions which implement the seekable stream | ||
58 | * decoder. | ||
59 | * | ||
60 | * The basic usage of this decoder is as follows: | ||
61 | * - The program creates an instance of a decoder using | ||
62 | * FLAC__seekable_stream_decoder_new(). | ||
63 | * - The program overrides the default settings and sets callbacks for | ||
64 | * reading, writing, seeking, error reporting, and metadata reporting | ||
65 | * using FLAC__seekable_stream_decoder_set_*() functions. | ||
66 | * - The program initializes the instance to validate the settings and | ||
67 | * prepare for decoding using FLAC__seekable_stream_decoder_init(). | ||
68 | * - The program calls the FLAC__seekable_stream_decoder_process_*() | ||
69 | * functions to decode data, which subsequently calls the callbacks. | ||
70 | * - The program finishes the decoding with | ||
71 | * FLAC__seekable_stream_decoder_finish(), which flushes the input and | ||
72 | * output and resets the decoder to the uninitialized state. | ||
73 | * - The instance may be used again or deleted with | ||
74 | * FLAC__seekable_stream_decoder_delete(). | ||
75 | * | ||
76 | * The seekable stream decoder is a wrapper around the | ||
77 | * \link flac_stream_decoder stream decoder \endlink which also provides | ||
78 | * seeking capability. In addition to the Read/Write/Metadata/Error | ||
79 | * callbacks of the stream decoder, the user must also provide the following: | ||
80 | * | ||
81 | * - Seek callback - This function will be called when the decoder wants to | ||
82 | * seek to an absolute position in the stream. | ||
83 | * - Tell callback - This function will be called when the decoder wants to | ||
84 | * know the current absolute position of the stream. | ||
85 | * - Length callback - This function will be called when the decoder wants | ||
86 | * to know length of the stream. The seeking algorithm currently requires | ||
87 | * that the overall stream length be known. | ||
88 | * - EOF callback - This function will be called when the decoder wants to | ||
89 | * know if it is at the end of the stream. This could be synthesized from | ||
90 | * the tell and length callbacks but it may be more expensive that way, so | ||
91 | * there is a separate callback for it. | ||
92 | * | ||
93 | * Seeking is exposed through the | ||
94 | * FLAC__seekable_stream_decoder_seek_absolute() method. At any point after | ||
95 | * the seekable stream decoder has been initialized, the user can call this | ||
96 | * function to seek to an exact sample within the stream. Subsequently, the | ||
97 | * first time the write callback is called it will be passed a (possibly | ||
98 | * partial) block starting at that sample. | ||
99 | * | ||
100 | * The seekable stream decoder also provides MD5 signature checking. If | ||
101 | * this is turned on before initialization, | ||
102 | * FLAC__seekable_stream_decoder_finish() will report when the decoded MD5 | ||
103 | * signature does not match the one stored in the STREAMINFO block. MD5 | ||
104 | * checking is automatically turned off (until the next | ||
105 | * FLAC__seekable_stream_decoder_reset()) if there is no signature in the | ||
106 | * STREAMINFO block or when a seek is attempted. | ||
107 | * | ||
108 | * Make sure to read the detailed description of the | ||
109 | * \link flac_stream_decoder stream decoder module \endlink since the | ||
110 | * seekable stream decoder inherits much of its behavior. | ||
111 | * | ||
112 | * \note | ||
113 | * The "set" functions may only be called when the decoder is in the | ||
114 | * state FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED, i.e. after | ||
115 | * FLAC__seekable_stream_decoder_new() or | ||
116 | * FLAC__seekable_stream_decoder_finish(), but before | ||
117 | * FLAC__seekable_stream_decoder_init(). If this is the case they will | ||
118 | * return \c true, otherwise \c false. | ||
119 | * | ||
120 | * \note | ||
121 | * FLAC__stream_decoder_finish() resets all settings to the constructor | ||
122 | * defaults, including the callbacks. | ||
123 | * | ||
124 | * \{ | ||
125 | */ | ||
126 | |||
127 | |||
128 | /** State values for a FLAC__SeekableStreamDecoder | ||
129 | * | ||
130 | * The decoder's state can be obtained by calling FLAC__seekable_stream_decoder_get_state(). | ||
131 | */ | ||
132 | typedef enum { | ||
133 | |||
134 | FLAC__SEEKABLE_STREAM_DECODER_OK = 0, | ||
135 | /**< The decoder is in the normal OK state. */ | ||
136 | |||
137 | FLAC__SEEKABLE_STREAM_DECODER_SEEKING, | ||
138 | /**< The decoder is in the process of seeking. */ | ||
139 | |||
140 | FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM, | ||
141 | /**< The decoder has reached the end of the stream. */ | ||
142 | |||
143 | FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR, | ||
144 | /**< An error occurred allocating memory. */ | ||
145 | |||
146 | FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR, | ||
147 | /**< An error occurred in the underlying stream decoder. */ | ||
148 | |||
149 | FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR, | ||
150 | /**< The read callback returned an error. */ | ||
151 | |||
152 | FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR, | ||
153 | /**< An error occurred while seeking or the seek or tell | ||
154 | * callback returned an error. | ||
155 | */ | ||
156 | |||
157 | FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED, | ||
158 | /**< FLAC__seekable_stream_decoder_init() was called when the | ||
159 | * decoder was already initialized, usually because | ||
160 | * FLAC__seekable_stream_decoder_finish() was not called. | ||
161 | */ | ||
162 | |||
163 | FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK, | ||
164 | /**< FLAC__seekable_stream_decoder_init() was called without all | ||
165 | * callbacks being set. | ||
166 | */ | ||
167 | |||
168 | FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED | ||
169 | /**< The decoder is in the uninitialized state. */ | ||
170 | |||
171 | } FLAC__SeekableStreamDecoderState; | ||
172 | |||
173 | /** Maps a FLAC__SeekableStreamDecoderState to a C string. | ||
174 | * | ||
175 | * Using a FLAC__SeekableStreamDecoderState as the index to this array | ||
176 | * will give the string equivalent. The contents should not be modified. | ||
177 | */ | ||
178 | extern FLAC_API const char * const FLAC__SeekableStreamDecoderStateString[]; | ||
179 | |||
180 | |||
181 | /** Return values for the FLAC__SeekableStreamDecoder read callback. | ||
182 | */ | ||
183 | typedef enum { | ||
184 | |||
185 | FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK, | ||
186 | /**< The read was OK and decoding can continue. */ | ||
187 | |||
188 | FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR | ||
189 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
190 | |||
191 | } FLAC__SeekableStreamDecoderReadStatus; | ||
192 | |||
193 | /** Maps a FLAC__SeekableStreamDecoderReadStatus to a C string. | ||
194 | * | ||
195 | * Using a FLAC__SeekableStreamDecoderReadStatus as the index to this array | ||
196 | * will give the string equivalent. The contents should not be modified. | ||
197 | */ | ||
198 | extern FLAC_API const char * const FLAC__SeekableStreamDecoderReadStatusString[]; | ||
199 | |||
200 | |||
201 | /** Return values for the FLAC__SeekableStreamDecoder seek callback. | ||
202 | */ | ||
203 | typedef enum { | ||
204 | |||
205 | FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK, | ||
206 | /**< The seek was OK and decoding can continue. */ | ||
207 | |||
208 | FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR | ||
209 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
210 | |||
211 | } FLAC__SeekableStreamDecoderSeekStatus; | ||
212 | |||
213 | /** Maps a FLAC__SeekableStreamDecoderSeekStatus to a C string. | ||
214 | * | ||
215 | * Using a FLAC__SeekableStreamDecoderSeekStatus as the index to this array | ||
216 | * will give the string equivalent. The contents should not be modified. | ||
217 | */ | ||
218 | extern FLAC_API const char * const FLAC__SeekableStreamDecoderSeekStatusString[]; | ||
219 | |||
220 | |||
221 | /** Return values for the FLAC__SeekableStreamDecoder tell callback. | ||
222 | */ | ||
223 | typedef enum { | ||
224 | |||
225 | FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK, | ||
226 | /**< The tell was OK and decoding can continue. */ | ||
227 | |||
228 | FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR | ||
229 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
230 | |||
231 | } FLAC__SeekableStreamDecoderTellStatus; | ||
232 | |||
233 | /** Maps a FLAC__SeekableStreamDecoderTellStatus to a C string. | ||
234 | * | ||
235 | * Using a FLAC__SeekableStreamDecoderTellStatus as the index to this array | ||
236 | * will give the string equivalent. The contents should not be modified. | ||
237 | */ | ||
238 | extern FLAC_API const char * const FLAC__SeekableStreamDecoderTellStatusString[]; | ||
239 | |||
240 | |||
241 | /** Return values for the FLAC__SeekableStreamDecoder length callback. | ||
242 | */ | ||
243 | typedef enum { | ||
244 | |||
245 | FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK, | ||
246 | /**< The length call was OK and decoding can continue. */ | ||
247 | |||
248 | FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR | ||
249 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
250 | |||
251 | } FLAC__SeekableStreamDecoderLengthStatus; | ||
252 | |||
253 | /** Maps a FLAC__SeekableStreamDecoderLengthStatus to a C string. | ||
254 | * | ||
255 | * Using a FLAC__SeekableStreamDecoderLengthStatus as the index to this array | ||
256 | * will give the string equivalent. The contents should not be modified. | ||
257 | */ | ||
258 | extern FLAC_API const char * const FLAC__SeekableStreamDecoderLengthStatusString[]; | ||
259 | |||
260 | |||
261 | /*********************************************************************** | ||
262 | * | ||
263 | * class FLAC__SeekableStreamDecoder : public FLAC__StreamDecoder | ||
264 | * | ||
265 | ***********************************************************************/ | ||
266 | |||
267 | struct FLAC__SeekableStreamDecoderProtected; | ||
268 | struct FLAC__SeekableStreamDecoderPrivate; | ||
269 | /** The opaque structure definition for the seekable stream decoder type. | ||
270 | * See the | ||
271 | * \link flac_seekable_stream_decoder seekable stream decoder module \endlink | ||
272 | * for a detailed description. | ||
273 | */ | ||
274 | typedef struct { | ||
275 | struct FLAC__SeekableStreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
276 | struct FLAC__SeekableStreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
277 | } FLAC__SeekableStreamDecoder; | ||
278 | |||
279 | /** Signature for the read callback. | ||
280 | * See FLAC__seekable_stream_decoder_set_read_callback() | ||
281 | * and FLAC__StreamDecoderReadCallback for more info. | ||
282 | * | ||
283 | * \param decoder The decoder instance calling the callback. | ||
284 | * \param buffer A pointer to a location for the callee to store | ||
285 | * data to be decoded. | ||
286 | * \param bytes A pointer to the size of the buffer. | ||
287 | * \param client_data The callee's client data set through | ||
288 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
289 | * \retval FLAC__SeekableStreamDecoderReadStatus | ||
290 | * The callee's return status. | ||
291 | */ | ||
292 | typedef FLAC__SeekableStreamDecoderReadStatus (*FLAC__SeekableStreamDecoderReadCallback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
293 | |||
294 | /** Signature for the seek callback. | ||
295 | * See FLAC__seekable_stream_decoder_set_seek_callback() for more info. | ||
296 | * | ||
297 | * \param decoder The decoder instance calling the callback. | ||
298 | * \param absolute_byte_offset The offset from the beginning of the stream | ||
299 | * to seek to. | ||
300 | * \param client_data The callee's client data set through | ||
301 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
302 | * \retval FLAC__SeekableStreamDecoderSeekStatus | ||
303 | * The callee's return status. | ||
304 | */ | ||
305 | typedef FLAC__SeekableStreamDecoderSeekStatus (*FLAC__SeekableStreamDecoderSeekCallback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
306 | |||
307 | /** Signature for the tell callback. | ||
308 | * See FLAC__seekable_stream_decoder_set_tell_callback() for more info. | ||
309 | * | ||
310 | * \param decoder The decoder instance calling the callback. | ||
311 | * \param absolute_byte_offset A pointer to storage for the current offset | ||
312 | * from the beginning of the stream. | ||
313 | * \param client_data The callee's client data set through | ||
314 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
315 | * \retval FLAC__SeekableStreamDecoderTellStatus | ||
316 | * The callee's return status. | ||
317 | */ | ||
318 | typedef FLAC__SeekableStreamDecoderTellStatus (*FLAC__SeekableStreamDecoderTellCallback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
319 | |||
320 | /** Signature for the length callback. | ||
321 | * See FLAC__seekable_stream_decoder_set_length_callback() for more info. | ||
322 | * | ||
323 | * \param decoder The decoder instance calling the callback. | ||
324 | * \param stream_length A pointer to storage for the length of the stream | ||
325 | * in bytes. | ||
326 | * \param client_data The callee's client data set through | ||
327 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
328 | * \retval FLAC__SeekableStreamDecoderLengthStatus | ||
329 | * The callee's return status. | ||
330 | */ | ||
331 | typedef FLAC__SeekableStreamDecoderLengthStatus (*FLAC__SeekableStreamDecoderLengthCallback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); | ||
332 | |||
333 | /** Signature for the EOF callback. | ||
334 | * See FLAC__seekable_stream_decoder_set_eof_callback() for more info. | ||
335 | * | ||
336 | * \param decoder The decoder instance calling the callback. | ||
337 | * \param client_data The callee's client data set through | ||
338 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
339 | * \retval FLAC__bool | ||
340 | * \c true if the currently at the end of the stream, else \c false. | ||
341 | */ | ||
342 | typedef FLAC__bool (*FLAC__SeekableStreamDecoderEofCallback)(const FLAC__SeekableStreamDecoder *decoder, void *client_data); | ||
343 | |||
344 | /** Signature for the write callback. | ||
345 | * See FLAC__seekable_stream_decoder_set_write_callback() | ||
346 | * and FLAC__StreamDecoderWriteCallback for more info. | ||
347 | * | ||
348 | * \param decoder The decoder instance calling the callback. | ||
349 | * \param frame The description of the decoded frame. | ||
350 | * \param buffer An array of pointers to decoded channels of data. | ||
351 | * \param client_data The callee's client data set through | ||
352 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
353 | * \retval FLAC__StreamDecoderWriteStatus | ||
354 | * The callee's return status. | ||
355 | */ | ||
356 | typedef FLAC__StreamDecoderWriteStatus (*FLAC__SeekableStreamDecoderWriteCallback)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
357 | |||
358 | /** Signature for the metadata callback. | ||
359 | * See FLAC__seekable_stream_decoder_set_metadata_callback() | ||
360 | * and FLAC__StreamDecoderMetadataCallback for more info. | ||
361 | * | ||
362 | * \param decoder The decoder instance calling the callback. | ||
363 | * \param metadata The decoded metadata block. | ||
364 | * \param client_data The callee's client data set through | ||
365 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
366 | */ | ||
367 | typedef void (*FLAC__SeekableStreamDecoderMetadataCallback)(const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
368 | |||
369 | /** Signature for the error callback. | ||
370 | * See FLAC__seekable_stream_decoder_set_error_callback() | ||
371 | * and FLAC__StreamDecoderErrorCallback for more info. | ||
372 | * | ||
373 | * \param decoder The decoder instance calling the callback. | ||
374 | * \param status The error encountered by the decoder. | ||
375 | * \param client_data The callee's client data set through | ||
376 | * FLAC__seekable_stream_decoder_set_client_data(). | ||
377 | */ | ||
378 | typedef void (*FLAC__SeekableStreamDecoderErrorCallback)(const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
379 | |||
380 | |||
381 | /*********************************************************************** | ||
382 | * | ||
383 | * Class constructor/destructor | ||
384 | * | ||
385 | ***********************************************************************/ | ||
386 | |||
387 | /** Create a new seekable stream decoder instance. The instance is created | ||
388 | * with default settings; see the individual | ||
389 | * FLAC__seekable_stream_decoder_set_*() functions for each setting's | ||
390 | * default. | ||
391 | * | ||
392 | * \retval FLAC__SeekableStreamDecoder* | ||
393 | * \c NULL if there was an error allocating memory, else the new instance. | ||
394 | */ | ||
395 | FLAC_API FLAC__SeekableStreamDecoder *FLAC__seekable_stream_decoder_new(); | ||
396 | |||
397 | /** Free a decoder instance. Deletes the object pointed to by \a decoder. | ||
398 | * | ||
399 | * \param decoder A pointer to an existing decoder. | ||
400 | * \assert | ||
401 | * \code decoder != NULL \endcode | ||
402 | */ | ||
403 | FLAC_API void FLAC__seekable_stream_decoder_delete(FLAC__SeekableStreamDecoder *decoder); | ||
404 | |||
405 | |||
406 | /*********************************************************************** | ||
407 | * | ||
408 | * Public class method prototypes | ||
409 | * | ||
410 | ***********************************************************************/ | ||
411 | |||
412 | /** Set the "MD5 signature checking" flag. If \c true, the decoder will | ||
413 | * compute the MD5 signature of the unencoded audio data while decoding | ||
414 | * and compare it to the signature from the STREAMINFO block, if it | ||
415 | * exists, during FLAC__seekable_stream_decoder_finish(). | ||
416 | * | ||
417 | * MD5 signature checking will be turned off (until the next | ||
418 | * FLAC__seekable_stream_decoder_reset()) if there is no signature in | ||
419 | * the STREAMINFO block or when a seek is attempted. | ||
420 | * | ||
421 | * \default \c false | ||
422 | * \param decoder A decoder instance to set. | ||
423 | * \param value Flag value (see above). | ||
424 | * \assert | ||
425 | * \code decoder != NULL \endcode | ||
426 | * \retval FLAC__bool | ||
427 | * \c false if the decoder is already initialized, else \c true. | ||
428 | */ | ||
429 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_md5_checking(FLAC__SeekableStreamDecoder *decoder, FLAC__bool value); | ||
430 | |||
431 | /** Set the read callback. | ||
432 | * This is inherited from FLAC__StreamDecoder; see | ||
433 | * FLAC__stream_decoder_set_read_callback(). | ||
434 | * | ||
435 | * \note | ||
436 | * The callback is mandatory and must be set before initialization. | ||
437 | * | ||
438 | * \default \c NULL | ||
439 | * \param decoder A decoder instance to set. | ||
440 | * \param value See above. | ||
441 | * \assert | ||
442 | * \code decoder != NULL \endcode | ||
443 | * \code value != NULL \endcode | ||
444 | * \retval FLAC__bool | ||
445 | * \c false if the decoder is already initialized, else \c true. | ||
446 | */ | ||
447 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_read_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderReadCallback value); | ||
448 | |||
449 | /** Set the seek callback. | ||
450 | * The supplied function will be called when the decoder needs to seek | ||
451 | * the input stream. The decoder will pass the absolute byte offset | ||
452 | * to seek to, 0 meaning the beginning of the stream. | ||
453 | * | ||
454 | * \note | ||
455 | * The callback is mandatory and must be set before initialization. | ||
456 | * | ||
457 | * \default \c NULL | ||
458 | * \param decoder A decoder instance to set. | ||
459 | * \param value See above. | ||
460 | * \assert | ||
461 | * \code decoder != NULL \endcode | ||
462 | * \code value != NULL \endcode | ||
463 | * \retval FLAC__bool | ||
464 | * \c false if the decoder is already initialized, else \c true. | ||
465 | */ | ||
466 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_seek_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderSeekCallback value); | ||
467 | |||
468 | /** Set the tell callback. | ||
469 | * The supplied function will be called when the decoder wants to know | ||
470 | * the current position of the stream. The callback should return the | ||
471 | * byte offset from the beginning of the stream. | ||
472 | * | ||
473 | * \note | ||
474 | * The callback is mandatory and must be set before initialization. | ||
475 | * | ||
476 | * \default \c NULL | ||
477 | * \param decoder A decoder instance to set. | ||
478 | * \param value See above. | ||
479 | * \assert | ||
480 | * \code decoder != NULL \endcode | ||
481 | * \code value != NULL \endcode | ||
482 | * \retval FLAC__bool | ||
483 | * \c false if the decoder is already initialized, else \c true. | ||
484 | */ | ||
485 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_tell_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderTellCallback value); | ||
486 | |||
487 | /** Set the length callback. | ||
488 | * The supplied function will be called when the decoder wants to know | ||
489 | * the total length of the stream in bytes. | ||
490 | * | ||
491 | * \note | ||
492 | * The callback is mandatory and must be set before initialization. | ||
493 | * | ||
494 | * \default \c NULL | ||
495 | * \param decoder A decoder instance to set. | ||
496 | * \param value See above. | ||
497 | * \assert | ||
498 | * \code decoder != NULL \endcode | ||
499 | * \code value != NULL \endcode | ||
500 | * \retval FLAC__bool | ||
501 | * \c false if the decoder is already initialized, else \c true. | ||
502 | */ | ||
503 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_length_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderLengthCallback value); | ||
504 | |||
505 | /** Set the eof callback. | ||
506 | * The supplied function will be called when the decoder needs to know | ||
507 | * if the end of the stream has been reached. | ||
508 | * | ||
509 | * \note | ||
510 | * The callback is mandatory and must be set before initialization. | ||
511 | * | ||
512 | * \default \c NULL | ||
513 | * \param decoder A decoder instance to set. | ||
514 | * \param value See above. | ||
515 | * \assert | ||
516 | * \code decoder != NULL \endcode | ||
517 | * \code value != NULL \endcode | ||
518 | * \retval FLAC__bool | ||
519 | * \c false if the decoder is already initialized, else \c true. | ||
520 | */ | ||
521 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderEofCallback value); | ||
522 | |||
523 | /** Set the write callback. | ||
524 | * This is inherited from FLAC__StreamDecoder; see | ||
525 | * FLAC__stream_decoder_set_write_callback(). | ||
526 | * | ||
527 | * \note | ||
528 | * The callback is mandatory and must be set before initialization. | ||
529 | * | ||
530 | * \default \c NULL | ||
531 | * \param decoder A decoder instance to set. | ||
532 | * \param value See above. | ||
533 | * \assert | ||
534 | * \code decoder != NULL \endcode | ||
535 | * \code value != NULL \endcode | ||
536 | * \retval FLAC__bool | ||
537 | * \c false if the decoder is already initialized, else \c true. | ||
538 | */ | ||
539 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderWriteCallback value); | ||
540 | |||
541 | /** Set the metadata callback. | ||
542 | * This is inherited from FLAC__StreamDecoder; see | ||
543 | * FLAC__stream_decoder_set_metadata_callback(). | ||
544 | * | ||
545 | * \note | ||
546 | * The callback is mandatory and must be set before initialization. | ||
547 | * | ||
548 | * \default \c NULL | ||
549 | * \param decoder A decoder instance to set. | ||
550 | * \param value See above. | ||
551 | * \assert | ||
552 | * \code decoder != NULL \endcode | ||
553 | * \code value != NULL \endcode | ||
554 | * \retval FLAC__bool | ||
555 | * \c false if the decoder is already initialized, else \c true. | ||
556 | */ | ||
557 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderMetadataCallback value); | ||
558 | |||
559 | /** Set the error callback. | ||
560 | * This is inherited from FLAC__StreamDecoder; see | ||
561 | * FLAC__stream_decoder_set_error_callback(). | ||
562 | * | ||
563 | * \note | ||
564 | * The callback is mandatory and must be set before initialization. | ||
565 | * | ||
566 | * \default \c NULL | ||
567 | * \param decoder A decoder instance to set. | ||
568 | * \param value See above. | ||
569 | * \assert | ||
570 | * \code decoder != NULL \endcode | ||
571 | * \code value != NULL \endcode | ||
572 | * \retval FLAC__bool | ||
573 | * \c false if the decoder is already initialized, else \c true. | ||
574 | */ | ||
575 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_error_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderErrorCallback value); | ||
576 | |||
577 | /** Set the client data to be passed back to callbacks. | ||
578 | * This value will be supplied to callbacks in their \a client_data | ||
579 | * argument. | ||
580 | * | ||
581 | * \default \c NULL | ||
582 | * \param decoder A decoder instance to set. | ||
583 | * \param value See above. | ||
584 | * \assert | ||
585 | * \code decoder != NULL \endcode | ||
586 | * \retval FLAC__bool | ||
587 | * \c false if the decoder is already initialized, else \c true. | ||
588 | */ | ||
589 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_client_data(FLAC__SeekableStreamDecoder *decoder, void *value); | ||
590 | |||
591 | /** This is inherited from FLAC__StreamDecoder; see | ||
592 | * FLAC__stream_decoder_set_metadata_respond(). | ||
593 | * | ||
594 | * \default By default, only the \c STREAMINFO block is returned via the | ||
595 | * metadata callback. | ||
596 | * \param decoder A decoder instance to set. | ||
597 | * \param type See above. | ||
598 | * \assert | ||
599 | * \code decoder != NULL \endcode | ||
600 | * \a type is valid | ||
601 | * \retval FLAC__bool | ||
602 | * \c false if the decoder is already initialized, else \c true. | ||
603 | */ | ||
604 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type); | ||
605 | |||
606 | /** This is inherited from FLAC__StreamDecoder; see | ||
607 | * FLAC__stream_decoder_set_metadata_respond_application(). | ||
608 | * | ||
609 | * \default By default, only the \c STREAMINFO block is returned via the | ||
610 | * metadata callback. | ||
611 | * \param decoder A decoder instance to set. | ||
612 | * \param id See above. | ||
613 | * \assert | ||
614 | * \code decoder != NULL \endcode | ||
615 | * \code id != NULL \endcode | ||
616 | * \retval FLAC__bool | ||
617 | * \c false if the decoder is already initialized, else \c true. | ||
618 | */ | ||
619 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4]); | ||
620 | |||
621 | /** This is inherited from FLAC__StreamDecoder; see | ||
622 | * FLAC__stream_decoder_set_metadata_respond_all(). | ||
623 | * | ||
624 | * \default By default, only the \c STREAMINFO block is returned via the | ||
625 | * metadata callback. | ||
626 | * \param decoder A decoder instance to set. | ||
627 | * \assert | ||
628 | * \code decoder != NULL \endcode | ||
629 | * \retval FLAC__bool | ||
630 | * \c false if the decoder is already initialized, else \c true. | ||
631 | */ | ||
632 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_all(FLAC__SeekableStreamDecoder *decoder); | ||
633 | |||
634 | /** This is inherited from FLAC__StreamDecoder; see | ||
635 | * FLAC__stream_decoder_set_metadata_ignore(). | ||
636 | * | ||
637 | * \default By default, only the \c STREAMINFO block is returned via the | ||
638 | * metadata callback. | ||
639 | * \param decoder A decoder instance to set. | ||
640 | * \param type See above. | ||
641 | * \assert | ||
642 | * \code decoder != NULL \endcode | ||
643 | * \a type is valid | ||
644 | * \retval FLAC__bool | ||
645 | * \c false if the decoder is already initialized, else \c true. | ||
646 | */ | ||
647 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type); | ||
648 | |||
649 | /** This is inherited from FLAC__StreamDecoder; see | ||
650 | * FLAC__stream_decoder_set_metadata_ignore_application(). | ||
651 | * | ||
652 | * \default By default, only the \c STREAMINFO block is returned via the | ||
653 | * metadata callback. | ||
654 | * \param decoder A decoder instance to set. | ||
655 | * \param id See above. | ||
656 | * \assert | ||
657 | * \code decoder != NULL \endcode | ||
658 | * \code id != NULL \endcode | ||
659 | * \retval FLAC__bool | ||
660 | * \c false if the decoder is already initialized, else \c true. | ||
661 | */ | ||
662 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4]); | ||
663 | |||
664 | /** This is inherited from FLAC__StreamDecoder; see | ||
665 | * FLAC__stream_decoder_set_metadata_ignore_all(). | ||
666 | * | ||
667 | * \default By default, only the \c STREAMINFO block is returned via the | ||
668 | * metadata callback. | ||
669 | * \param decoder A decoder instance to set. | ||
670 | * \assert | ||
671 | * \code decoder != NULL \endcode | ||
672 | * \retval FLAC__bool | ||
673 | * \c false if the decoder is already initialized, else \c true. | ||
674 | */ | ||
675 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder); | ||
676 | |||
677 | /** Get the current decoder state. | ||
678 | * | ||
679 | * \param decoder A decoder instance to query. | ||
680 | * \assert | ||
681 | * \code decoder != NULL \endcode | ||
682 | * \retval FLAC__SeekableStreamDecoderState | ||
683 | * The current decoder state. | ||
684 | */ | ||
685 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_get_state(const FLAC__SeekableStreamDecoder *decoder); | ||
686 | |||
687 | /** Get the state of the underlying stream decoder. | ||
688 | * Useful when the seekable stream decoder state is | ||
689 | * \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR. | ||
690 | * | ||
691 | * \param decoder A decoder instance to query. | ||
692 | * \assert | ||
693 | * \code decoder != NULL \endcode | ||
694 | * \retval FLAC__StreamDecoderState | ||
695 | * The stream decoder state. | ||
696 | */ | ||
697 | FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder); | ||
698 | |||
699 | /** Get the current decoder state as a C string. | ||
700 | * This version automatically resolves | ||
701 | * \c FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR by getting the | ||
702 | * stream decoder's state. | ||
703 | * | ||
704 | * \param decoder A decoder instance to query. | ||
705 | * \assert | ||
706 | * \code decoder != NULL \endcode | ||
707 | * \retval const char * | ||
708 | * The decoder state as a C string. Do not modify the contents. | ||
709 | */ | ||
710 | FLAC_API const char *FLAC__seekable_stream_decoder_get_resolved_state_string(const FLAC__SeekableStreamDecoder *decoder); | ||
711 | |||
712 | /** Get the "MD5 signature checking" flag. | ||
713 | * This is the value of the setting, not whether or not the decoder is | ||
714 | * currently checking the MD5 (remember, it can be turned off automatically | ||
715 | * by a seek). When the decoder is reset the flag will be restored to the | ||
716 | * value returned by this function. | ||
717 | * | ||
718 | * \param decoder A decoder instance to query. | ||
719 | * \assert | ||
720 | * \code decoder != NULL \endcode | ||
721 | * \retval FLAC__bool | ||
722 | * See above. | ||
723 | */ | ||
724 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_md5_checking(const FLAC__SeekableStreamDecoder *decoder); | ||
725 | |||
726 | /** This is inherited from FLAC__StreamDecoder; see | ||
727 | * FLAC__stream_decoder_get_channels(). | ||
728 | * | ||
729 | * \param decoder A decoder instance to query. | ||
730 | * \assert | ||
731 | * \code decoder != NULL \endcode | ||
732 | * \retval unsigned | ||
733 | * See above. | ||
734 | */ | ||
735 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder); | ||
736 | |||
737 | /** This is inherited from FLAC__StreamDecoder; see | ||
738 | * FLAC__stream_decoder_get_channel_assignment(). | ||
739 | * | ||
740 | * \param decoder A decoder instance to query. | ||
741 | * \assert | ||
742 | * \code decoder != NULL \endcode | ||
743 | * \retval FLAC__ChannelAssignment | ||
744 | * See above. | ||
745 | */ | ||
746 | FLAC_API FLAC__ChannelAssignment FLAC__seekable_stream_decoder_get_channel_assignment(const FLAC__SeekableStreamDecoder *decoder); | ||
747 | |||
748 | /** This is inherited from FLAC__StreamDecoder; see | ||
749 | * FLAC__stream_decoder_get_bits_per_sample(). | ||
750 | * | ||
751 | * \param decoder A decoder instance to query. | ||
752 | * \assert | ||
753 | * \code decoder != NULL \endcode | ||
754 | * \retval unsigned | ||
755 | * See above. | ||
756 | */ | ||
757 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_bits_per_sample(const FLAC__SeekableStreamDecoder *decoder); | ||
758 | |||
759 | /** This is inherited from FLAC__StreamDecoder; see | ||
760 | * FLAC__stream_decoder_get_sample_rate(). | ||
761 | * | ||
762 | * \param decoder A decoder instance to query. | ||
763 | * \assert | ||
764 | * \code decoder != NULL \endcode | ||
765 | * \retval unsigned | ||
766 | * See above. | ||
767 | */ | ||
768 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_sample_rate(const FLAC__SeekableStreamDecoder *decoder); | ||
769 | |||
770 | /** This is inherited from FLAC__StreamDecoder; see | ||
771 | * FLAC__stream_decoder_get_blocksize(). | ||
772 | * | ||
773 | * \param decoder A decoder instance to query. | ||
774 | * \assert | ||
775 | * \code decoder != NULL \endcode | ||
776 | * \retval unsigned | ||
777 | * See above. | ||
778 | */ | ||
779 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_blocksize(const FLAC__SeekableStreamDecoder *decoder); | ||
780 | |||
781 | /** Returns the decoder's current read position within the stream. | ||
782 | * The position is the byte offset from the start of the stream. | ||
783 | * Bytes before this position have been fully decoded. Note that | ||
784 | * there may still be undecoded bytes in the decoder's read FIFO. | ||
785 | * The returned position is correct even after a seek. | ||
786 | * | ||
787 | * \param decoder A decoder instance to query. | ||
788 | * \param position Address at which to return the desired position. | ||
789 | * \assert | ||
790 | * \code decoder != NULL \endcode | ||
791 | * \code position != NULL \endcode | ||
792 | * \retval FLAC__bool | ||
793 | * \c true if successful, \c false if there was an error from | ||
794 | * the 'tell' callback. | ||
795 | */ | ||
796 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_decode_position(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position); | ||
797 | |||
798 | /** Initialize the decoder instance. | ||
799 | * Should be called after FLAC__seekable_stream_decoder_new() and | ||
800 | * FLAC__seekable_stream_decoder_set_*() but before any of the | ||
801 | * FLAC__seekable_stream_decoder_process_*() functions. Will set and return | ||
802 | * the decoder state, which will be FLAC__SEEKABLE_STREAM_DECODER_OK | ||
803 | * if initialization succeeded. | ||
804 | * | ||
805 | * \param decoder An uninitialized decoder instance. | ||
806 | * \assert | ||
807 | * \code decoder != NULL \endcode | ||
808 | * \retval FLAC__SeekableStreamDecoderState | ||
809 | * \c FLAC__SEEKABLE_STREAM_DECODER_OK if initialization was | ||
810 | * successful; see FLAC__SeekableStreamDecoderState for the meanings | ||
811 | * of other return values. | ||
812 | */ | ||
813 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_init(FLAC__SeekableStreamDecoder *decoder); | ||
814 | |||
815 | /** Finish the decoding process. | ||
816 | * Flushes the decoding buffer, releases resources, resets the decoder | ||
817 | * settings to their defaults, and returns the decoder state to | ||
818 | * FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED. | ||
819 | * | ||
820 | * In the event of a prematurely-terminated decode, it is not strictly | ||
821 | * necessary to call this immediately before | ||
822 | * FLAC__seekable_stream_decoder_delete() but it is good practice to match | ||
823 | * every FLAC__seekable_stream_decoder_init() with a | ||
824 | * FLAC__seekable_stream_decoder_finish(). | ||
825 | * | ||
826 | * \param decoder An uninitialized decoder instance. | ||
827 | * \assert | ||
828 | * \code decoder != NULL \endcode | ||
829 | * \retval FLAC__bool | ||
830 | * \c false if MD5 checking is on AND a STREAMINFO block was available | ||
831 | * AND the MD5 signature in the STREAMINFO block was non-zero AND the | ||
832 | * signature does not match the one computed by the decoder; else | ||
833 | * \c true. | ||
834 | */ | ||
835 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_finish(FLAC__SeekableStreamDecoder *decoder); | ||
836 | |||
837 | /** Flush the stream input. | ||
838 | * The decoder's input buffer will be cleared and the state set to | ||
839 | * \c FLAC__SEEKABLE_STREAM_DECODER_OK. This will also turn off MD5 | ||
840 | * checking. | ||
841 | * | ||
842 | * \param decoder A decoder instance. | ||
843 | * \assert | ||
844 | * \code decoder != NULL \endcode | ||
845 | * \retval FLAC__bool | ||
846 | * \c true if successful, else \c false if a memory allocation | ||
847 | * or stream decoder error occurs. | ||
848 | */ | ||
849 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_flush(FLAC__SeekableStreamDecoder *decoder); | ||
850 | |||
851 | /** Reset the decoding process. | ||
852 | * The decoder's input buffer will be cleared and the state set to | ||
853 | * \c FLAC__SEEKABLE_STREAM_DECODER_OK. This is similar to | ||
854 | * FLAC__seekable_stream_decoder_finish() except that the settings are | ||
855 | * preserved; there is no need to call FLAC__seekable_stream_decoder_init() | ||
856 | * before decoding again. MD5 checking will be restored to its original | ||
857 | * setting. | ||
858 | * | ||
859 | * \param decoder A decoder instance. | ||
860 | * \assert | ||
861 | * \code decoder != NULL \endcode | ||
862 | * \retval FLAC__bool | ||
863 | * \c true if successful, else \c false if a memory allocation | ||
864 | * or stream decoder error occurs. | ||
865 | */ | ||
866 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_reset(FLAC__SeekableStreamDecoder *decoder); | ||
867 | |||
868 | /** This is inherited from FLAC__StreamDecoder; see | ||
869 | * FLAC__stream_decoder_process_single(). | ||
870 | * | ||
871 | * \param decoder A decoder instance. | ||
872 | * \assert | ||
873 | * \code decoder != NULL \endcode | ||
874 | * \retval FLAC__bool | ||
875 | * See above. | ||
876 | */ | ||
877 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder); | ||
878 | |||
879 | /** This is inherited from FLAC__StreamDecoder; see | ||
880 | * FLAC__stream_decoder_process_until_end_of_metadata(). | ||
881 | * | ||
882 | * \param decoder A decoder instance. | ||
883 | * \assert | ||
884 | * \code decoder != NULL \endcode | ||
885 | * \retval FLAC__bool | ||
886 | * See above. | ||
887 | */ | ||
888 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder); | ||
889 | |||
890 | /** This is inherited from FLAC__StreamDecoder; see | ||
891 | * FLAC__stream_decoder_process_until_end_of_stream(). | ||
892 | * | ||
893 | * \param decoder A decoder instance. | ||
894 | * \assert | ||
895 | * \code decoder != NULL \endcode | ||
896 | * \retval FLAC__bool | ||
897 | * See above. | ||
898 | */ | ||
899 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_stream(FLAC__SeekableStreamDecoder *decoder); | ||
900 | |||
901 | /** This is inherited from FLAC__StreamDecoder; see | ||
902 | * FLAC__stream_decoder_skip_single_frame(). | ||
903 | * | ||
904 | * \param decoder A decoder instance. | ||
905 | * \assert | ||
906 | * \code decoder != NULL \endcode | ||
907 | * \retval FLAC__bool | ||
908 | * See above. | ||
909 | */ | ||
910 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_skip_single_frame(FLAC__SeekableStreamDecoder *decoder); | ||
911 | |||
912 | /** Flush the input and seek to an absolute sample. | ||
913 | * Decoding will resume at the given sample. Note that because of | ||
914 | * this, the next write callback may contain a partial block. | ||
915 | * | ||
916 | * \param decoder A decoder instance. | ||
917 | * \param sample The target sample number to seek to. | ||
918 | * \assert | ||
919 | * \code decoder != NULL \endcode | ||
920 | * \retval FLAC__bool | ||
921 | * \c true if successful, else \c false. | ||
922 | */ | ||
923 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample); | ||
924 | |||
925 | /* \} */ | ||
926 | |||
927 | #ifdef __cplusplus | ||
928 | } | ||
929 | #endif | ||
930 | |||
931 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/seekable_stream_encoder.h b/apps/codecs/libFLAC/include/FLAC/seekable_stream_encoder.h new file mode 100644 index 0000000000..4efeb427be --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/seekable_stream_encoder.h | |||
@@ -0,0 +1,992 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__SEEKABLE_STREAM_ENCODER_H | ||
33 | #define FLAC__SEEKABLE_STREAM_ENCODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "stream_encoder.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /** \file include/FLAC/seekable_stream_encoder.h | ||
44 | * | ||
45 | * \brief | ||
46 | * This module contains the functions which implement the seekable stream | ||
47 | * encoder. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_seekable_stream_encoder seekable stream encoder \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_seekable_stream_encoder FLAC/seekable_stream_encoder.h: seekable stream encoder interface | ||
54 | * \ingroup flac_encoder | ||
55 | * | ||
56 | * \brief | ||
57 | * This module contains the functions which implement the seekable stream | ||
58 | * encoder. | ||
59 | * | ||
60 | * The basic usage of this encoder is as follows: | ||
61 | * - The program creates an instance of an encoder using | ||
62 | * FLAC__seekable_stream_encoder_new(). | ||
63 | * - The program overrides the default settings and sets callbacks using | ||
64 | * FLAC__seekable_stream_encoder_set_*() functions. | ||
65 | * - The program initializes the instance to validate the settings and | ||
66 | * prepare for encoding using FLAC__seekable_stream_encoder_init(). | ||
67 | * - The program calls FLAC__seekable_stream_encoder_process() or | ||
68 | * FLAC__seekable_stream_encoder_process_interleaved() to encode data, which | ||
69 | * subsequently calls the callbacks when there is encoder data ready | ||
70 | * to be written. | ||
71 | * - The program finishes the encoding with FLAC__seekable_stream_encoder_finish(), | ||
72 | * which causes the encoder to encode any data still in its input pipe, | ||
73 | * rewrite the metadata with the final encoding statistics, and finally | ||
74 | * reset the encoder to the uninitialized state. | ||
75 | * - The instance may be used again or deleted with | ||
76 | * FLAC__seekable_stream_encoder_delete(). | ||
77 | * | ||
78 | * The seekable stream encoder is a wrapper around the | ||
79 | * \link flac_stream_encoder stream encoder \endlink with callbacks for | ||
80 | * seeking the output and reporting the output stream position. This | ||
81 | * allows the encoder to go back and rewrite some of the metadata after | ||
82 | * encoding if necessary, and provides the metadata callback of the stream | ||
83 | * encoder internally. However, you must provide seek and tell callbacks | ||
84 | * (see FLAC__seekable_stream_encoder_set_seek_callback() and | ||
85 | * FLAC__seekable_stream_encoder_set_tell_callback()). | ||
86 | * | ||
87 | * Make sure to read the detailed description of the | ||
88 | * \link flac_stream_encoder stream encoder module \endlink since the | ||
89 | * seekable stream encoder inherits much of its behavior. | ||
90 | * | ||
91 | * \note | ||
92 | * If you are writing the FLAC data to a file, make sure it is open | ||
93 | * for update (e.g. mode "w+" for stdio streams). This is because after | ||
94 | * the first encoding pass, the encoder will try to seek back to the | ||
95 | * beginning of the stream, to the STREAMINFO block, to write some data | ||
96 | * there. | ||
97 | * | ||
98 | * \note | ||
99 | * The "set" functions may only be called when the encoder is in the | ||
100 | * state FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED, i.e. after | ||
101 | * FLAC__seekable_stream_encoder_new() or FLAC__seekable_stream_encoder_finish(), but | ||
102 | * before FLAC__seekable_stream_encoder_init(). If this is the case they will | ||
103 | * return \c true, otherwise \c false. | ||
104 | * | ||
105 | * \note | ||
106 | * FLAC__seekable_stream_encoder_finish() resets all settings to the constructor | ||
107 | * defaults, including the callbacks. | ||
108 | * | ||
109 | * \{ | ||
110 | */ | ||
111 | |||
112 | |||
113 | /** State values for a FLAC__SeekableStreamEncoder | ||
114 | * | ||
115 | * The encoder's state can be obtained by calling FLAC__seekable_stream_encoder_get_state(). | ||
116 | */ | ||
117 | typedef enum { | ||
118 | |||
119 | FLAC__SEEKABLE_STREAM_ENCODER_OK = 0, | ||
120 | /**< The encoder is in the normal OK state. */ | ||
121 | |||
122 | FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR, | ||
123 | /**< An error occurred in the underlying stream encoder; | ||
124 | * check FLAC__seekable_stream_encoder_get_stream_encoder_state(). | ||
125 | */ | ||
126 | |||
127 | FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, | ||
128 | /**< Memory allocation failed. */ | ||
129 | |||
130 | FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR, | ||
131 | /**< The write callback returned an error. */ | ||
132 | |||
133 | FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR, | ||
134 | /**< The read callback returned an error. */ | ||
135 | |||
136 | FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR, | ||
137 | /**< The seek callback returned an error. */ | ||
138 | |||
139 | FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR, | ||
140 | /**< The tell callback returned an error. */ | ||
141 | |||
142 | FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED, | ||
143 | /**< FLAC__seekable_stream_encoder_init() was called when the encoder was | ||
144 | * already initialized, usually because | ||
145 | * FLAC__seekable_stream_encoder_finish() was not called. | ||
146 | */ | ||
147 | |||
148 | FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK, | ||
149 | /**< FLAC__seekable_stream_encoder_init() was called without all | ||
150 | * callbacks being set. | ||
151 | */ | ||
152 | |||
153 | FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE, | ||
154 | /**< An invalid seek table was passed is the metadata to | ||
155 | * FLAC__seekable_stream_encoder_set_metadata(). | ||
156 | */ | ||
157 | |||
158 | FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED | ||
159 | /**< The encoder is in the uninitialized state. */ | ||
160 | |||
161 | } FLAC__SeekableStreamEncoderState; | ||
162 | |||
163 | /** Maps a FLAC__SeekableStreamEncoderState to a C string. | ||
164 | * | ||
165 | * Using a FLAC__SeekableStreamEncoderState as the index to this array | ||
166 | * will give the string equivalent. The contents should not be modified. | ||
167 | */ | ||
168 | extern FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[]; | ||
169 | |||
170 | |||
171 | /** Return values for the FLAC__SeekableStreamEncoder seek callback. | ||
172 | */ | ||
173 | typedef enum { | ||
174 | |||
175 | FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK, | ||
176 | /**< The seek was OK and encoding can continue. */ | ||
177 | |||
178 | FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR | ||
179 | /**< An unrecoverable error occurred. The encoder will return from the process call. */ | ||
180 | |||
181 | } FLAC__SeekableStreamEncoderSeekStatus; | ||
182 | |||
183 | /** Maps a FLAC__SeekableStreamEncoderSeekStatus to a C string. | ||
184 | * | ||
185 | * Using a FLAC__SeekableStreamEncoderSeekStatus as the index to this array | ||
186 | * will give the string equivalent. The contents should not be modified. | ||
187 | */ | ||
188 | extern FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[]; | ||
189 | |||
190 | |||
191 | /** Return values for the FLAC__SeekableStreamEncoder tell callback. | ||
192 | */ | ||
193 | typedef enum { | ||
194 | |||
195 | FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK, | ||
196 | /**< The tell was OK and encoding can continue. */ | ||
197 | |||
198 | FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR | ||
199 | /**< An unrecoverable error occurred. The encoder will return from the process call. */ | ||
200 | |||
201 | } FLAC__SeekableStreamEncoderTellStatus; | ||
202 | |||
203 | /** Maps a FLAC__SeekableStreamEncoderTellStatus to a C string. | ||
204 | * | ||
205 | * Using a FLAC__SeekableStreamEncoderTellStatus as the index to this array | ||
206 | * will give the string equivalent. The contents should not be modified. | ||
207 | */ | ||
208 | extern FLAC_API const char * const FLAC__SeekableStreamEncoderTellStatusString[]; | ||
209 | |||
210 | |||
211 | /*********************************************************************** | ||
212 | * | ||
213 | * class FLAC__SeekableStreamEncoder | ||
214 | * | ||
215 | ***********************************************************************/ | ||
216 | |||
217 | struct FLAC__SeekableStreamEncoderProtected; | ||
218 | struct FLAC__SeekableStreamEncoderPrivate; | ||
219 | /** The opaque structure definition for the seekable stream encoder type. | ||
220 | * See the \link flac_seekable_stream_encoder seekable stream encoder module \endlink | ||
221 | * for a detailed description. | ||
222 | */ | ||
223 | typedef struct { | ||
224 | struct FLAC__SeekableStreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
225 | struct FLAC__SeekableStreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
226 | } FLAC__SeekableStreamEncoder; | ||
227 | |||
228 | /** Signature for the seek callback. | ||
229 | * See FLAC__seekable_stream_encoder_set_seek_callback() for more info. | ||
230 | * | ||
231 | * \param encoder The encoder instance calling the callback. | ||
232 | * \param absolute_byte_offset The offset from the beginning of the stream | ||
233 | * to seek to. | ||
234 | * \param client_data The callee's client data set through | ||
235 | * FLAC__seekable_stream_encoder_set_client_data(). | ||
236 | * \retval FLAC__SeekableStreamEncoderSeekStatus | ||
237 | * The callee's return status. | ||
238 | */ | ||
239 | typedef FLAC__SeekableStreamEncoderSeekStatus (*FLAC__SeekableStreamEncoderSeekCallback)(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
240 | |||
241 | /** Signature for the tell callback. | ||
242 | * See FLAC__seekable_stream_encoder_set_tell_callback() for more info. | ||
243 | * | ||
244 | * \warning | ||
245 | * The callback must return the true current byte offset of the output to | ||
246 | * which the encoder is writing. If you are buffering the output, make | ||
247 | * sure and take this into account. If you are writing directly to a | ||
248 | * FILE* from your write callback, ftell() is sufficient. If you are | ||
249 | * writing directly to a file descriptor from your write callback, you | ||
250 | * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to | ||
251 | * these points to rewrite metadata after encoding. | ||
252 | * | ||
253 | * \param encoder The encoder instance calling the callback. | ||
254 | * \param absolute_byte_offset The address at which to store the current | ||
255 | * position of the output. | ||
256 | * \param client_data The callee's client data set through | ||
257 | * FLAC__seekable_stream_encoder_set_client_data(). | ||
258 | * \retval FLAC__SeekableStreamEncoderTellStatus | ||
259 | * The callee's return status. | ||
260 | */ | ||
261 | typedef FLAC__SeekableStreamEncoderTellStatus (*FLAC__SeekableStreamEncoderTellCallback)(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
262 | |||
263 | /** Signature for the write callback. | ||
264 | * See FLAC__seekable_stream_encoder_set_write_callback() | ||
265 | * and FLAC__StreamEncoderWriteCallback for more info. | ||
266 | * | ||
267 | * \param encoder The encoder instance calling the callback. | ||
268 | * \param buffer An array of encoded data of length \a bytes. | ||
269 | * \param bytes The byte length of \a buffer. | ||
270 | * \param samples The number of samples encoded by \a buffer. | ||
271 | * \c 0 has a special meaning; see | ||
272 | * FLAC__stream_encoder_set_write_callback(). | ||
273 | * \param current_frame The number of current frame being encoded. | ||
274 | * \param client_data The callee's client data set through | ||
275 | * FLAC__seekable_stream_encoder_set_client_data(). | ||
276 | * \retval FLAC__StreamEncoderWriteStatus | ||
277 | * The callee's return status. | ||
278 | */ | ||
279 | typedef FLAC__StreamEncoderWriteStatus (*FLAC__SeekableStreamEncoderWriteCallback)(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); | ||
280 | |||
281 | |||
282 | /*********************************************************************** | ||
283 | * | ||
284 | * Class constructor/destructor | ||
285 | * | ||
286 | ***********************************************************************/ | ||
287 | |||
288 | /** Create a new seekable stream encoder instance. The instance is created with | ||
289 | * default settings; see the individual FLAC__seekable_stream_encoder_set_*() | ||
290 | * functions for each setting's default. | ||
291 | * | ||
292 | * \retval FLAC__SeekableStreamEncoder* | ||
293 | * \c NULL if there was an error allocating memory, else the new instance. | ||
294 | */ | ||
295 | FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new(); | ||
296 | |||
297 | /** Free an encoder instance. Deletes the object pointed to by \a encoder. | ||
298 | * | ||
299 | * \param encoder A pointer to an existing encoder. | ||
300 | * \assert | ||
301 | * \code encoder != NULL \endcode | ||
302 | */ | ||
303 | FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder); | ||
304 | |||
305 | /*********************************************************************** | ||
306 | * | ||
307 | * Public class method prototypes | ||
308 | * | ||
309 | ***********************************************************************/ | ||
310 | |||
311 | /** This is inherited from FLAC__StreamEncoder; see | ||
312 | * FLAC__stream_encoder_set_verify(). | ||
313 | * | ||
314 | * \default \c true | ||
315 | * \param encoder An encoder instance to set. | ||
316 | * \param value See above. | ||
317 | * \assert | ||
318 | * \code encoder != NULL \endcode | ||
319 | * \retval FLAC__bool | ||
320 | * \c false if the encoder is already initialized, else \c true. | ||
321 | */ | ||
322 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
323 | |||
324 | /** This is inherited from FLAC__StreamEncoder; see | ||
325 | * FLAC__stream_encoder_set_streamable_subset(). | ||
326 | * | ||
327 | * \default \c true | ||
328 | * \param encoder An encoder instance to set. | ||
329 | * \param value See above. | ||
330 | * \assert | ||
331 | * \code encoder != NULL \endcode | ||
332 | * \retval FLAC__bool | ||
333 | * \c false if the encoder is already initialized, else \c true. | ||
334 | */ | ||
335 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
336 | |||
337 | /** This is inherited from FLAC__StreamEncoder; see | ||
338 | * FLAC__stream_encoder_set_do_mid_side_stereo(). | ||
339 | * | ||
340 | * \default \c false | ||
341 | * \param encoder An encoder instance to set. | ||
342 | * \param value See above. | ||
343 | * \assert | ||
344 | * \code encoder != NULL \endcode | ||
345 | * \retval FLAC__bool | ||
346 | * \c false if the encoder is already initialized, else \c true. | ||
347 | */ | ||
348 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
349 | |||
350 | /** This is inherited from FLAC__StreamEncoder; see | ||
351 | * FLAC__stream_encoder_set_loose_mid_side_stereo(). | ||
352 | * | ||
353 | * \default \c false | ||
354 | * \param encoder An encoder instance to set. | ||
355 | * \param value See above. | ||
356 | * \assert | ||
357 | * \code encoder != NULL \endcode | ||
358 | * \retval FLAC__bool | ||
359 | * \c false if the encoder is already initialized, else \c true. | ||
360 | */ | ||
361 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
362 | |||
363 | /** This is inherited from FLAC__StreamEncoder; see | ||
364 | * FLAC__stream_encoder_set_channels(). | ||
365 | * | ||
366 | * \default \c 2 | ||
367 | * \param encoder An encoder instance to set. | ||
368 | * \param value See above. | ||
369 | * \assert | ||
370 | * \code encoder != NULL \endcode | ||
371 | * \retval FLAC__bool | ||
372 | * \c false if the encoder is already initialized, else \c true. | ||
373 | */ | ||
374 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
375 | |||
376 | /** This is inherited from FLAC__StreamEncoder; see | ||
377 | * FLAC__stream_encoder_set_bits_per_sample(). | ||
378 | * | ||
379 | * \warning | ||
380 | * Do not feed the encoder data that is wider than the value you | ||
381 | * set here or you will generate an invalid stream. | ||
382 | * | ||
383 | * \default \c 16 | ||
384 | * \param encoder An encoder instance to set. | ||
385 | * \param value See above. | ||
386 | * \assert | ||
387 | * \code encoder != NULL \endcode | ||
388 | * \retval FLAC__bool | ||
389 | * \c false if the encoder is already initialized, else \c true. | ||
390 | */ | ||
391 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
392 | |||
393 | /** This is inherited from FLAC__StreamEncoder; see | ||
394 | * FLAC__stream_encoder_set_sample_rate(). | ||
395 | * | ||
396 | * \default \c 44100 | ||
397 | * \param encoder An encoder instance to set. | ||
398 | * \param value See above. | ||
399 | * \assert | ||
400 | * \code encoder != NULL \endcode | ||
401 | * \retval FLAC__bool | ||
402 | * \c false if the encoder is already initialized, else \c true. | ||
403 | */ | ||
404 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
405 | |||
406 | /** This is inherited from FLAC__StreamEncoder; see | ||
407 | * FLAC__stream_encoder_set_blocksize(). | ||
408 | * | ||
409 | * \default \c 1152 | ||
410 | * \param encoder An encoder instance to set. | ||
411 | * \param value See above. | ||
412 | * \assert | ||
413 | * \code encoder != NULL \endcode | ||
414 | * \retval FLAC__bool | ||
415 | * \c false if the encoder is already initialized, else \c true. | ||
416 | */ | ||
417 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
418 | |||
419 | /** This is inherited from FLAC__StreamEncoder; see | ||
420 | * FLAC__stream_encoder_set_max_lpc_order(). | ||
421 | * | ||
422 | * \default \c 0 | ||
423 | * \param encoder An encoder instance to set. | ||
424 | * \param value See above. | ||
425 | * \assert | ||
426 | * \code encoder != NULL \endcode | ||
427 | * \retval FLAC__bool | ||
428 | * \c false if the encoder is already initialized, else \c true. | ||
429 | */ | ||
430 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
431 | |||
432 | /** This is inherited from FLAC__StreamEncoder; see | ||
433 | * FLAC__stream_encoder_set_qlp_coeff_precision(). | ||
434 | * | ||
435 | * \note | ||
436 | * In the current implementation, qlp_coeff_precision + bits_per_sample must | ||
437 | * be less than 32. | ||
438 | * | ||
439 | * \default \c 0 | ||
440 | * \param encoder An encoder instance to set. | ||
441 | * \param value See above. | ||
442 | * \assert | ||
443 | * \code encoder != NULL \endcode | ||
444 | * \retval FLAC__bool | ||
445 | * \c false if the encoder is already initialized, else \c true. | ||
446 | */ | ||
447 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
448 | |||
449 | /** This is inherited from FLAC__StreamEncoder; see | ||
450 | * FLAC__stream_encoder_set_do_qlp_coeff_prec_search(). | ||
451 | * | ||
452 | * \default \c false | ||
453 | * \param encoder An encoder instance to set. | ||
454 | * \param value See above. | ||
455 | * \assert | ||
456 | * \code encoder != NULL \endcode | ||
457 | * \retval FLAC__bool | ||
458 | * \c false if the encoder is already initialized, else \c true. | ||
459 | */ | ||
460 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
461 | |||
462 | /** This is inherited from FLAC__StreamEncoder; see | ||
463 | * FLAC__stream_encoder_set_do_escape_coding(). | ||
464 | * | ||
465 | * \default \c false | ||
466 | * \param encoder An encoder instance to set. | ||
467 | * \param value See above. | ||
468 | * \assert | ||
469 | * \code encoder != NULL \endcode | ||
470 | * \retval FLAC__bool | ||
471 | * \c false if the encoder is already initialized, else \c true. | ||
472 | */ | ||
473 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
474 | |||
475 | /** This is inherited from FLAC__StreamEncoder; see | ||
476 | * FLAC__stream_encoder_set_do_exhaustive_model_search(). | ||
477 | * | ||
478 | * \default \c false | ||
479 | * \param encoder An encoder instance to set. | ||
480 | * \param value See above. | ||
481 | * \assert | ||
482 | * \code encoder != NULL \endcode | ||
483 | * \retval FLAC__bool | ||
484 | * \c false if the encoder is already initialized, else \c true. | ||
485 | */ | ||
486 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
487 | |||
488 | /** This is inherited from FLAC__StreamEncoder; see | ||
489 | * FLAC__stream_encoder_set_min_residual_partition_order(). | ||
490 | * | ||
491 | * \default \c 0 | ||
492 | * \param encoder An encoder instance to set. | ||
493 | * \param value See above. | ||
494 | * \assert | ||
495 | * \code encoder != NULL \endcode | ||
496 | * \retval FLAC__bool | ||
497 | * \c false if the encoder is already initialized, else \c true. | ||
498 | */ | ||
499 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
500 | |||
501 | /** This is inherited from FLAC__StreamEncoder; see | ||
502 | * FLAC__stream_encoder_set_max_residual_partition_order(). | ||
503 | * | ||
504 | * \default \c 0 | ||
505 | * \param encoder An encoder instance to set. | ||
506 | * \param value See above. | ||
507 | * \assert | ||
508 | * \code encoder != NULL \endcode | ||
509 | * \retval FLAC__bool | ||
510 | * \c false if the encoder is already initialized, else \c true. | ||
511 | */ | ||
512 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
513 | |||
514 | /** This is inherited from FLAC__StreamEncoder; see | ||
515 | * FLAC__stream_encoder_set_rice_parameter_search_dist(). | ||
516 | * | ||
517 | * \default \c 0 | ||
518 | * \param encoder An encoder instance to set. | ||
519 | * \param value See above. | ||
520 | * \assert | ||
521 | * \code encoder != NULL \endcode | ||
522 | * \retval FLAC__bool | ||
523 | * \c false if the encoder is already initialized, else \c true. | ||
524 | */ | ||
525 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value); | ||
526 | |||
527 | /** This is inherited from FLAC__StreamEncoder; see | ||
528 | * FLAC__stream_encoder_set_total_samples_estimate(). | ||
529 | * | ||
530 | * \default \c 0 | ||
531 | * \param encoder An encoder instance to set. | ||
532 | * \param value See above. | ||
533 | * \assert | ||
534 | * \code encoder != NULL \endcode | ||
535 | * \retval FLAC__bool | ||
536 | * \c false if the encoder is already initialized, else \c true. | ||
537 | */ | ||
538 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value); | ||
539 | |||
540 | /** This is inherited from FLAC__StreamEncoder; see | ||
541 | * FLAC__stream_encoder_set_metadata(). | ||
542 | * | ||
543 | * \note | ||
544 | * SEEKTABLE blocks are handled specially. Since you will not know | ||
545 | * the values for the seek point stream offsets, you should pass in | ||
546 | * a SEEKTABLE 'template', that is, a SEEKTABLE object with the | ||
547 | * required sample numbers (or placeholder points), with \c 0 for the | ||
548 | * \a frame_samples and \a stream_offset fields for each point. While | ||
549 | * encoding, the encoder will fill them in for you and when encoding | ||
550 | * is finished, it will seek back and write the real values into the | ||
551 | * SEEKTABLE block in the stream. There are helper routines for | ||
552 | * manipulating seektable template blocks; see metadata.h: | ||
553 | * FLAC__metadata_object_seektable_template_*(). | ||
554 | * | ||
555 | * \note | ||
556 | * The encoder instance \b will modify the first \c SEEKTABLE block | ||
557 | * as it transforms the template to a valid seektable while encoding, | ||
558 | * but it is still up to the caller to free all metadata blocks after | ||
559 | * encoding. | ||
560 | * | ||
561 | * \default \c NULL, 0 | ||
562 | * \param encoder An encoder instance to set. | ||
563 | * \param metadata See above. | ||
564 | * \param num_blocks See above. | ||
565 | * \assert | ||
566 | * \code encoder != NULL \endcode | ||
567 | * \retval FLAC__bool | ||
568 | * \c false if the encoder is already initialized, else \c true. | ||
569 | */ | ||
570 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); | ||
571 | |||
572 | /** Set the seek callback. | ||
573 | * The supplied function will be called when the encoder needs to seek | ||
574 | * the output stream. The encoder will pass the absolute byte offset | ||
575 | * to seek to, 0 meaning the beginning of the stream. | ||
576 | * | ||
577 | * \note | ||
578 | * The callback is mandatory and must be set before initialization. | ||
579 | * | ||
580 | * \default \c NULL | ||
581 | * \param encoder An encoder instance to set. | ||
582 | * \param value See above. | ||
583 | * \assert | ||
584 | * \code encoder != NULL \endcode | ||
585 | * \code value != NULL \endcode | ||
586 | * \retval FLAC__bool | ||
587 | * \c false if the encoder is already initialized, else \c true. | ||
588 | */ | ||
589 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value); | ||
590 | |||
591 | /** Set the tell callback. | ||
592 | * The supplied function will be called when the encoder needs to know | ||
593 | * the current position of the output stream. | ||
594 | * | ||
595 | * \note | ||
596 | * The callback is mandatory and must be set before initialization. | ||
597 | * | ||
598 | * \default \c NULL | ||
599 | * \param encoder An encoder instance to set. | ||
600 | * \param value See above. | ||
601 | * \assert | ||
602 | * \code encoder != NULL \endcode | ||
603 | * \code value != NULL \endcode | ||
604 | * \retval FLAC__bool | ||
605 | * \c false if the encoder is already initialized, else \c true. | ||
606 | */ | ||
607 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_tell_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderTellCallback value); | ||
608 | |||
609 | /** Set the write callback. | ||
610 | * This is inherited from FLAC__StreamEncoder; see | ||
611 | * FLAC__stream_encoder_set_write_callback(). | ||
612 | * | ||
613 | * \note | ||
614 | * The callback is mandatory and must be set before initialization. | ||
615 | * | ||
616 | * \default \c NULL | ||
617 | * \param encoder An encoder instance to set. | ||
618 | * \param value See above. | ||
619 | * \assert | ||
620 | * \code encoder != NULL \endcode | ||
621 | * \code value != NULL \endcode | ||
622 | * \retval FLAC__bool | ||
623 | * \c false if the encoder is already initialized, else \c true. | ||
624 | */ | ||
625 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value); | ||
626 | |||
627 | /** Set the client data to be passed back to callbacks. | ||
628 | * This value will be supplied to callbacks in their \a client_data | ||
629 | * argument. | ||
630 | * | ||
631 | * \default \c NULL | ||
632 | * \param encoder An encoder instance to set. | ||
633 | * \param value See above. | ||
634 | * \assert | ||
635 | * \code encoder != NULL \endcode | ||
636 | * \retval FLAC__bool | ||
637 | * \c false if the encoder is already initialized, else \c true. | ||
638 | */ | ||
639 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value); | ||
640 | |||
641 | /** Get the current encoder state. | ||
642 | * | ||
643 | * \param encoder An encoder instance to query. | ||
644 | * \assert | ||
645 | * \code encoder != NULL \endcode | ||
646 | * \retval FLAC__SeekableStreamEncoderState | ||
647 | * The current encoder state. | ||
648 | */ | ||
649 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder); | ||
650 | |||
651 | /** Get the state of the underlying stream encoder. | ||
652 | * Useful when the seekable stream encoder state is | ||
653 | * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR. | ||
654 | * | ||
655 | * \param encoder An encoder instance to query. | ||
656 | * \assert | ||
657 | * \code encoder != NULL \endcode | ||
658 | * \retval FLAC__StreamEncoderState | ||
659 | * The stream encoder state. | ||
660 | */ | ||
661 | FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder); | ||
662 | |||
663 | /** Get the state of the underlying stream encoder's verify decoder. | ||
664 | * Useful when the seekable stream encoder state is | ||
665 | * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR and the | ||
666 | * stream encoder state is \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. | ||
667 | * | ||
668 | * \param encoder An encoder instance to query. | ||
669 | * \assert | ||
670 | * \code encoder != NULL \endcode | ||
671 | * \retval FLAC__StreamDecoderState | ||
672 | * The stream encoder state. | ||
673 | */ | ||
674 | FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder); | ||
675 | |||
676 | /** Get the current encoder state as a C string. | ||
677 | * This version automatically resolves | ||
678 | * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR by getting the | ||
679 | * stream encoder's state. | ||
680 | * | ||
681 | * \param encoder A encoder instance to query. | ||
682 | * \assert | ||
683 | * \code encoder != NULL \endcode | ||
684 | * \retval const char * | ||
685 | * The encoder state as a C string. Do not modify the contents. | ||
686 | */ | ||
687 | FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder); | ||
688 | |||
689 | /** Get relevant values about the nature of a verify decoder error. | ||
690 | * Inherited from FLAC__stream_encoder_get_verify_decoder_error_stats(). | ||
691 | * Useful when the seekable stream encoder state is | ||
692 | * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR and the | ||
693 | * stream encoder state is | ||
694 | * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. | ||
695 | * | ||
696 | * \param encoder An encoder instance to query. | ||
697 | * \param absolute_sample The absolute sample number of the mismatch. | ||
698 | * \param frame_number The number of the frame in which the mismatch occurred. | ||
699 | * \param channel The channel in which the mismatch occurred. | ||
700 | * \param sample The number of the sample (relative to the frame) in | ||
701 | * which the mismatch occurred. | ||
702 | * \param expected The expected value for the sample in question. | ||
703 | * \param got The actual value returned by the decoder. | ||
704 | * \assert | ||
705 | * \code encoder != NULL \endcode | ||
706 | */ | ||
707 | FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); | ||
708 | |||
709 | /** Get the "verify" flag. | ||
710 | * This is inherited from FLAC__StreamEncoder; see | ||
711 | * FLAC__stream_encoder_get_verify(). | ||
712 | * | ||
713 | * \param encoder An encoder instance to query. | ||
714 | * \assert | ||
715 | * \code encoder != NULL \endcode | ||
716 | * \retval FLAC__bool | ||
717 | * See FLAC__seekable_stream_encoder_set_verify(). | ||
718 | */ | ||
719 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder); | ||
720 | |||
721 | /** Get the "streamable subset" flag. | ||
722 | * This is inherited from FLAC__StreamEncoder; see | ||
723 | * FLAC__stream_encoder_get_streamable_subset(). | ||
724 | * | ||
725 | * \param encoder An encoder instance to query. | ||
726 | * \assert | ||
727 | * \code encoder != NULL \endcode | ||
728 | * \retval FLAC__bool | ||
729 | * See FLAC__seekable_stream_encoder_set_streamable_subset(). | ||
730 | */ | ||
731 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder); | ||
732 | |||
733 | /** Get the "mid/side stereo coding" flag. | ||
734 | * This is inherited from FLAC__StreamEncoder; see | ||
735 | * FLAC__stream_encoder_get_do_mid_side_stereo(). | ||
736 | * | ||
737 | * \param encoder An encoder instance to query. | ||
738 | * \assert | ||
739 | * \code encoder != NULL \endcode | ||
740 | * \retval FLAC__bool | ||
741 | * See FLAC__seekable_stream_encoder_get_do_mid_side_stereo(). | ||
742 | */ | ||
743 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder); | ||
744 | |||
745 | /** Get the "adaptive mid/side switching" flag. | ||
746 | * This is inherited from FLAC__StreamEncoder; see | ||
747 | * FLAC__stream_encoder_get_loose_mid_side_stereo(). | ||
748 | * | ||
749 | * \param encoder An encoder instance to query. | ||
750 | * \assert | ||
751 | * \code encoder != NULL \endcode | ||
752 | * \retval FLAC__bool | ||
753 | * See FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(). | ||
754 | */ | ||
755 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder); | ||
756 | |||
757 | /** Get the number of input channels being processed. | ||
758 | * This is inherited from FLAC__StreamEncoder; see | ||
759 | * FLAC__stream_encoder_get_channels(). | ||
760 | * | ||
761 | * \param encoder An encoder instance to query. | ||
762 | * \assert | ||
763 | * \code encoder != NULL \endcode | ||
764 | * \retval unsigned | ||
765 | * See FLAC__seekable_stream_encoder_set_channels(). | ||
766 | */ | ||
767 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder); | ||
768 | |||
769 | /** Get the input sample resolution setting. | ||
770 | * This is inherited from FLAC__StreamEncoder; see | ||
771 | * FLAC__stream_encoder_get_bits_per_sample(). | ||
772 | * | ||
773 | * \param encoder An encoder instance to query. | ||
774 | * \assert | ||
775 | * \code encoder != NULL \endcode | ||
776 | * \retval unsigned | ||
777 | * See FLAC__seekable_stream_encoder_set_bits_per_sample(). | ||
778 | */ | ||
779 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder); | ||
780 | |||
781 | /** Get the input sample rate setting. | ||
782 | * This is inherited from FLAC__StreamEncoder; see | ||
783 | * FLAC__stream_encoder_get_sample_rate(). | ||
784 | * | ||
785 | * \param encoder An encoder instance to query. | ||
786 | * \assert | ||
787 | * \code encoder != NULL \endcode | ||
788 | * \retval unsigned | ||
789 | * See FLAC__seekable_stream_encoder_set_sample_rate(). | ||
790 | */ | ||
791 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder); | ||
792 | |||
793 | /** Get the blocksize setting. | ||
794 | * This is inherited from FLAC__StreamEncoder; see | ||
795 | * FLAC__stream_encoder_get_blocksize(). | ||
796 | * | ||
797 | * \param encoder An encoder instance to query. | ||
798 | * \assert | ||
799 | * \code encoder != NULL \endcode | ||
800 | * \retval unsigned | ||
801 | * See FLAC__seekable_stream_encoder_set_blocksize(). | ||
802 | */ | ||
803 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder); | ||
804 | |||
805 | /** Get the maximum LPC order setting. | ||
806 | * This is inherited from FLAC__StreamEncoder; see | ||
807 | * FLAC__stream_encoder_get_max_lpc_order(). | ||
808 | * | ||
809 | * \param encoder An encoder instance to query. | ||
810 | * \assert | ||
811 | * \code encoder != NULL \endcode | ||
812 | * \retval unsigned | ||
813 | * See FLAC__seekable_stream_encoder_set_max_lpc_order(). | ||
814 | */ | ||
815 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder); | ||
816 | |||
817 | /** Get the quantized linear predictor coefficient precision setting. | ||
818 | * This is inherited from FLAC__StreamEncoder; see | ||
819 | * FLAC__stream_encoder_get_qlp_coeff_precision(). | ||
820 | * | ||
821 | * \param encoder An encoder instance to query. | ||
822 | * \assert | ||
823 | * \code encoder != NULL \endcode | ||
824 | * \retval unsigned | ||
825 | * See FLAC__seekable_stream_encoder_set_qlp_coeff_precision(). | ||
826 | */ | ||
827 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder); | ||
828 | |||
829 | /** Get the qlp coefficient precision search flag. | ||
830 | * This is inherited from FLAC__StreamEncoder; see | ||
831 | * FLAC__stream_encoder_get_do_qlp_coeff_prec_search(). | ||
832 | * | ||
833 | * \param encoder An encoder instance to query. | ||
834 | * \assert | ||
835 | * \code encoder != NULL \endcode | ||
836 | * \retval FLAC__bool | ||
837 | * See FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(). | ||
838 | */ | ||
839 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder); | ||
840 | |||
841 | /** Get the "escape coding" flag. | ||
842 | * This is inherited from FLAC__StreamEncoder; see | ||
843 | * FLAC__stream_encoder_get_do_escape_coding(). | ||
844 | * | ||
845 | * \param encoder An encoder instance to query. | ||
846 | * \assert | ||
847 | * \code encoder != NULL \endcode | ||
848 | * \retval FLAC__bool | ||
849 | * See FLAC__seekable_stream_encoder_set_do_escape_coding(). | ||
850 | */ | ||
851 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder); | ||
852 | |||
853 | /** Get the exhaustive model search flag. | ||
854 | * This is inherited from FLAC__StreamEncoder; see | ||
855 | * FLAC__stream_encoder_get_do_exhaustive_model_search(). | ||
856 | * | ||
857 | * \param encoder An encoder instance to query. | ||
858 | * \assert | ||
859 | * \code encoder != NULL \endcode | ||
860 | * \retval FLAC__bool | ||
861 | * See FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(). | ||
862 | */ | ||
863 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder); | ||
864 | |||
865 | /** Get the minimum residual partition order setting. | ||
866 | * This is inherited from FLAC__StreamEncoder; see | ||
867 | * FLAC__stream_encoder_get_min_residual_partition_order(). | ||
868 | * | ||
869 | * \param encoder An encoder instance to query. | ||
870 | * \assert | ||
871 | * \code encoder != NULL \endcode | ||
872 | * \retval unsigned | ||
873 | * See FLAC__seekable_stream_encoder_set_min_residual_partition_order(). | ||
874 | */ | ||
875 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder); | ||
876 | |||
877 | /** Get maximum residual partition order setting. | ||
878 | * This is inherited from FLAC__StreamEncoder; see | ||
879 | * FLAC__stream_encoder_get_max_residual_partition_order(). | ||
880 | * | ||
881 | * \param encoder An encoder instance to query. | ||
882 | * \assert | ||
883 | * \code encoder != NULL \endcode | ||
884 | * \retval unsigned | ||
885 | * See FLAC__seekable_stream_encoder_set_max_residual_partition_order(). | ||
886 | */ | ||
887 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder); | ||
888 | |||
889 | /** Get the Rice parameter search distance setting. | ||
890 | * This is inherited from FLAC__StreamEncoder; see | ||
891 | * FLAC__stream_encoder_get_rice_parameter_search_dist(). | ||
892 | * | ||
893 | * \param encoder An encoder instance to query. | ||
894 | * \assert | ||
895 | * \code encoder != NULL \endcode | ||
896 | * \retval unsigned | ||
897 | * See FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(). | ||
898 | */ | ||
899 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder); | ||
900 | |||
901 | /** Get the previously set estimate of the total samples to be encoded. | ||
902 | * This is inherited from FLAC__StreamEncoder; see | ||
903 | * FLAC__stream_encoder_get_total_samples_estimate(). | ||
904 | * | ||
905 | * \param encoder An encoder instance to query. | ||
906 | * \assert | ||
907 | * \code encoder != NULL \endcode | ||
908 | * \retval FLAC__uint64 | ||
909 | * See FLAC__seekable_stream_encoder_set_total_samples_estimate(). | ||
910 | */ | ||
911 | FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder); | ||
912 | |||
913 | /** Initialize the encoder instance. | ||
914 | * Should be called after FLAC__seekable_stream_encoder_new() and | ||
915 | * FLAC__seekable_stream_encoder_set_*() but before FLAC__seekable_stream_encoder_process() | ||
916 | * or FLAC__seekable_stream_encoder_process_interleaved(). Will set and return | ||
917 | * the encoder state, which will be FLAC__SEEKABLE_STREAM_ENCODER_OK if | ||
918 | * initialization succeeded. | ||
919 | * | ||
920 | * The call to FLAC__seekable_stream_encoder_init() currently will also immediately | ||
921 | * call the write callback with the \c fLaC signature and all the encoded | ||
922 | * metadata. | ||
923 | * | ||
924 | * \param encoder An uninitialized encoder instance. | ||
925 | * \assert | ||
926 | * \code encoder != NULL \endcode | ||
927 | * \retval FLAC__SeekableStreamEncoderState | ||
928 | * \c FLAC__SEEKABLE_STREAM_ENCODER_OK if initialization was successful; see | ||
929 | * FLAC__SeekableStreamEncoderState for the meanings of other return values. | ||
930 | */ | ||
931 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder); | ||
932 | |||
933 | /** Finish the encoding process. | ||
934 | * Flushes the encoding buffer, releases resources, resets the encoder | ||
935 | * settings to their defaults, and returns the encoder state to | ||
936 | * FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED. | ||
937 | * | ||
938 | * In the event of a prematurely-terminated encode, it is not strictly | ||
939 | * necessary to call this immediately before FLAC__seekable_stream_encoder_delete() | ||
940 | * but it is good practice to match every FLAC__seekable_stream_encoder_init() | ||
941 | * with a FLAC__seekable_stream_encoder_finish(). | ||
942 | * | ||
943 | * \param encoder An uninitialized encoder instance. | ||
944 | * \assert | ||
945 | * \code encoder != NULL \endcode | ||
946 | */ | ||
947 | FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder); | ||
948 | |||
949 | /** Submit data for encoding. | ||
950 | * This is inherited from FLAC__StreamEncoder; see | ||
951 | * FLAC__stream_encoder_process(). | ||
952 | * | ||
953 | * \param encoder An initialized encoder instance in the OK state. | ||
954 | * \param buffer An array of pointers to each channel's signal. | ||
955 | * \param samples The number of samples in one channel. | ||
956 | * \assert | ||
957 | * \code encoder != NULL \endcode | ||
958 | * \code FLAC__seekable_stream_encoder_get_state(encoder) == FLAC__SEEKABLE_STREAM_ENCODER_OK \endcode | ||
959 | * \retval FLAC__bool | ||
960 | * \c true if successful, else \c false; in this case, check the | ||
961 | * encoder state with FLAC__seekable_stream_encoder_get_state() to see what | ||
962 | * went wrong. | ||
963 | */ | ||
964 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); | ||
965 | |||
966 | /** Submit data for encoding. | ||
967 | * This is inherited from FLAC__StreamEncoder; see | ||
968 | * FLAC__stream_encoder_process_interleaved(). | ||
969 | * | ||
970 | * \param encoder An initialized encoder instance in the OK state. | ||
971 | * \param buffer An array of channel-interleaved data (see above). | ||
972 | * \param samples The number of samples in one channel, the same as for | ||
973 | * FLAC__seekable_stream_encoder_process(). For example, if | ||
974 | * encoding two channels, \c 1000 \a samples corresponds | ||
975 | * to a \a buffer of 2000 values. | ||
976 | * \assert | ||
977 | * \code encoder != NULL \endcode | ||
978 | * \code FLAC__seekable_stream_encoder_get_state(encoder) == FLAC__SEEKABLE_STREAM_ENCODER_OK \endcode | ||
979 | * \retval FLAC__bool | ||
980 | * \c true if successful, else \c false; in this case, check the | ||
981 | * encoder state with FLAC__seekable_stream_encoder_get_state() to see what | ||
982 | * went wrong. | ||
983 | */ | ||
984 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); | ||
985 | |||
986 | /* \} */ | ||
987 | |||
988 | #ifdef __cplusplus | ||
989 | } | ||
990 | #endif | ||
991 | |||
992 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/stream_decoder.h b/apps/codecs/libFLAC/include/FLAC/stream_decoder.h new file mode 100644 index 0000000000..6cd59d42a9 --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/stream_decoder.h | |||
@@ -0,0 +1,873 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__STREAM_DECODER_H | ||
33 | #define FLAC__STREAM_DECODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "format.h" | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | extern "C" { | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /** \file include/FLAC/stream_decoder.h | ||
44 | * | ||
45 | * \brief | ||
46 | * This module contains the functions which implement the stream | ||
47 | * decoder. | ||
48 | * | ||
49 | * See the detailed documentation in the | ||
50 | * \link flac_stream_decoder stream decoder \endlink module. | ||
51 | */ | ||
52 | |||
53 | /** \defgroup flac_decoder FLAC/ *_decoder.h: decoder interfaces | ||
54 | * \ingroup flac | ||
55 | * | ||
56 | * \brief | ||
57 | * This module describes the three decoder layers provided by libFLAC. | ||
58 | * | ||
59 | * For decoding FLAC streams, libFLAC provides three layers of access. The | ||
60 | * lowest layer is non-seekable stream-level decoding, the next is seekable | ||
61 | * stream-level decoding, and the highest layer is file-level decoding. The | ||
62 | * interfaces are described in the \link flac_stream_decoder stream decoder | ||
63 | * \endlink, \link flac_seekable_stream_decoder seekable stream decoder | ||
64 | * \endlink, and \link flac_file_decoder file decoder \endlink modules | ||
65 | * respectively. Typically you will choose the highest layer that your input | ||
66 | * source will support. | ||
67 | * | ||
68 | * The stream decoder relies on callbacks for all input and output and has no | ||
69 | * provisions for seeking. The seekable stream decoder wraps the stream | ||
70 | * decoder and exposes functions for seeking. However, you must provide | ||
71 | * extra callbacks for seek-related operations on your stream, like seek and | ||
72 | * tell. The file decoder wraps the seekable stream decoder and supplies | ||
73 | * most of the callbacks internally, simplifying the processing of standard | ||
74 | * files. | ||
75 | */ | ||
76 | |||
77 | /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface | ||
78 | * \ingroup flac_decoder | ||
79 | * | ||
80 | * \brief | ||
81 | * This module contains the functions which implement the stream | ||
82 | * decoder. | ||
83 | * | ||
84 | * The basic usage of this decoder is as follows: | ||
85 | * - The program creates an instance of a decoder using | ||
86 | * FLAC__stream_decoder_new(). | ||
87 | * - The program overrides the default settings and sets callbacks for | ||
88 | * reading, writing, error reporting, and metadata reporting using | ||
89 | * FLAC__stream_decoder_set_*() functions. | ||
90 | * - The program initializes the instance to validate the settings and | ||
91 | * prepare for decoding using FLAC__stream_decoder_init(). | ||
92 | * - The program calls the FLAC__stream_decoder_process_*() functions | ||
93 | * to decode data, which subsequently calls the callbacks. | ||
94 | * - The program finishes the decoding with FLAC__stream_decoder_finish(), | ||
95 | * which flushes the input and output and resets the decoder to the | ||
96 | * uninitialized state. | ||
97 | * - The instance may be used again or deleted with | ||
98 | * FLAC__stream_decoder_delete(). | ||
99 | * | ||
100 | * In more detail, the program will create a new instance by calling | ||
101 | * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() | ||
102 | * functions to set the callbacks and client data, and call | ||
103 | * FLAC__stream_decoder_init(). The required callbacks are: | ||
104 | * | ||
105 | * - Read callback - This function will be called when the decoder needs | ||
106 | * more input data. The address of the buffer to be filled is supplied, | ||
107 | * along with the number of bytes the buffer can hold. The callback may | ||
108 | * choose to supply less data and modify the byte count but must be careful | ||
109 | * not to overflow the buffer. The callback then returns a status code | ||
110 | * chosen from FLAC__StreamDecoderReadStatus. | ||
111 | * - Write callback - This function will be called when the decoder has | ||
112 | * decoded a single frame of data. The decoder will pass the frame | ||
113 | * metadata as well as an array of pointers (one for each channel) | ||
114 | * pointing to the decoded audio. | ||
115 | * - Metadata callback - This function will be called when the decoder has | ||
116 | * decoded a metadata block. In a valid FLAC file there will always be | ||
117 | * one STREAMINFO block, followed by zero or more other metadata | ||
118 | * blocks. These will be supplied by the decoder in the same order as | ||
119 | * they appear in the stream and always before the first audio frame | ||
120 | * (i.e. write callback). The metadata block that is passed in must not | ||
121 | * be modified, and it doesn't live beyond the callback, so you should | ||
122 | * make a copy of it with FLAC__metadata_object_clone() if you will need | ||
123 | * it elsewhere. Since metadata blocks can potentially be large, by | ||
124 | * default the decoder only calls the metadata callback for the STREAMINFO | ||
125 | * block; you can instruct the decoder to pass or filter other blocks with | ||
126 | * FLAC__stream_decoder_set_metadata_*() calls. | ||
127 | * - Error callback - This function will be called whenever an error occurs | ||
128 | * during decoding. | ||
129 | * | ||
130 | * Once the decoder is initialized, your program will call one of several | ||
131 | * functions to start the decoding process: | ||
132 | * | ||
133 | * - FLAC__stream_decoder_process_single() - Tells the decoder to process at | ||
134 | * most one metadata block or audio frame and return, calling either the | ||
135 | * metadata callback or write callback, respectively, once. If the decoder | ||
136 | * loses sync it will return with only the error callback being called. | ||
137 | * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder | ||
138 | * to process the stream from the current location and stop upon reaching | ||
139 | * the first audio frame. The user will get one metadata, write, or error | ||
140 | * callback per metadata block, audio frame, or sync error, respectively. | ||
141 | * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder | ||
142 | * to process the stream from the current location until the read callback | ||
143 | * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or | ||
144 | * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The user will get one metadata, | ||
145 | * write, or error callback per metadata block, audio frame, or sync error, | ||
146 | * respectively. | ||
147 | * | ||
148 | * When the decoder has finished decoding (normally or through an abort), | ||
149 | * the instance is finished by calling FLAC__stream_decoder_finish(), which | ||
150 | * ensures the decoder is in the correct state and frees memory. Then the | ||
151 | * instance may be deleted with FLAC__stream_decoder_delete() or initialized | ||
152 | * again to decode another stream. | ||
153 | * | ||
154 | * Note that the stream decoder has no real concept of stream position, it | ||
155 | * just converts data. To seek within a stream the callbacks have only to | ||
156 | * flush the decoder using FLAC__stream_decoder_flush() and start feeding | ||
157 | * data from the new position through the read callback. The seekable | ||
158 | * stream decoder does just this. | ||
159 | * | ||
160 | * The FLAC__stream_decoder_set_metadata_*() functions deserve special | ||
161 | * attention. By default, the decoder only calls the metadata_callback for | ||
162 | * the STREAMINFO block. These functions allow you to tell the decoder | ||
163 | * explicitly which blocks to parse and return via the metadata_callback | ||
164 | * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), | ||
165 | * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), | ||
166 | * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify which | ||
167 | * blocks to return. Remember that some metadata blocks can be big so | ||
168 | * filtering out the ones you don't use can reduce the memory requirements | ||
169 | * of the decoder. Also note the special forms | ||
170 | * FLAC__stream_decoder_set_metadata_respond_application(id) and | ||
171 | * FLAC__stream_decoder_set_metadata_ignore_application(id) for filtering APPLICATION | ||
172 | * blocks based on the application ID. | ||
173 | * | ||
174 | * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but | ||
175 | * they still can legally be filtered from the metadata_callback. | ||
176 | * | ||
177 | * \note | ||
178 | * The "set" functions may only be called when the decoder is in the | ||
179 | * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after | ||
180 | * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but | ||
181 | * before FLAC__stream_decoder_init(). If this is the case they will | ||
182 | * return \c true, otherwise \c false. | ||
183 | * | ||
184 | * \note | ||
185 | * FLAC__stream_decoder_finish() resets all settings to the constructor | ||
186 | * defaults, including the callbacks. | ||
187 | * | ||
188 | * \{ | ||
189 | */ | ||
190 | |||
191 | |||
192 | /** State values for a FLAC__StreamDecoder | ||
193 | * | ||
194 | * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). | ||
195 | */ | ||
196 | typedef enum { | ||
197 | |||
198 | FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, | ||
199 | /**< The decoder is ready to search for metadata. */ | ||
200 | |||
201 | FLAC__STREAM_DECODER_READ_METADATA, | ||
202 | /**< The decoder is ready to or is in the process of reading metadata. */ | ||
203 | |||
204 | FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, | ||
205 | /**< The decoder is ready to or is in the process of searching for the frame sync code. */ | ||
206 | |||
207 | FLAC__STREAM_DECODER_READ_FRAME, | ||
208 | /**< The decoder is ready to or is in the process of reading a frame. */ | ||
209 | |||
210 | FLAC__STREAM_DECODER_END_OF_STREAM, | ||
211 | /**< The decoder has reached the end of the stream. */ | ||
212 | |||
213 | FLAC__STREAM_DECODER_ABORTED, | ||
214 | /**< The decoder was aborted by the read callback. */ | ||
215 | |||
216 | FLAC__STREAM_DECODER_UNPARSEABLE_STREAM, | ||
217 | /**< The decoder encountered reserved fields in use in the stream. */ | ||
218 | |||
219 | FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, | ||
220 | /**< An error occurred allocating memory. */ | ||
221 | |||
222 | FLAC__STREAM_DECODER_ALREADY_INITIALIZED, | ||
223 | /**< FLAC__stream_decoder_init() was called when the decoder was | ||
224 | * already initialized, usually because | ||
225 | * FLAC__stream_decoder_finish() was not called. | ||
226 | */ | ||
227 | |||
228 | FLAC__STREAM_DECODER_INVALID_CALLBACK, | ||
229 | /**< FLAC__stream_decoder_init() was called without all callbacks being set. */ | ||
230 | |||
231 | FLAC__STREAM_DECODER_UNINITIALIZED | ||
232 | /**< The decoder is in the uninitialized state. */ | ||
233 | |||
234 | } FLAC__StreamDecoderState; | ||
235 | |||
236 | /** Maps a FLAC__StreamDecoderState to a C string. | ||
237 | * | ||
238 | * Using a FLAC__StreamDecoderState as the index to this array | ||
239 | * will give the string equivalent. The contents should not be modified. | ||
240 | */ | ||
241 | extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; | ||
242 | |||
243 | |||
244 | /** Return values for the FLAC__StreamDecoder read callback. | ||
245 | */ | ||
246 | typedef enum { | ||
247 | |||
248 | FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, | ||
249 | /**< The read was OK and decoding can continue. */ | ||
250 | |||
251 | FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, | ||
252 | /**< The read was attempted at the end of the stream. */ | ||
253 | |||
254 | FLAC__STREAM_DECODER_READ_STATUS_ABORT | ||
255 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
256 | |||
257 | } FLAC__StreamDecoderReadStatus; | ||
258 | |||
259 | /** Maps a FLAC__StreamDecoderReadStatus to a C string. | ||
260 | * | ||
261 | * Using a FLAC__StreamDecoderReadStatus as the index to this array | ||
262 | * will give the string equivalent. The contents should not be modified. | ||
263 | */ | ||
264 | extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; | ||
265 | |||
266 | |||
267 | /** Return values for the FLAC__StreamDecoder write callback. | ||
268 | */ | ||
269 | typedef enum { | ||
270 | |||
271 | FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, | ||
272 | /**< The write was OK and decoding can continue. */ | ||
273 | |||
274 | FLAC__STREAM_DECODER_WRITE_STATUS_ABORT | ||
275 | /**< An unrecoverable error occurred. The decoder will return from the process call. */ | ||
276 | |||
277 | } FLAC__StreamDecoderWriteStatus; | ||
278 | |||
279 | /** Maps a FLAC__StreamDecoderWriteStatus to a C string. | ||
280 | * | ||
281 | * Using a FLAC__StreamDecoderWriteStatus as the index to this array | ||
282 | * will give the string equivalent. The contents should not be modified. | ||
283 | */ | ||
284 | extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; | ||
285 | |||
286 | |||
287 | /** Possible values passed in to the FLAC__StreamDecoder error callback. | ||
288 | */ | ||
289 | typedef enum { | ||
290 | |||
291 | FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, | ||
292 | /**< An error in the stream caused the decoder to lose synchronization. */ | ||
293 | |||
294 | FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, | ||
295 | /**< The decoder encountered a corrupted frame header. */ | ||
296 | |||
297 | FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH | ||
298 | /**< The frame's data did not match the CRC in the footer. */ | ||
299 | |||
300 | } FLAC__StreamDecoderErrorStatus; | ||
301 | |||
302 | /** Maps a FLAC__StreamDecoderErrorStatus to a C string. | ||
303 | * | ||
304 | * Using a FLAC__StreamDecoderErrorStatus as the index to this array | ||
305 | * will give the string equivalent. The contents should not be modified. | ||
306 | */ | ||
307 | extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; | ||
308 | |||
309 | |||
310 | /*********************************************************************** | ||
311 | * | ||
312 | * class FLAC__StreamDecoder | ||
313 | * | ||
314 | ***********************************************************************/ | ||
315 | |||
316 | struct FLAC__StreamDecoderProtected; | ||
317 | struct FLAC__StreamDecoderPrivate; | ||
318 | /** The opaque structure definition for the stream decoder type. | ||
319 | * See the \link flac_stream_decoder stream decoder module \endlink | ||
320 | * for a detailed description. | ||
321 | */ | ||
322 | typedef struct { | ||
323 | struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
324 | struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
325 | } FLAC__StreamDecoder; | ||
326 | |||
327 | /** Signature for the read callback. | ||
328 | * See FLAC__stream_decoder_set_read_callback() for more info. | ||
329 | * | ||
330 | * \param decoder The decoder instance calling the callback. | ||
331 | * \param buffer A pointer to a location for the callee to store | ||
332 | * data to be decoded. | ||
333 | * \param bytes A pointer to the size of the buffer. On entry | ||
334 | * to the callback, it contains the maximum number | ||
335 | * of bytes that may be stored in \a buffer. The | ||
336 | * callee must set it to the actual number of bytes | ||
337 | * stored (0 in case of error or end-of-stream) before | ||
338 | * returning. | ||
339 | * \param client_data The callee's client data set through | ||
340 | * FLAC__stream_decoder_set_client_data(). | ||
341 | * \retval FLAC__StreamDecoderReadStatus | ||
342 | * The callee's return status. | ||
343 | */ | ||
344 | typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
345 | |||
346 | /** Signature for the write callback. | ||
347 | * See FLAC__stream_decoder_set_write_callback() for more info. | ||
348 | * | ||
349 | * \param decoder The decoder instance calling the callback. | ||
350 | * \param frame The description of the decoded frame. See | ||
351 | * FLAC__Frame. | ||
352 | * \param buffer An array of pointers to decoded channels of data. | ||
353 | * Each pointer will point to an array of signed | ||
354 | * samples of length \a frame->header.blocksize. | ||
355 | * Currently, the channel order has no meaning | ||
356 | * except for stereo streams; in this case channel | ||
357 | * 0 is left and 1 is right. | ||
358 | * \param client_data The callee's client data set through | ||
359 | * FLAC__stream_decoder_set_client_data(). | ||
360 | * \retval FLAC__StreamDecoderWriteStatus | ||
361 | * The callee's return status. | ||
362 | */ | ||
363 | typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
364 | |||
365 | /** Signature for the metadata callback. | ||
366 | * See FLAC__stream_decoder_set_metadata_callback() for more info. | ||
367 | * | ||
368 | * \param decoder The decoder instance calling the callback. | ||
369 | * \param metadata The decoded metadata block. | ||
370 | * \param client_data The callee's client data set through | ||
371 | * FLAC__stream_decoder_set_client_data(). | ||
372 | */ | ||
373 | typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
374 | |||
375 | /** Signature for the error callback. | ||
376 | * See FLAC__stream_decoder_set_error_callback() for more info. | ||
377 | * | ||
378 | * \param decoder The decoder instance calling the callback. | ||
379 | * \param status The error encountered by the decoder. | ||
380 | * \param client_data The callee's client data set through | ||
381 | * FLAC__stream_decoder_set_client_data(). | ||
382 | */ | ||
383 | typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
384 | |||
385 | |||
386 | /*********************************************************************** | ||
387 | * | ||
388 | * Class constructor/destructor | ||
389 | * | ||
390 | ***********************************************************************/ | ||
391 | |||
392 | /** Create a new stream decoder instance. The instance is created with | ||
393 | * default settings; see the individual FLAC__stream_decoder_set_*() | ||
394 | * functions for each setting's default. | ||
395 | * | ||
396 | * \retval FLAC__StreamDecoder* | ||
397 | * \c NULL if there was an error allocating memory, else the new instance. | ||
398 | */ | ||
399 | FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(); | ||
400 | |||
401 | /** Free a decoder instance. Deletes the object pointed to by \a decoder. | ||
402 | * | ||
403 | * \param decoder A pointer to an existing decoder. | ||
404 | * \assert | ||
405 | * \code decoder != NULL \endcode | ||
406 | */ | ||
407 | FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); | ||
408 | |||
409 | |||
410 | /*********************************************************************** | ||
411 | * | ||
412 | * Public class method prototypes | ||
413 | * | ||
414 | ***********************************************************************/ | ||
415 | |||
416 | /** Set the read callback. | ||
417 | * The supplied function will be called when the decoder needs more input | ||
418 | * data. The address of the buffer to be filled is supplied, along with | ||
419 | * the number of bytes the buffer can hold. The callback may choose to | ||
420 | * supply less data and modify the byte count but must be careful not to | ||
421 | * overflow the buffer. The callback then returns a status code chosen | ||
422 | * from FLAC__StreamDecoderReadStatus. | ||
423 | * | ||
424 | * \note | ||
425 | * The callback is mandatory and must be set before initialization. | ||
426 | * | ||
427 | * \default \c NULL | ||
428 | * \param decoder A decoder instance to set. | ||
429 | * \param value See above. | ||
430 | * \assert | ||
431 | * \code decoder != NULL \endcode | ||
432 | * \code value != NULL \endcode | ||
433 | * \retval FLAC__bool | ||
434 | * \c false if the decoder is already initialized, else \c true. | ||
435 | */ | ||
436 | FLAC_API FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback value); | ||
437 | |||
438 | /** Set the write callback. | ||
439 | * The supplied function will be called when the decoder has decoded a | ||
440 | * single frame of data. The decoder will pass the frame metadata as | ||
441 | * well as an array of pointers (one for each channel) pointing to the | ||
442 | * decoded audio. | ||
443 | * | ||
444 | * \note | ||
445 | * The callback is mandatory and must be set before initialization. | ||
446 | * | ||
447 | * \default \c NULL | ||
448 | * \param decoder A decoder instance to set. | ||
449 | * \param value See above. | ||
450 | * \assert | ||
451 | * \code decoder != NULL \endcode | ||
452 | * \code value != NULL \endcode | ||
453 | * \retval FLAC__bool | ||
454 | * \c false if the decoder is already initialized, else \c true. | ||
455 | */ | ||
456 | FLAC_API FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteCallback value); | ||
457 | |||
458 | /** Set the metadata callback. | ||
459 | * The supplied function will be called when the decoder has decoded a metadata | ||
460 | * block. In a valid FLAC file there will always be one STREAMINFO block, | ||
461 | * followed by zero or more other metadata blocks. These will be supplied | ||
462 | * by the decoder in the same order as they appear in the stream and always | ||
463 | * before the first audio frame (i.e. write callback). The metadata block | ||
464 | * that is passed in must not be modified, and it doesn't live beyond the | ||
465 | * callback, so you should make a copy of it with | ||
466 | * FLAC__metadata_object_clone() if you will need it elsewhere. Since | ||
467 | * metadata blocks can potentially be large, by default the decoder only | ||
468 | * calls the metadata callback for the STREAMINFO block; you can instruct | ||
469 | * the decoder to pass or filter other blocks with | ||
470 | * FLAC__stream_decoder_set_metadata_*() calls. | ||
471 | * | ||
472 | * \note | ||
473 | * The callback is mandatory and must be set before initialization. | ||
474 | * | ||
475 | * \default \c NULL | ||
476 | * \param decoder A decoder instance to set. | ||
477 | * \param value See above. | ||
478 | * \assert | ||
479 | * \code decoder != NULL \endcode | ||
480 | * \code value != NULL \endcode | ||
481 | * \retval FLAC__bool | ||
482 | * \c false if the decoder is already initialized, else \c true. | ||
483 | */ | ||
484 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderMetadataCallback value); | ||
485 | |||
486 | /** Set the error callback. | ||
487 | * The supplied function will be called whenever an error occurs during | ||
488 | * decoding. | ||
489 | * | ||
490 | * \note | ||
491 | * The callback is mandatory and must be set before initialization. | ||
492 | * | ||
493 | * \default \c NULL | ||
494 | * \param decoder A decoder instance to set. | ||
495 | * \param value See above. | ||
496 | * \assert | ||
497 | * \code decoder != NULL \endcode | ||
498 | * \code value != NULL \endcode | ||
499 | * \retval FLAC__bool | ||
500 | * \c false if the decoder is already initialized, else \c true. | ||
501 | */ | ||
502 | FLAC_API FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorCallback value); | ||
503 | |||
504 | /** Set the client data to be passed back to callbacks. | ||
505 | * This value will be supplied to callbacks in their \a client_data | ||
506 | * argument. | ||
507 | * | ||
508 | * \default \c NULL | ||
509 | * \param decoder A decoder instance to set. | ||
510 | * \param value See above. | ||
511 | * \assert | ||
512 | * \code decoder != NULL \endcode | ||
513 | * \retval FLAC__bool | ||
514 | * \c false if the decoder is already initialized, else \c true. | ||
515 | */ | ||
516 | FLAC_API FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value); | ||
517 | |||
518 | /** Direct the decoder to pass on all metadata blocks of type \a type. | ||
519 | * | ||
520 | * \default By default, only the \c STREAMINFO block is returned via the | ||
521 | * metadata callback. | ||
522 | * \param decoder A decoder instance to set. | ||
523 | * \param type See above. | ||
524 | * \assert | ||
525 | * \code decoder != NULL \endcode | ||
526 | * \a type is valid | ||
527 | * \retval FLAC__bool | ||
528 | * \c false if the decoder is already initialized, else \c true. | ||
529 | */ | ||
530 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); | ||
531 | |||
532 | /** Direct the decoder to pass on all APPLICATION metadata blocks of the | ||
533 | * given \a id. | ||
534 | * | ||
535 | * \default By default, only the \c STREAMINFO block is returned via the | ||
536 | * metadata callback. | ||
537 | * \param decoder A decoder instance to set. | ||
538 | * \param id See above. | ||
539 | * \assert | ||
540 | * \code decoder != NULL \endcode | ||
541 | * \code id != NULL \endcode | ||
542 | * \retval FLAC__bool | ||
543 | * \c false if the decoder is already initialized, else \c true. | ||
544 | */ | ||
545 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); | ||
546 | |||
547 | /** Direct the decoder to pass on all metadata blocks of any type. | ||
548 | * | ||
549 | * \default By default, only the \c STREAMINFO block is returned via the | ||
550 | * metadata callback. | ||
551 | * \param decoder A decoder instance to set. | ||
552 | * \assert | ||
553 | * \code decoder != NULL \endcode | ||
554 | * \retval FLAC__bool | ||
555 | * \c false if the decoder is already initialized, else \c true. | ||
556 | */ | ||
557 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); | ||
558 | |||
559 | /** Direct the decoder to filter out all metadata blocks of type \a type. | ||
560 | * | ||
561 | * \default By default, only the \c STREAMINFO block is returned via the | ||
562 | * metadata callback. | ||
563 | * \param decoder A decoder instance to set. | ||
564 | * \param type See above. | ||
565 | * \assert | ||
566 | * \code decoder != NULL \endcode | ||
567 | * \a type is valid | ||
568 | * \retval FLAC__bool | ||
569 | * \c false if the decoder is already initialized, else \c true. | ||
570 | */ | ||
571 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); | ||
572 | |||
573 | /** Direct the decoder to filter out all APPLICATION metadata blocks of | ||
574 | * the given \a id. | ||
575 | * | ||
576 | * \default By default, only the \c STREAMINFO block is returned via the | ||
577 | * metadata callback. | ||
578 | * \param decoder A decoder instance to set. | ||
579 | * \param id See above. | ||
580 | * \assert | ||
581 | * \code decoder != NULL \endcode | ||
582 | * \code id != NULL \endcode | ||
583 | * \retval FLAC__bool | ||
584 | * \c false if the decoder is already initialized, else \c true. | ||
585 | */ | ||
586 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); | ||
587 | |||
588 | /** Direct the decoder to filter out all metadata blocks of any type. | ||
589 | * | ||
590 | * \default By default, only the \c STREAMINFO block is returned via the | ||
591 | * metadata callback. | ||
592 | * \param decoder A decoder instance to set. | ||
593 | * \assert | ||
594 | * \code decoder != NULL \endcode | ||
595 | * \retval FLAC__bool | ||
596 | * \c false if the decoder is already initialized, else \c true. | ||
597 | */ | ||
598 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); | ||
599 | |||
600 | /** Get the current decoder state. | ||
601 | * | ||
602 | * \param decoder A decoder instance to query. | ||
603 | * \assert | ||
604 | * \code decoder != NULL \endcode | ||
605 | * \retval FLAC__StreamDecoderState | ||
606 | * The current decoder state. | ||
607 | */ | ||
608 | FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); | ||
609 | |||
610 | /** Get the current decoder state as a C string. | ||
611 | * | ||
612 | * \param decoder A decoder instance to query. | ||
613 | * \assert | ||
614 | * \code decoder != NULL \endcode | ||
615 | * \retval const char * | ||
616 | * The decoder state as a C string. Do not modify the contents. | ||
617 | */ | ||
618 | FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); | ||
619 | |||
620 | /** Get the current number of channels in the stream being decoded. | ||
621 | * Will only be valid after decoding has started and will contain the | ||
622 | * value from the most recently decoded frame header. | ||
623 | * | ||
624 | * \param decoder A decoder instance to query. | ||
625 | * \assert | ||
626 | * \code decoder != NULL \endcode | ||
627 | * \retval unsigned | ||
628 | * See above. | ||
629 | */ | ||
630 | FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); | ||
631 | |||
632 | /** Get the current channel assignment in the stream being decoded. | ||
633 | * Will only be valid after decoding has started and will contain the | ||
634 | * value from the most recently decoded frame header. | ||
635 | * | ||
636 | * \param decoder A decoder instance to query. | ||
637 | * \assert | ||
638 | * \code decoder != NULL \endcode | ||
639 | * \retval FLAC__ChannelAssignment | ||
640 | * See above. | ||
641 | */ | ||
642 | FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); | ||
643 | |||
644 | /** Get the current sample resolution in the stream being decoded. | ||
645 | * Will only be valid after decoding has started and will contain the | ||
646 | * value from the most recently decoded frame header. | ||
647 | * | ||
648 | * \param decoder A decoder instance to query. | ||
649 | * \assert | ||
650 | * \code decoder != NULL \endcode | ||
651 | * \retval unsigned | ||
652 | * See above. | ||
653 | */ | ||
654 | FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); | ||
655 | |||
656 | /** Get the current sample rate in Hz of the stream being decoded. | ||
657 | * Will only be valid after decoding has started and will contain the | ||
658 | * value from the most recently decoded frame header. | ||
659 | * | ||
660 | * \param decoder A decoder instance to query. | ||
661 | * \assert | ||
662 | * \code decoder != NULL \endcode | ||
663 | * \retval unsigned | ||
664 | * See above. | ||
665 | */ | ||
666 | FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); | ||
667 | |||
668 | /** Get the current blocksize of the stream being decoded. | ||
669 | * Will only be valid after decoding has started and will contain the | ||
670 | * value from the most recently decoded frame header. | ||
671 | * | ||
672 | * \param decoder A decoder instance to query. | ||
673 | * \assert | ||
674 | * \code decoder != NULL \endcode | ||
675 | * \retval unsigned | ||
676 | * See above. | ||
677 | */ | ||
678 | FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); | ||
679 | |||
680 | /** Initialize the decoder instance. | ||
681 | * Should be called after FLAC__stream_decoder_new() and | ||
682 | * FLAC__stream_decoder_set_*() but before any of the | ||
683 | * FLAC__stream_decoder_process_*() functions. Will set and return the | ||
684 | * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA | ||
685 | * if initialization succeeded. | ||
686 | * | ||
687 | * \param decoder An uninitialized decoder instance. | ||
688 | * \assert | ||
689 | * \code decoder != NULL \endcode | ||
690 | * \retval FLAC__StreamDecoderState | ||
691 | * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA if initialization was | ||
692 | * successful; see FLAC__StreamDecoderState for the meanings of other | ||
693 | * return values. | ||
694 | */ | ||
695 | FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder); | ||
696 | |||
697 | /** Finish the decoding process. | ||
698 | * Flushes the decoding buffer, releases resources, resets the decoder | ||
699 | * settings to their defaults, and returns the decoder state to | ||
700 | * FLAC__STREAM_DECODER_UNINITIALIZED. | ||
701 | * | ||
702 | * In the event of a prematurely-terminated decode, it is not strictly | ||
703 | * necessary to call this immediately before FLAC__stream_decoder_delete() | ||
704 | * but it is good practice to match every FLAC__stream_decoder_init() | ||
705 | * with a FLAC__stream_decoder_finish(). | ||
706 | * | ||
707 | * \param decoder An uninitialized decoder instance. | ||
708 | * \assert | ||
709 | * \code decoder != NULL \endcode | ||
710 | */ | ||
711 | FLAC_API void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); | ||
712 | |||
713 | /** Flush the stream input. | ||
714 | * The decoder's input buffer will be cleared and the state set to | ||
715 | * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. | ||
716 | * | ||
717 | * \param decoder A decoder instance. | ||
718 | * \assert | ||
719 | * \code decoder != NULL \endcode | ||
720 | * \retval FLAC__bool | ||
721 | * \c true if successful, else \c false if a memory allocation | ||
722 | * error occurs. | ||
723 | */ | ||
724 | FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); | ||
725 | |||
726 | /** Reset the decoding process. | ||
727 | * The decoder's input buffer will be cleared and the state set to | ||
728 | * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to | ||
729 | * FLAC__stream_decoder_finish() except that the settings are | ||
730 | * preserved; there is no need to call FLAC__stream_decoder_init() | ||
731 | * before decoding again. | ||
732 | * | ||
733 | * \param decoder A decoder instance. | ||
734 | * \assert | ||
735 | * \code decoder != NULL \endcode | ||
736 | * \retval FLAC__bool | ||
737 | * \c true if successful, else \c false if a memory allocation | ||
738 | * error occurs. | ||
739 | */ | ||
740 | FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); | ||
741 | |||
742 | /** Decode one metadata block or audio frame. | ||
743 | * This version instructs the decoder to decode a either a single metadata | ||
744 | * block or a single frame and stop, unless the callbacks return a fatal | ||
745 | * error or the read callback returns | ||
746 | * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. | ||
747 | * | ||
748 | * As the decoder needs more input it will call the read callback. | ||
749 | * Depending on what was decoded, the metadata or write callback will be | ||
750 | * called with the decoded metadata block or audio frame, unless an error | ||
751 | * occurred. If the decoder loses sync it will call the error callback | ||
752 | * instead. | ||
753 | * | ||
754 | * Unless there is a fatal read error or end of stream, this function | ||
755 | * will return once one whole frame is decoded. In other words, if the | ||
756 | * stream is not synchronized or points to a corrupt frame header, the | ||
757 | * decoder will continue to try and resync until it gets to a valid | ||
758 | * frame, then decode one frame, then return. If the decoder points to | ||
759 | * frame whose frame CRC in the frame footer does not match the | ||
760 | * computed frame CRC, this function will issue a | ||
761 | * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the | ||
762 | * error callback, and return, having decoded one complete, although | ||
763 | * corrupt, frame. (Such corrupted frames are sent as silence of the | ||
764 | * correct length to the write callback.) | ||
765 | * | ||
766 | * \param decoder An initialized decoder instance. | ||
767 | * \assert | ||
768 | * \code decoder != NULL \endcode | ||
769 | * \retval FLAC__bool | ||
770 | * \c false if any read or write error occurred (except | ||
771 | * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC), else \c true; | ||
772 | * in any case, check the decoder state with | ||
773 | * FLAC__stream_decoder_get_state() to see what went wrong or to | ||
774 | * check for lost synchronization (a sign of stream corruption). | ||
775 | */ | ||
776 | FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); | ||
777 | |||
778 | /** Decode until the end of the metadata. | ||
779 | * This version instructs the decoder to decode from the current position | ||
780 | * and continue until all the metadata has been read, or until the | ||
781 | * callbacks return a fatal error or the read callback returns | ||
782 | * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. | ||
783 | * | ||
784 | * As the decoder needs more input it will call the read callback. | ||
785 | * As each metadata block is decoded, the metadata callback will be called | ||
786 | * with the decoded metadata. If the decoder loses sync it will call the | ||
787 | * error callback. | ||
788 | * | ||
789 | * \param decoder An initialized decoder instance. | ||
790 | * \assert | ||
791 | * \code decoder != NULL \endcode | ||
792 | * \retval FLAC__bool | ||
793 | * \c false if any read or write error occurred (except | ||
794 | * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC), else \c true; | ||
795 | * in any case, check the decoder state with | ||
796 | * FLAC__stream_decoder_get_state() to see what went wrong or to | ||
797 | * check for lost synchronization (a sign of stream corruption). | ||
798 | */ | ||
799 | FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); | ||
800 | |||
801 | /** Decode until the end of the stream. | ||
802 | * This version instructs the decoder to decode from the current position | ||
803 | * and continue until the end of stream (the read callback returns | ||
804 | * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the | ||
805 | * callbacks return a fatal error. | ||
806 | * | ||
807 | * As the decoder needs more input it will call the read callback. | ||
808 | * As each metadata block and frame is decoded, the metadata or write | ||
809 | * callback will be called with the decoded metadata or frame. If the | ||
810 | * decoder loses sync it will call the error callback. | ||
811 | * | ||
812 | * \param decoder An initialized decoder instance. | ||
813 | * \assert | ||
814 | * \code decoder != NULL \endcode | ||
815 | * \retval FLAC__bool | ||
816 | * \c false if any read or write error occurred (except | ||
817 | * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC), else \c true; | ||
818 | * in any case, check the decoder state with | ||
819 | * FLAC__stream_decoder_get_state() to see what went wrong or to | ||
820 | * check for lost synchronization (a sign of stream corruption). | ||
821 | */ | ||
822 | FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); | ||
823 | |||
824 | /** Skip one audio frame. | ||
825 | * This version instructs the decoder to 'skip' a single frame and stop, | ||
826 | * unless the callbacks return a fatal error or the read callback returns | ||
827 | * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. | ||
828 | * | ||
829 | * The decoding flow is the same as what occurs when | ||
830 | * FLAC__stream_decoder_process_single() is called to process an audio | ||
831 | * frame, except that this function does not decode the parsed data into | ||
832 | * PCM or call the write callback. The integrity of the frame is still | ||
833 | * checked the same way as in the other process functions. | ||
834 | * | ||
835 | * This function will return once one whole frame is skipped, in the | ||
836 | * same way that FLAC__stream_decoder_process_single() will return once | ||
837 | * one whole frame is decoded. | ||
838 | * | ||
839 | * This function, when used from the higher FLAC__SeekableStreamDecoder | ||
840 | * layer, can be used in more quickly determining FLAC frame boundaries | ||
841 | * when decoding of the actual data is not needed, for example when an | ||
842 | * application is separating a FLAC stream into frames for editing or | ||
843 | * storing in a container. To do this, the application can use | ||
844 | * FLAC__seekable_stream_decoder_skip_single_frame() to quickly advance | ||
845 | * to the next frame, then use | ||
846 | * FLAC__seekable_stream_decoder_get_decode_position() to find the new | ||
847 | * frame boundary. | ||
848 | * | ||
849 | * This function should only be called when the stream has advanced | ||
850 | * past all the metadata, otherwise it will return \c false. | ||
851 | * | ||
852 | * \param decoder An initialized decoder instance not in a metadata | ||
853 | * state. | ||
854 | * \assert | ||
855 | * \code decoder != NULL \endcode | ||
856 | * \retval FLAC__bool | ||
857 | * \c false if any read or write error occurred (except | ||
858 | * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC), or if the decoder | ||
859 | * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or | ||
860 | * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; | ||
861 | * in any case, check the decoder state with | ||
862 | * FLAC__stream_decoder_get_state() to see what went wrong or to | ||
863 | * check for lost synchronization (a sign of stream corruption). | ||
864 | */ | ||
865 | FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); | ||
866 | |||
867 | /* \} */ | ||
868 | |||
869 | #ifdef __cplusplus | ||
870 | } | ||
871 | #endif | ||
872 | |||
873 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/FLAC/stream_encoder.h b/apps/codecs/libFLAC/include/FLAC/stream_encoder.h new file mode 100644 index 0000000000..0ac18a365d --- /dev/null +++ b/apps/codecs/libFLAC/include/FLAC/stream_encoder.h | |||
@@ -0,0 +1,1064 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__STREAM_ENCODER_H | ||
33 | #define FLAC__STREAM_ENCODER_H | ||
34 | |||
35 | #include "export.h" | ||
36 | #include "format.h" | ||
37 | #include "stream_decoder.h" | ||
38 | |||
39 | #ifdef __cplusplus | ||
40 | extern "C" { | ||
41 | #endif | ||
42 | |||
43 | |||
44 | /** \file include/FLAC/stream_encoder.h | ||
45 | * | ||
46 | * \brief | ||
47 | * This module contains the functions which implement the stream | ||
48 | * encoder. | ||
49 | * | ||
50 | * See the detailed documentation in the | ||
51 | * \link flac_stream_encoder stream encoder \endlink module. | ||
52 | */ | ||
53 | |||
54 | /** \defgroup flac_encoder FLAC/ *_encoder.h: encoder interfaces | ||
55 | * \ingroup flac | ||
56 | * | ||
57 | * \brief | ||
58 | * This module describes the two encoder layers provided by libFLAC. | ||
59 | * | ||
60 | * For encoding FLAC streams, libFLAC provides three layers of access. The | ||
61 | * lowest layer is non-seekable stream-level encoding, the next is seekable | ||
62 | * stream-level encoding, and the highest layer is file-level encoding. The | ||
63 | * interfaces are described in the \link flac_stream_encoder stream encoder | ||
64 | * \endlink, \link flac_seekable_stream_encoder seekable stream encoder | ||
65 | * \endlink, and \link flac_file_encoder file encoder \endlink modules | ||
66 | * respectively. Typically you will choose the highest layer that your input | ||
67 | * source will support. | ||
68 | * The stream encoder relies on callbacks for writing the data and | ||
69 | * metadata. The file encoder provides these callbacks internally and you | ||
70 | * need only supply the filename. | ||
71 | * | ||
72 | * The stream encoder relies on callbacks for writing the data and has no | ||
73 | * provisions for seeking the output. The seekable stream encoder wraps | ||
74 | * the stream encoder and also automaticallay handles the writing back of | ||
75 | * metadata discovered while encoding. However, you must provide extra | ||
76 | * callbacks for seek-related operations on your output, like seek and | ||
77 | * tell. The file encoder wraps the seekable stream encoder and supplies | ||
78 | * all of the callbacks internally, simplifying the processing of standard | ||
79 | * files. The only callback exposed is for progress reporting, and that | ||
80 | * is optional. | ||
81 | */ | ||
82 | |||
83 | /** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface | ||
84 | * \ingroup flac_encoder | ||
85 | * | ||
86 | * \brief | ||
87 | * This module contains the functions which implement the stream | ||
88 | * encoder. | ||
89 | * | ||
90 | * The basic usage of this encoder is as follows: | ||
91 | * - The program creates an instance of an encoder using | ||
92 | * FLAC__stream_encoder_new(). | ||
93 | * - The program overrides the default settings and sets callbacks using | ||
94 | * FLAC__stream_encoder_set_*() functions. | ||
95 | * - The program initializes the instance to validate the settings and | ||
96 | * prepare for encoding using FLAC__stream_encoder_init(). | ||
97 | * - The program calls FLAC__stream_encoder_process() or | ||
98 | * FLAC__stream_encoder_process_interleaved() to encode data, which | ||
99 | * subsequently calls the callbacks when there is encoder data ready | ||
100 | * to be written. | ||
101 | * - The program finishes the encoding with FLAC__stream_encoder_finish(), | ||
102 | * which causes the encoder to encode any data still in its input pipe, | ||
103 | * call the metadata callback with the final encoding statistics, and | ||
104 | * finally reset the encoder to the uninitialized state. | ||
105 | * - The instance may be used again or deleted with | ||
106 | * FLAC__stream_encoder_delete(). | ||
107 | * | ||
108 | * In more detail, the stream encoder functions similarly to the | ||
109 | * \link flac_stream_decoder stream decoder \endlink, but has fewer | ||
110 | * callbacks and more options. Typically the user will create a new | ||
111 | * instance by calling FLAC__stream_encoder_new(), then set the necessary | ||
112 | * parameters and callbacks with FLAC__stream_encoder_set_*(), and | ||
113 | * initialize it by calling FLAC__stream_encoder_init(). | ||
114 | * | ||
115 | * Unlike the decoders, the stream encoder has many options that can | ||
116 | * affect the speed and compression ratio. When setting these parameters | ||
117 | * you should have some basic knowledge of the format (see the | ||
118 | * <A HREF="../documentation.html#format">user-level documentation</A> | ||
119 | * or the <A HREF="../format.html">formal description</A>). The | ||
120 | * FLAC__stream_encoder_set_*() functions themselves do not validate the | ||
121 | * values as many are interdependent. The FLAC__stream_encoder_init() | ||
122 | * function will do this, so make sure to pay attention to the state | ||
123 | * returned by FLAC__stream_encoder_init() to make sure that it is | ||
124 | * FLAC__STREAM_ENCODER_OK. Any parameters that are not set before | ||
125 | * FLAC__stream_encoder_init() will take on the defaults from the | ||
126 | * constructor. | ||
127 | * | ||
128 | * The user must provide function pointers for the following callbacks: | ||
129 | * | ||
130 | * - Write callback - This function is called by the encoder anytime there | ||
131 | * is raw encoded data to write. It may include metadata mixed with | ||
132 | * encoded audio frames and the data is not guaranteed to be aligned on | ||
133 | * frame or metadata block boundaries. | ||
134 | * - Metadata callback - This function is called once at the end of | ||
135 | * encoding with the populated STREAMINFO structure. This is so file | ||
136 | * encoders can seek back to the beginning of the file and write the | ||
137 | * STREAMINFO block with the correct statistics after encoding (like | ||
138 | * minimum/maximum frame size). | ||
139 | * | ||
140 | * The call to FLAC__stream_encoder_init() currently will also immediately | ||
141 | * call the write callback several times, once with the \c fLaC signature, | ||
142 | * and once for each encoded metadata block. | ||
143 | * | ||
144 | * After initializing the instance, the user may feed audio data to the | ||
145 | * encoder in one of two ways: | ||
146 | * | ||
147 | * - Channel separate, through FLAC__stream_encoder_process() - The user | ||
148 | * will pass an array of pointers to buffers, one for each channel, to | ||
149 | * the encoder, each of the same length. The samples need not be | ||
150 | * block-aligned. | ||
151 | * - Channel interleaved, through | ||
152 | * FLAC__stream_encoder_process_interleaved() - The user will pass a single | ||
153 | * pointer to data that is channel-interleaved (i.e. channel0_sample0, | ||
154 | * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). | ||
155 | * Again, the samples need not be block-aligned but they must be | ||
156 | * sample-aligned, i.e. the first value should be channel0_sample0 and | ||
157 | * the last value channelN_sampleM. | ||
158 | * | ||
159 | * When the user is finished encoding data, it calls | ||
160 | * FLAC__stream_encoder_finish(), which causes the encoder to encode any | ||
161 | * data still in its input pipe, and call the metadata callback with the | ||
162 | * final encoding statistics. Then the instance may be deleted with | ||
163 | * FLAC__stream_encoder_delete() or initialized again to encode another | ||
164 | * stream. | ||
165 | * | ||
166 | * For programs that write their own metadata, but that do not know the | ||
167 | * actual metadata until after encoding, it is advantageous to instruct | ||
168 | * the encoder to write a PADDING block of the correct size, so that | ||
169 | * instead of rewriting the whole stream after encoding, the program can | ||
170 | * just overwrite the PADDING block. If only the maximum size of the | ||
171 | * metadata is known, the program can write a slightly larger padding | ||
172 | * block, then split it after encoding. | ||
173 | * | ||
174 | * Make sure you understand how lengths are calculated. All FLAC metadata | ||
175 | * blocks have a 4 byte header which contains the type and length. This | ||
176 | * length does not include the 4 bytes of the header. See the format page | ||
177 | * for the specification of metadata blocks and their lengths. | ||
178 | * | ||
179 | * \note | ||
180 | * The "set" functions may only be called when the encoder is in the | ||
181 | * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after | ||
182 | * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but | ||
183 | * before FLAC__stream_encoder_init(). If this is the case they will | ||
184 | * return \c true, otherwise \c false. | ||
185 | * | ||
186 | * \note | ||
187 | * FLAC__stream_encoder_finish() resets all settings to the constructor | ||
188 | * defaults, including the callbacks. | ||
189 | * | ||
190 | * \{ | ||
191 | */ | ||
192 | |||
193 | |||
194 | /** State values for a FLAC__StreamEncoder | ||
195 | * | ||
196 | * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state(). | ||
197 | */ | ||
198 | typedef enum { | ||
199 | |||
200 | FLAC__STREAM_ENCODER_OK = 0, | ||
201 | /**< The encoder is in the normal OK state. */ | ||
202 | |||
203 | FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR, | ||
204 | /**< An error occurred in the underlying verify stream decoder; | ||
205 | * check FLAC__stream_encoder_get_verify_decoder_state(). | ||
206 | */ | ||
207 | |||
208 | FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA, | ||
209 | /**< The verify decoder detected a mismatch between the original | ||
210 | * audio signal and the decoded audio signal. | ||
211 | */ | ||
212 | |||
213 | FLAC__STREAM_ENCODER_INVALID_CALLBACK, | ||
214 | /**< The encoder was initialized before setting all the required callbacks. */ | ||
215 | |||
216 | FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS, | ||
217 | /**< The encoder has an invalid setting for number of channels. */ | ||
218 | |||
219 | FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE, | ||
220 | /**< The encoder has an invalid setting for bits-per-sample. | ||
221 | * FLAC supports 4-32 bps but the reference encoder currently supports | ||
222 | * only up to 24 bps. | ||
223 | */ | ||
224 | |||
225 | FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE, | ||
226 | /**< The encoder has an invalid setting for the input sample rate. */ | ||
227 | |||
228 | FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE, | ||
229 | /**< The encoder has an invalid setting for the block size. */ | ||
230 | |||
231 | FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER, | ||
232 | /**< The encoder has an invalid setting for the maximum LPC order. */ | ||
233 | |||
234 | FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION, | ||
235 | /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */ | ||
236 | |||
237 | FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH, | ||
238 | /**< Mid/side coding was specified but the number of channels is not equal to 2. */ | ||
239 | |||
240 | FLAC__STREAM_ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH, | ||
241 | /**< Deprecated. */ | ||
242 | |||
243 | FLAC__STREAM_ENCODER_ILLEGAL_MID_SIDE_FORCE, | ||
244 | /**< Loose mid/side coding was specified but mid/side coding was not. */ | ||
245 | |||
246 | FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER, | ||
247 | /**< The specified block size is less than the maximum LPC order. */ | ||
248 | |||
249 | FLAC__STREAM_ENCODER_NOT_STREAMABLE, | ||
250 | /**< The encoder is bound to the "streamable subset" but other settings violate it. */ | ||
251 | |||
252 | FLAC__STREAM_ENCODER_FRAMING_ERROR, | ||
253 | /**< An error occurred while writing the stream; usually, the write_callback returned an error. */ | ||
254 | |||
255 | FLAC__STREAM_ENCODER_INVALID_METADATA, | ||
256 | /**< The metadata input to the encoder is invalid, in one of the following ways: | ||
257 | * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0 | ||
258 | * - One of the metadata blocks contains an undefined type | ||
259 | * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal() | ||
260 | * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal() | ||
261 | * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block | ||
262 | */ | ||
263 | |||
264 | FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING, | ||
265 | /**< An error occurred while writing the stream; usually, the write_callback returned an error. */ | ||
266 | |||
267 | FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING, | ||
268 | /**< The write_callback returned an error. */ | ||
269 | |||
270 | FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, | ||
271 | /**< Memory allocation failed. */ | ||
272 | |||
273 | FLAC__STREAM_ENCODER_ALREADY_INITIALIZED, | ||
274 | /**< FLAC__stream_encoder_init() was called when the encoder was | ||
275 | * already initialized, usually because | ||
276 | * FLAC__stream_encoder_finish() was not called. | ||
277 | */ | ||
278 | |||
279 | FLAC__STREAM_ENCODER_UNINITIALIZED | ||
280 | /**< The encoder is in the uninitialized state. */ | ||
281 | |||
282 | } FLAC__StreamEncoderState; | ||
283 | |||
284 | /** Maps a FLAC__StreamEncoderState to a C string. | ||
285 | * | ||
286 | * Using a FLAC__StreamEncoderState as the index to this array | ||
287 | * will give the string equivalent. The contents should not be modified. | ||
288 | */ | ||
289 | extern FLAC_API const char * const FLAC__StreamEncoderStateString[]; | ||
290 | |||
291 | /** Return values for the FLAC__StreamEncoder write callback. | ||
292 | */ | ||
293 | typedef enum { | ||
294 | |||
295 | FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0, | ||
296 | /**< The write was OK and encoding can continue. */ | ||
297 | |||
298 | FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR | ||
299 | /**< An unrecoverable error occurred. The encoder will return from the process call. */ | ||
300 | |||
301 | } FLAC__StreamEncoderWriteStatus; | ||
302 | |||
303 | /** Maps a FLAC__StreamEncoderWriteStatus to a C string. | ||
304 | * | ||
305 | * Using a FLAC__StreamEncoderWriteStatus as the index to this array | ||
306 | * will give the string equivalent. The contents should not be modified. | ||
307 | */ | ||
308 | extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[]; | ||
309 | |||
310 | |||
311 | /*********************************************************************** | ||
312 | * | ||
313 | * class FLAC__StreamEncoder | ||
314 | * | ||
315 | ***********************************************************************/ | ||
316 | |||
317 | struct FLAC__StreamEncoderProtected; | ||
318 | struct FLAC__StreamEncoderPrivate; | ||
319 | /** The opaque structure definition for the stream encoder type. | ||
320 | * See the \link flac_stream_encoder stream encoder module \endlink | ||
321 | * for a detailed description. | ||
322 | */ | ||
323 | typedef struct { | ||
324 | struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ | ||
325 | struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ | ||
326 | } FLAC__StreamEncoder; | ||
327 | |||
328 | /** Signature for the write callback. | ||
329 | * See FLAC__stream_encoder_set_write_callback() for more info. | ||
330 | * | ||
331 | * \param encoder The encoder instance calling the callback. | ||
332 | * \param buffer An array of encoded data of length \a bytes. | ||
333 | * \param bytes The byte length of \a buffer. | ||
334 | * \param samples The number of samples encoded by \a buffer. | ||
335 | * \c 0 has a special meaning; see | ||
336 | * FLAC__stream_encoder_set_write_callback(). | ||
337 | * \param current_frame The number of the current frame being encoded. | ||
338 | * \param client_data The callee's client data set through | ||
339 | * FLAC__stream_encoder_set_client_data(). | ||
340 | * \retval FLAC__StreamEncoderWriteStatus | ||
341 | * The callee's return status. | ||
342 | */ | ||
343 | typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); | ||
344 | |||
345 | /** Signature for the metadata callback. | ||
346 | * See FLAC__stream_encoder_set_metadata_callback() for more info. | ||
347 | * | ||
348 | * \param encoder The encoder instance calling the callback. | ||
349 | * \param metadata The final populated STREAMINFO block. | ||
350 | * \param client_data The callee's client data set through | ||
351 | * FLAC__stream_encoder_set_client_data(). | ||
352 | */ | ||
353 | typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
354 | |||
355 | |||
356 | /*********************************************************************** | ||
357 | * | ||
358 | * Class constructor/destructor | ||
359 | * | ||
360 | ***********************************************************************/ | ||
361 | |||
362 | /** Create a new stream encoder instance. The instance is created with | ||
363 | * default settings; see the individual FLAC__stream_encoder_set_*() | ||
364 | * functions for each setting's default. | ||
365 | * | ||
366 | * \retval FLAC__StreamEncoder* | ||
367 | * \c NULL if there was an error allocating memory, else the new instance. | ||
368 | */ | ||
369 | FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(); | ||
370 | |||
371 | /** Free an encoder instance. Deletes the object pointed to by \a encoder. | ||
372 | * | ||
373 | * \param encoder A pointer to an existing encoder. | ||
374 | * \assert | ||
375 | * \code encoder != NULL \endcode | ||
376 | */ | ||
377 | FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder); | ||
378 | |||
379 | |||
380 | /*********************************************************************** | ||
381 | * | ||
382 | * Public class method prototypes | ||
383 | * | ||
384 | ***********************************************************************/ | ||
385 | |||
386 | /** Set the "verify" flag. If \c true, the encoder will verify it's own | ||
387 | * encoded output by feeding it through an internal decoder and comparing | ||
388 | * the original signal against the decoded signal. If a mismatch occurs, | ||
389 | * the process call will return \c false. Note that this will slow the | ||
390 | * encoding process by the extra time required for decoding and comparison. | ||
391 | * | ||
392 | * \default \c false | ||
393 | * \param encoder An encoder instance to set. | ||
394 | * \param value Flag value (see above). | ||
395 | * \assert | ||
396 | * \code encoder != NULL \endcode | ||
397 | * \retval FLAC__bool | ||
398 | * \c false if the encoder is already initialized, else \c true. | ||
399 | */ | ||
400 | FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
401 | |||
402 | /** Set the "streamable subset" flag. If \c true, the encoder will comply | ||
403 | * with the subset (see the format specification) and will check the | ||
404 | * settings during FLAC__stream_encoder_init() to see if all settings | ||
405 | * comply. If \c false, the settings may take advantage of the full | ||
406 | * range that the format allows. | ||
407 | * | ||
408 | * Make sure you know what it entails before setting this to \c false. | ||
409 | * | ||
410 | * \default \c true | ||
411 | * \param encoder An encoder instance to set. | ||
412 | * \param value Flag value (see above). | ||
413 | * \assert | ||
414 | * \code encoder != NULL \endcode | ||
415 | * \retval FLAC__bool | ||
416 | * \c false if the encoder is already initialized, else \c true. | ||
417 | */ | ||
418 | FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
419 | |||
420 | /** Set to \c true to enable mid-side encoding on stereo input. The | ||
421 | * number of channels must be 2. Set to \c false to use only | ||
422 | * independent channel coding. | ||
423 | * | ||
424 | * \default \c false | ||
425 | * \param encoder An encoder instance to set. | ||
426 | * \param value Flag value (see above). | ||
427 | * \assert | ||
428 | * \code encoder != NULL \endcode | ||
429 | * \retval FLAC__bool | ||
430 | * \c false if the encoder is already initialized, else \c true. | ||
431 | */ | ||
432 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
433 | |||
434 | /** Set to \c true to enable adaptive switching between mid-side and | ||
435 | * left-right encoding on stereo input. The number of channels must | ||
436 | * be 2. Set to \c false to use exhaustive searching. In either | ||
437 | * case, the mid/side stereo setting must be \c true. | ||
438 | * | ||
439 | * \default \c false | ||
440 | * \param encoder An encoder instance to set. | ||
441 | * \param value Flag value (see above). | ||
442 | * \assert | ||
443 | * \code encoder != NULL \endcode | ||
444 | * \retval FLAC__bool | ||
445 | * \c false if the encoder is already initialized, else \c true. | ||
446 | */ | ||
447 | FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
448 | |||
449 | /** Set the number of channels to be encoded. | ||
450 | * | ||
451 | * \default \c 2 | ||
452 | * \param encoder An encoder instance to set. | ||
453 | * \param value See above. | ||
454 | * \assert | ||
455 | * \code encoder != NULL \endcode | ||
456 | * \retval FLAC__bool | ||
457 | * \c false if the encoder is already initialized, else \c true. | ||
458 | */ | ||
459 | FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value); | ||
460 | |||
461 | /** Set the sample resolution of the input to be encoded. | ||
462 | * | ||
463 | * \warning | ||
464 | * Do not feed the encoder data that is wider than the value you | ||
465 | * set here or you will generate an invalid stream. | ||
466 | * | ||
467 | * \default \c 16 | ||
468 | * \param encoder An encoder instance to set. | ||
469 | * \param value See above. | ||
470 | * \assert | ||
471 | * \code encoder != NULL \endcode | ||
472 | * \retval FLAC__bool | ||
473 | * \c false if the encoder is already initialized, else \c true. | ||
474 | */ | ||
475 | FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value); | ||
476 | |||
477 | /** Set the sample rate (in Hz) of the input to be encoded. | ||
478 | * | ||
479 | * \default \c 44100 | ||
480 | * \param encoder An encoder instance to set. | ||
481 | * \param value See above. | ||
482 | * \assert | ||
483 | * \code encoder != NULL \endcode | ||
484 | * \retval FLAC__bool | ||
485 | * \c false if the encoder is already initialized, else \c true. | ||
486 | */ | ||
487 | FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value); | ||
488 | |||
489 | /** Set the blocksize to use while encoding. | ||
490 | * | ||
491 | * \default \c 1152 | ||
492 | * \param encoder An encoder instance to set. | ||
493 | * \param value See above. | ||
494 | * \assert | ||
495 | * \code encoder != NULL \endcode | ||
496 | * \retval FLAC__bool | ||
497 | * \c false if the encoder is already initialized, else \c true. | ||
498 | */ | ||
499 | FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value); | ||
500 | |||
501 | /** Set the maximum LPC order, or \c 0 to use only the fixed predictors. | ||
502 | * | ||
503 | * \default \c 0 | ||
504 | * \param encoder An encoder instance to set. | ||
505 | * \param value See above. | ||
506 | * \assert | ||
507 | * \code encoder != NULL \endcode | ||
508 | * \retval FLAC__bool | ||
509 | * \c false if the encoder is already initialized, else \c true. | ||
510 | */ | ||
511 | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value); | ||
512 | |||
513 | /** Set the precision, in bits, of the quantized linear predictor | ||
514 | * coefficients, or \c 0 to let the encoder select it based on the | ||
515 | * blocksize. | ||
516 | * | ||
517 | * \note | ||
518 | * In the current implementation, qlp_coeff_precision + bits_per_sample must | ||
519 | * be less than 32. | ||
520 | * | ||
521 | * \default \c 0 | ||
522 | * \param encoder An encoder instance to set. | ||
523 | * \param value See above. | ||
524 | * \assert | ||
525 | * \code encoder != NULL \endcode | ||
526 | * \retval FLAC__bool | ||
527 | * \c false if the encoder is already initialized, else \c true. | ||
528 | */ | ||
529 | FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value); | ||
530 | |||
531 | /** Set to \c false to use only the specified quantized linear predictor | ||
532 | * coefficient precision, or \c true to search neighboring precision | ||
533 | * values and use the best one. | ||
534 | * | ||
535 | * \default \c false | ||
536 | * \param encoder An encoder instance to set. | ||
537 | * \param value See above. | ||
538 | * \assert | ||
539 | * \code encoder != NULL \endcode | ||
540 | * \retval FLAC__bool | ||
541 | * \c false if the encoder is already initialized, else \c true. | ||
542 | */ | ||
543 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
544 | |||
545 | /** Deprecated. Setting this value has no effect. | ||
546 | * | ||
547 | * \default \c false | ||
548 | * \param encoder An encoder instance to set. | ||
549 | * \param value See above. | ||
550 | * \assert | ||
551 | * \code encoder != NULL \endcode | ||
552 | * \retval FLAC__bool | ||
553 | * \c false if the encoder is already initialized, else \c true. | ||
554 | */ | ||
555 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
556 | |||
557 | /** Set to \c false to let the encoder estimate the best model order | ||
558 | * based on the residual signal energy, or \c true to force the | ||
559 | * encoder to evaluate all order models and select the best. | ||
560 | * | ||
561 | * \default \c false | ||
562 | * \param encoder An encoder instance to set. | ||
563 | * \param value See above. | ||
564 | * \assert | ||
565 | * \code encoder != NULL \endcode | ||
566 | * \retval FLAC__bool | ||
567 | * \c false if the encoder is already initialized, else \c true. | ||
568 | */ | ||
569 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
570 | |||
571 | /** Set the minimum partition order to search when coding the residual. | ||
572 | * This is used in tandem with | ||
573 | * FLAC__stream_encoder_set_max_residual_partition_order(). | ||
574 | * | ||
575 | * The partition order determines the context size in the residual. | ||
576 | * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. | ||
577 | * | ||
578 | * Set both min and max values to \c 0 to force a single context, | ||
579 | * whose Rice parameter is based on the residual signal variance. | ||
580 | * Otherwise, set a min and max order, and the encoder will search | ||
581 | * all orders, using the mean of each context for its Rice parameter, | ||
582 | * and use the best. | ||
583 | * | ||
584 | * \default \c 0 | ||
585 | * \param encoder An encoder instance to set. | ||
586 | * \param value See above. | ||
587 | * \assert | ||
588 | * \code encoder != NULL \endcode | ||
589 | * \retval FLAC__bool | ||
590 | * \c false if the encoder is already initialized, else \c true. | ||
591 | */ | ||
592 | FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); | ||
593 | |||
594 | /** Set the maximum partition order to search when coding the residual. | ||
595 | * This is used in tandem with | ||
596 | * FLAC__stream_encoder_set_min_residual_partition_order(). | ||
597 | * | ||
598 | * The partition order determines the context size in the residual. | ||
599 | * The context size will be approximately <tt>blocksize / (2 ^ order)</tt>. | ||
600 | * | ||
601 | * Set both min and max values to \c 0 to force a single context, | ||
602 | * whose Rice parameter is based on the residual signal variance. | ||
603 | * Otherwise, set a min and max order, and the encoder will search | ||
604 | * all orders, using the mean of each context for its Rice parameter, | ||
605 | * and use the best. | ||
606 | * | ||
607 | * \default \c 0 | ||
608 | * \param encoder An encoder instance to set. | ||
609 | * \param value See above. | ||
610 | * \assert | ||
611 | * \code encoder != NULL \endcode | ||
612 | * \retval FLAC__bool | ||
613 | * \c false if the encoder is already initialized, else \c true. | ||
614 | */ | ||
615 | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); | ||
616 | |||
617 | /** Deprecated. Setting this value has no effect. | ||
618 | * | ||
619 | * \default \c 0 | ||
620 | * \param encoder An encoder instance to set. | ||
621 | * \param value See above. | ||
622 | * \assert | ||
623 | * \code encoder != NULL \endcode | ||
624 | * \retval FLAC__bool | ||
625 | * \c false if the encoder is already initialized, else \c true. | ||
626 | */ | ||
627 | FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value); | ||
628 | |||
629 | /** Set an estimate of the total samples that will be encoded. | ||
630 | * This is merely an estimate and may be set to \c 0 if unknown. | ||
631 | * This value will be written to the STREAMINFO block before encoding, | ||
632 | * and can remove the need for the caller to rewrite the value later | ||
633 | * if the value is known before encoding. | ||
634 | * | ||
635 | * \default \c 0 | ||
636 | * \param encoder An encoder instance to set. | ||
637 | * \param value See above. | ||
638 | * \assert | ||
639 | * \code encoder != NULL \endcode | ||
640 | * \retval FLAC__bool | ||
641 | * \c false if the encoder is already initialized, else \c true. | ||
642 | */ | ||
643 | FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); | ||
644 | |||
645 | /** Set the metadata blocks to be emitted to the stream before encoding. | ||
646 | * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an | ||
647 | * array of pointers to metadata blocks. The array is non-const since | ||
648 | * the encoder may need to change the \a is_last flag inside them. | ||
649 | * Otherwise, the encoder will not modify or free the blocks. It is up | ||
650 | * to the caller to free the metadata blocks after encoding. | ||
651 | * | ||
652 | * \note | ||
653 | * The encoder stores only the \a metadata pointer; the passed-in array | ||
654 | * must survive at least until after FLAC__stream_encoder_init() returns. | ||
655 | * Do not modify the array or free the blocks until then. | ||
656 | * | ||
657 | * \note | ||
658 | * The STREAMINFO block is always written and no STREAMINFO block may | ||
659 | * occur in the supplied array. | ||
660 | * | ||
661 | * \note | ||
662 | * By default the encoder does not create a SEEKTABLE. If one is supplied | ||
663 | * in the \a metadata array it will be written verbatim. However by itself | ||
664 | * this is not very useful as the user will not know the stream offsets for | ||
665 | * the seekpoints ahead of time. You must use the seekable stream encoder | ||
666 | * to generate a legal seektable | ||
667 | * (see FLAC__seekable_stream_encoder_set_metadata()) | ||
668 | * | ||
669 | * \note | ||
670 | * A VORBIS_COMMENT block may be supplied. The vendor string in it | ||
671 | * will be ignored. libFLAC will use it's own vendor string. libFLAC | ||
672 | * will not modify the passed-in VORBIS_COMMENT's vendor string, it | ||
673 | * will simply write it's own into the stream. If no VORBIS_COMMENT | ||
674 | * block is present in the \a metadata array, libFLAC will write an | ||
675 | * empty one, containing only the vendor string. | ||
676 | * | ||
677 | * \default \c NULL, 0 | ||
678 | * \param encoder An encoder instance to set. | ||
679 | * \param metadata See above. | ||
680 | * \param num_blocks See above. | ||
681 | * \assert | ||
682 | * \code encoder != NULL \endcode | ||
683 | * \retval FLAC__bool | ||
684 | * \c false if the encoder is already initialized, else \c true. | ||
685 | */ | ||
686 | FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); | ||
687 | |||
688 | /** Set the write callback. | ||
689 | * The supplied function will be called by the encoder anytime there is raw | ||
690 | * encoded data ready to write. It may include metadata mixed with encoded | ||
691 | * audio frames and the data is not guaranteed to be aligned on frame or | ||
692 | * metadata block boundaries. | ||
693 | * | ||
694 | * The only duty of the callback is to write out the \a bytes worth of data | ||
695 | * in \a buffer to the current position in the output stream. The arguments | ||
696 | * \a samples and \a current_frame are purely informational. If \a samples | ||
697 | * is greater than \c 0, then \a current_frame will hold the current frame | ||
698 | * number that is being written; otherwise, the write callback is being called | ||
699 | * to write metadata. | ||
700 | * | ||
701 | * \note | ||
702 | * The callback is mandatory and must be set before initialization. | ||
703 | * | ||
704 | * \default \c NULL | ||
705 | * \param encoder An encoder instance to set. | ||
706 | * \param value See above. | ||
707 | * \assert | ||
708 | * \code encoder != NULL \endcode | ||
709 | * \code value != NULL \endcode | ||
710 | * \retval FLAC__bool | ||
711 | * \c false if the encoder is already initialized, else \c true. | ||
712 | */ | ||
713 | FLAC_API FLAC__bool FLAC__stream_encoder_set_write_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback value); | ||
714 | |||
715 | /** Set the metadata callback. | ||
716 | * The supplied function will be called once at the end of encoding with | ||
717 | * the populated STREAMINFO structure. This is so file encoders can seek | ||
718 | * back to the beginning of the file and write the STREAMINFO block with | ||
719 | * the correct statistics after encoding (like minimum/maximum frame size | ||
720 | * and total samples). | ||
721 | * | ||
722 | * \note | ||
723 | * The callback is mandatory and must be set before initialization. | ||
724 | * | ||
725 | * \default \c NULL | ||
726 | * \param encoder An encoder instance to set. | ||
727 | * \param value See above. | ||
728 | * \assert | ||
729 | * \code encoder != NULL \endcode | ||
730 | * \code value != NULL \endcode | ||
731 | * \retval FLAC__bool | ||
732 | * \c false if the encoder is already initialized, else \c true. | ||
733 | */ | ||
734 | FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderMetadataCallback value); | ||
735 | |||
736 | /** Set the client data to be passed back to callbacks. | ||
737 | * This value will be supplied to callbacks in their \a client_data | ||
738 | * argument. | ||
739 | * | ||
740 | * \default \c NULL | ||
741 | * \param encoder An encoder instance to set. | ||
742 | * \param value See above. | ||
743 | * \assert | ||
744 | * \code encoder != NULL \endcode | ||
745 | * \retval FLAC__bool | ||
746 | * \c false if the encoder is already initialized, else \c true. | ||
747 | */ | ||
748 | FLAC_API FLAC__bool FLAC__stream_encoder_set_client_data(FLAC__StreamEncoder *encoder, void *value); | ||
749 | |||
750 | /** Get the current encoder state. | ||
751 | * | ||
752 | * \param encoder An encoder instance to query. | ||
753 | * \assert | ||
754 | * \code encoder != NULL \endcode | ||
755 | * \retval FLAC__StreamEncoderState | ||
756 | * The current encoder state. | ||
757 | */ | ||
758 | FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); | ||
759 | |||
760 | /** Get the state of the verify stream decoder. | ||
761 | * Useful when the stream encoder state is | ||
762 | * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. | ||
763 | * | ||
764 | * \param encoder An encoder instance to query. | ||
765 | * \assert | ||
766 | * \code encoder != NULL \endcode | ||
767 | * \retval FLAC__StreamDecoderState | ||
768 | * The verify stream decoder state. | ||
769 | */ | ||
770 | FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder); | ||
771 | |||
772 | /** Get the current encoder state as a C string. | ||
773 | * This version automatically resolves | ||
774 | * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the | ||
775 | * verify decoder's state. | ||
776 | * | ||
777 | * \param encoder A encoder instance to query. | ||
778 | * \assert | ||
779 | * \code encoder != NULL \endcode | ||
780 | * \retval const char * | ||
781 | * The encoder state as a C string. Do not modify the contents. | ||
782 | */ | ||
783 | FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder); | ||
784 | |||
785 | /** Get relevant values about the nature of a verify decoder error. | ||
786 | * Useful when the stream encoder state is | ||
787 | * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should | ||
788 | * be addresses in which the stats will be returned, or NULL if value | ||
789 | * is not desired. | ||
790 | * | ||
791 | * \param encoder An encoder instance to query. | ||
792 | * \param absolute_sample The absolute sample number of the mismatch. | ||
793 | * \param frame_number The number of the frame in which the mismatch occurred. | ||
794 | * \param channel The channel in which the mismatch occurred. | ||
795 | * \param sample The number of the sample (relative to the frame) in | ||
796 | * which the mismatch occurred. | ||
797 | * \param expected The expected value for the sample in question. | ||
798 | * \param got The actual value returned by the decoder. | ||
799 | * \assert | ||
800 | * \code encoder != NULL \endcode | ||
801 | */ | ||
802 | FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); | ||
803 | |||
804 | /** Get the "verify" flag. | ||
805 | * | ||
806 | * \param encoder An encoder instance to query. | ||
807 | * \assert | ||
808 | * \code encoder != NULL \endcode | ||
809 | * \retval FLAC__bool | ||
810 | * See FLAC__stream_encoder_set_verify(). | ||
811 | */ | ||
812 | FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder); | ||
813 | |||
814 | /** Get the "streamable subset" flag. | ||
815 | * | ||
816 | * \param encoder An encoder instance to query. | ||
817 | * \assert | ||
818 | * \code encoder != NULL \endcode | ||
819 | * \retval FLAC__bool | ||
820 | * See FLAC__stream_encoder_set_streamable_subset(). | ||
821 | */ | ||
822 | FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder); | ||
823 | |||
824 | /** Get the "mid/side stereo coding" flag. | ||
825 | * | ||
826 | * \param encoder An encoder instance to query. | ||
827 | * \assert | ||
828 | * \code encoder != NULL \endcode | ||
829 | * \retval FLAC__bool | ||
830 | * See FLAC__stream_encoder_get_do_mid_side_stereo(). | ||
831 | */ | ||
832 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder); | ||
833 | |||
834 | /** Get the "adaptive mid/side switching" flag. | ||
835 | * | ||
836 | * \param encoder An encoder instance to query. | ||
837 | * \assert | ||
838 | * \code encoder != NULL \endcode | ||
839 | * \retval FLAC__bool | ||
840 | * See FLAC__stream_encoder_set_loose_mid_side_stereo(). | ||
841 | */ | ||
842 | FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder); | ||
843 | |||
844 | /** Get the number of input channels being processed. | ||
845 | * | ||
846 | * \param encoder An encoder instance to query. | ||
847 | * \assert | ||
848 | * \code encoder != NULL \endcode | ||
849 | * \retval unsigned | ||
850 | * See FLAC__stream_encoder_set_channels(). | ||
851 | */ | ||
852 | FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder); | ||
853 | |||
854 | /** Get the input sample resolution setting. | ||
855 | * | ||
856 | * \param encoder An encoder instance to query. | ||
857 | * \assert | ||
858 | * \code encoder != NULL \endcode | ||
859 | * \retval unsigned | ||
860 | * See FLAC__stream_encoder_set_bits_per_sample(). | ||
861 | */ | ||
862 | FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder); | ||
863 | |||
864 | /** Get the input sample rate setting. | ||
865 | * | ||
866 | * \param encoder An encoder instance to query. | ||
867 | * \assert | ||
868 | * \code encoder != NULL \endcode | ||
869 | * \retval unsigned | ||
870 | * See FLAC__stream_encoder_set_sample_rate(). | ||
871 | */ | ||
872 | FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder); | ||
873 | |||
874 | /** Get the blocksize setting. | ||
875 | * | ||
876 | * \param encoder An encoder instance to query. | ||
877 | * \assert | ||
878 | * \code encoder != NULL \endcode | ||
879 | * \retval unsigned | ||
880 | * See FLAC__stream_encoder_set_blocksize(). | ||
881 | */ | ||
882 | FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder); | ||
883 | |||
884 | /** Get the maximum LPC order setting. | ||
885 | * | ||
886 | * \param encoder An encoder instance to query. | ||
887 | * \assert | ||
888 | * \code encoder != NULL \endcode | ||
889 | * \retval unsigned | ||
890 | * See FLAC__stream_encoder_set_max_lpc_order(). | ||
891 | */ | ||
892 | FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder); | ||
893 | |||
894 | /** Get the quantized linear predictor coefficient precision setting. | ||
895 | * | ||
896 | * \param encoder An encoder instance to query. | ||
897 | * \assert | ||
898 | * \code encoder != NULL \endcode | ||
899 | * \retval unsigned | ||
900 | * See FLAC__stream_encoder_set_qlp_coeff_precision(). | ||
901 | */ | ||
902 | FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder); | ||
903 | |||
904 | /** Get the qlp coefficient precision search flag. | ||
905 | * | ||
906 | * \param encoder An encoder instance to query. | ||
907 | * \assert | ||
908 | * \code encoder != NULL \endcode | ||
909 | * \retval FLAC__bool | ||
910 | * See FLAC__stream_encoder_set_do_qlp_coeff_prec_search(). | ||
911 | */ | ||
912 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder); | ||
913 | |||
914 | /** Get the "escape coding" flag. | ||
915 | * | ||
916 | * \param encoder An encoder instance to query. | ||
917 | * \assert | ||
918 | * \code encoder != NULL \endcode | ||
919 | * \retval FLAC__bool | ||
920 | * See FLAC__stream_encoder_set_do_escape_coding(). | ||
921 | */ | ||
922 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder); | ||
923 | |||
924 | /** Get the exhaustive model search flag. | ||
925 | * | ||
926 | * \param encoder An encoder instance to query. | ||
927 | * \assert | ||
928 | * \code encoder != NULL \endcode | ||
929 | * \retval FLAC__bool | ||
930 | * See FLAC__stream_encoder_set_do_exhaustive_model_search(). | ||
931 | */ | ||
932 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder); | ||
933 | |||
934 | /** Get the minimum residual partition order setting. | ||
935 | * | ||
936 | * \param encoder An encoder instance to query. | ||
937 | * \assert | ||
938 | * \code encoder != NULL \endcode | ||
939 | * \retval unsigned | ||
940 | * See FLAC__stream_encoder_set_min_residual_partition_order(). | ||
941 | */ | ||
942 | FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder); | ||
943 | |||
944 | /** Get maximum residual partition order setting. | ||
945 | * | ||
946 | * \param encoder An encoder instance to query. | ||
947 | * \assert | ||
948 | * \code encoder != NULL \endcode | ||
949 | * \retval unsigned | ||
950 | * See FLAC__stream_encoder_set_max_residual_partition_order(). | ||
951 | */ | ||
952 | FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder); | ||
953 | |||
954 | /** Get the Rice parameter search distance setting. | ||
955 | * | ||
956 | * \param encoder An encoder instance to query. | ||
957 | * \assert | ||
958 | * \code encoder != NULL \endcode | ||
959 | * \retval unsigned | ||
960 | * See FLAC__stream_encoder_set_rice_parameter_search_dist(). | ||
961 | */ | ||
962 | FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder); | ||
963 | |||
964 | /** Get the previously set estimate of the total samples to be encoded. | ||
965 | * The encoder merely mimics back the value given to | ||
966 | * FLAC__stream_encoder_set_total_samples_estimate() since it has no | ||
967 | * other way of knowing how many samples the user will encode. | ||
968 | * | ||
969 | * \param encoder An encoder instance to set. | ||
970 | * \assert | ||
971 | * \code encoder != NULL \endcode | ||
972 | * \retval FLAC__uint64 | ||
973 | * See FLAC__stream_encoder_get_total_samples_estimate(). | ||
974 | */ | ||
975 | FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); | ||
976 | |||
977 | /** Initialize the encoder instance. | ||
978 | * Should be called after FLAC__stream_encoder_new() and | ||
979 | * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() | ||
980 | * or FLAC__stream_encoder_process_interleaved(). Will set and return | ||
981 | * the encoder state, which will be FLAC__STREAM_ENCODER_OK if | ||
982 | * initialization succeeded. | ||
983 | * | ||
984 | * The call to FLAC__stream_encoder_init() currently will also immediately | ||
985 | * call the write callback several times, once with the \c fLaC signature, | ||
986 | * and once for each encoded metadata block. | ||
987 | * | ||
988 | * \param encoder An uninitialized encoder instance. | ||
989 | * \assert | ||
990 | * \code encoder != NULL \endcode | ||
991 | * \retval FLAC__StreamEncoderState | ||
992 | * \c FLAC__STREAM_ENCODER_OK if initialization was successful; see | ||
993 | * FLAC__StreamEncoderState for the meanings of other return values. | ||
994 | */ | ||
995 | FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder); | ||
996 | |||
997 | /** Finish the encoding process. | ||
998 | * Flushes the encoding buffer, releases resources, resets the encoder | ||
999 | * settings to their defaults, and returns the encoder state to | ||
1000 | * FLAC__STREAM_ENCODER_UNINITIALIZED. Note that this can generate | ||
1001 | * one or more write callbacks before returning, and will generate | ||
1002 | * a metadata callback. | ||
1003 | * | ||
1004 | * In the event of a prematurely-terminated encode, it is not strictly | ||
1005 | * necessary to call this immediately before FLAC__stream_encoder_delete() | ||
1006 | * but it is good practice to match every FLAC__stream_encoder_init() | ||
1007 | * with a FLAC__stream_encoder_finish(). | ||
1008 | * | ||
1009 | * \param encoder An uninitialized encoder instance. | ||
1010 | * \assert | ||
1011 | * \code encoder != NULL \endcode | ||
1012 | */ | ||
1013 | FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); | ||
1014 | |||
1015 | /** Submit data for encoding. | ||
1016 | * This version allows you to supply the input data via an array of | ||
1017 | * pointers, each pointer pointing to an array of \a samples samples | ||
1018 | * representing one channel. The samples need not be block-aligned, | ||
1019 | * but each channel should have the same number of samples. | ||
1020 | * | ||
1021 | * \param encoder An initialized encoder instance in the OK state. | ||
1022 | * \param buffer An array of pointers to each channel's signal. | ||
1023 | * \param samples The number of samples in one channel. | ||
1024 | * \assert | ||
1025 | * \code encoder != NULL \endcode | ||
1026 | * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode | ||
1027 | * \retval FLAC__bool | ||
1028 | * \c true if successful, else \c false; in this case, check the | ||
1029 | * encoder state with FLAC__stream_encoder_get_state() to see what | ||
1030 | * went wrong. | ||
1031 | */ | ||
1032 | FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); | ||
1033 | |||
1034 | /** Submit data for encoding. | ||
1035 | * This version allows you to supply the input data where the channels | ||
1036 | * are interleaved into a single array (i.e. channel0_sample0, | ||
1037 | * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). | ||
1038 | * The samples need not be block-aligned but they must be | ||
1039 | * sample-aligned, i.e. the first value should be channel0_sample0 | ||
1040 | * and the last value channelN_sampleM. | ||
1041 | * | ||
1042 | * \param encoder An initialized encoder instance in the OK state. | ||
1043 | * \param buffer An array of channel-interleaved data (see above). | ||
1044 | * \param samples The number of samples in one channel, the same as for | ||
1045 | * FLAC__stream_encoder_process(). For example, if | ||
1046 | * encoding two channels, \c 1000 \a samples corresponds | ||
1047 | * to a \a buffer of 2000 values. | ||
1048 | * \assert | ||
1049 | * \code encoder != NULL \endcode | ||
1050 | * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode | ||
1051 | * \retval FLAC__bool | ||
1052 | * \c true if successful, else \c false; in this case, check the | ||
1053 | * encoder state with FLAC__stream_encoder_get_state() to see what | ||
1054 | * went wrong. | ||
1055 | */ | ||
1056 | FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); | ||
1057 | |||
1058 | /* \} */ | ||
1059 | |||
1060 | #ifdef __cplusplus | ||
1061 | } | ||
1062 | #endif | ||
1063 | |||
1064 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/all.h b/apps/codecs/libFLAC/include/private/all.h new file mode 100644 index 0000000000..5c9e9842e1 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/all.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__ALL_H | ||
33 | #define FLAC__PRIVATE__ALL_H | ||
34 | |||
35 | #include "bitbuffer.h" | ||
36 | #include "bitmath.h" | ||
37 | #include "cpu.h" | ||
38 | #include "crc.h" | ||
39 | #include "fixed.h" | ||
40 | #include "float.h" | ||
41 | #include "format.h" | ||
42 | #include "lpc.h" | ||
43 | #include "md5.h" | ||
44 | #include "memory.h" | ||
45 | #include "metadata.h" | ||
46 | #include "stream_encoder_framing.h" | ||
47 | |||
48 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/bitbuffer.h b/apps/codecs/libFLAC/include/private/bitbuffer.h new file mode 100644 index 0000000000..4ce5957fde --- /dev/null +++ b/apps/codecs/libFLAC/include/private/bitbuffer.h | |||
@@ -0,0 +1,159 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__BITBUFFER_H | ||
33 | #define FLAC__PRIVATE__BITBUFFER_H | ||
34 | |||
35 | #include <stdio.h> /* for FILE */ | ||
36 | #include "FLAC/ordinals.h" | ||
37 | |||
38 | /* @@@ This should be configurable. Valid values are currently 8 and 32. */ | ||
39 | /* @@@ WATCHOUT! do not use 32 with a little endian system yet. */ | ||
40 | #define FLAC__BITS_PER_BLURB 8 | ||
41 | |||
42 | #if FLAC__BITS_PER_BLURB == 8 | ||
43 | typedef FLAC__byte FLAC__blurb; | ||
44 | #elif FLAC__BITS_PER_BLURB == 32 | ||
45 | typedef FLAC__uint32 FLAC__blurb; | ||
46 | #else | ||
47 | /* ERROR, only sizes of 8 and 32 are supported */ | ||
48 | #endif | ||
49 | |||
50 | /* | ||
51 | * opaque structure definition | ||
52 | */ | ||
53 | struct FLAC__BitBuffer; | ||
54 | typedef struct FLAC__BitBuffer FLAC__BitBuffer; | ||
55 | |||
56 | /* | ||
57 | * construction, deletion, initialization, cloning functions | ||
58 | */ | ||
59 | FLAC__BitBuffer *FLAC__bitbuffer_new(); | ||
60 | void FLAC__bitbuffer_delete(FLAC__BitBuffer *bb); | ||
61 | FLAC__bool FLAC__bitbuffer_init(FLAC__BitBuffer *bb); | ||
62 | FLAC__bool FLAC__bitbuffer_init_from(FLAC__BitBuffer *bb, const FLAC__byte buffer[], unsigned bytes); | ||
63 | FLAC__bool FLAC__bitbuffer_concatenate_aligned(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src); | ||
64 | void FLAC__bitbuffer_free(FLAC__BitBuffer *bb); /* does not 'free(buffer)' */ | ||
65 | FLAC__bool FLAC__bitbuffer_clear(FLAC__BitBuffer *bb); | ||
66 | FLAC__bool FLAC__bitbuffer_clone(FLAC__BitBuffer *dest, const FLAC__BitBuffer *src); | ||
67 | |||
68 | /* | ||
69 | * CRC functions | ||
70 | */ | ||
71 | void FLAC__bitbuffer_reset_read_crc16(FLAC__BitBuffer *bb, FLAC__uint16 seed); | ||
72 | FLAC__uint16 FLAC__bitbuffer_get_read_crc16(FLAC__BitBuffer *bb); | ||
73 | FLAC__uint16 FLAC__bitbuffer_get_write_crc16(const FLAC__BitBuffer *bb); | ||
74 | FLAC__byte FLAC__bitbuffer_get_write_crc8(const FLAC__BitBuffer *bb); | ||
75 | |||
76 | /* | ||
77 | * info functions | ||
78 | */ | ||
79 | FLAC__bool FLAC__bitbuffer_is_byte_aligned(const FLAC__BitBuffer *bb); | ||
80 | FLAC__bool FLAC__bitbuffer_is_consumed_byte_aligned(const FLAC__BitBuffer *bb); | ||
81 | unsigned FLAC__bitbuffer_bits_left_for_byte_alignment(const FLAC__BitBuffer *bb); | ||
82 | unsigned FLAC__bitbuffer_get_input_bytes_unconsumed(const FLAC__BitBuffer *bb); /* do not call unless byte-aligned */ | ||
83 | |||
84 | /* | ||
85 | * direct buffer access | ||
86 | */ | ||
87 | void FLAC__bitbuffer_get_buffer(FLAC__BitBuffer *bb, const FLAC__byte **buffer, unsigned *bytes); | ||
88 | void FLAC__bitbuffer_release_buffer(FLAC__BitBuffer *bb); | ||
89 | |||
90 | /* | ||
91 | * write functions | ||
92 | */ | ||
93 | FLAC__bool FLAC__bitbuffer_write_zeroes(FLAC__BitBuffer *bb, unsigned bits); | ||
94 | FLAC__bool FLAC__bitbuffer_write_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val, unsigned bits); | ||
95 | FLAC__bool FLAC__bitbuffer_write_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 val, unsigned bits); | ||
96 | FLAC__bool FLAC__bitbuffer_write_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val, unsigned bits); | ||
97 | #if 0 /* UNUSED */ | ||
98 | FLAC__bool FLAC__bitbuffer_write_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 val, unsigned bits); | ||
99 | #endif | ||
100 | FLAC__bool FLAC__bitbuffer_write_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 val); /*only for bits=32*/ | ||
101 | FLAC__bool FLAC__bitbuffer_write_byte_block(FLAC__BitBuffer *bb, const FLAC__byte vals[], unsigned nvals); | ||
102 | FLAC__bool FLAC__bitbuffer_write_unary_unsigned(FLAC__BitBuffer *bb, unsigned val); | ||
103 | unsigned FLAC__bitbuffer_rice_bits(int val, unsigned parameter); | ||
104 | #if 0 /* UNUSED */ | ||
105 | unsigned FLAC__bitbuffer_golomb_bits_signed(int val, unsigned parameter); | ||
106 | unsigned FLAC__bitbuffer_golomb_bits_unsigned(unsigned val, unsigned parameter); | ||
107 | #endif | ||
108 | #ifdef FLAC__SYMMETRIC_RICE | ||
109 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); | ||
110 | #if 0 /* UNUSED */ | ||
111 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); | ||
112 | #endif | ||
113 | FLAC__bool FLAC__bitbuffer_write_symmetric_rice_signed_escape(FLAC__BitBuffer *bb, int val, unsigned parameter); | ||
114 | #endif | ||
115 | FLAC__bool FLAC__bitbuffer_write_rice_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); | ||
116 | #if 0 /* UNUSED */ | ||
117 | FLAC__bool FLAC__bitbuffer_write_rice_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); | ||
118 | #endif | ||
119 | #if 0 /* UNUSED */ | ||
120 | FLAC__bool FLAC__bitbuffer_write_golomb_signed(FLAC__BitBuffer *bb, int val, unsigned parameter); | ||
121 | FLAC__bool FLAC__bitbuffer_write_golomb_signed_guarded(FLAC__BitBuffer *bb, int val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); | ||
122 | FLAC__bool FLAC__bitbuffer_write_golomb_unsigned(FLAC__BitBuffer *bb, unsigned val, unsigned parameter); | ||
123 | FLAC__bool FLAC__bitbuffer_write_golomb_unsigned_guarded(FLAC__BitBuffer *bb, unsigned val, unsigned parameter, unsigned max_bits, FLAC__bool *overflow); | ||
124 | #endif | ||
125 | FLAC__bool FLAC__bitbuffer_write_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 val); | ||
126 | FLAC__bool FLAC__bitbuffer_write_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 val); | ||
127 | FLAC__bool FLAC__bitbuffer_zero_pad_to_byte_boundary(FLAC__BitBuffer *bb); | ||
128 | |||
129 | /* | ||
130 | * read functions | ||
131 | */ | ||
132 | FLAC__bool FLAC__bitbuffer_peek_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
133 | FLAC__bool FLAC__bitbuffer_read_bit(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
134 | FLAC__bool FLAC__bitbuffer_read_bit_to_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
135 | FLAC__bool FLAC__bitbuffer_read_bit_to_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
136 | FLAC__bool FLAC__bitbuffer_read_raw_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
137 | FLAC__bool FLAC__bitbuffer_read_raw_int32(FLAC__BitBuffer *bb, FLAC__int32 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
138 | FLAC__bool FLAC__bitbuffer_read_raw_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
139 | #if 0 /* UNUSED */ | ||
140 | FLAC__bool FLAC__bitbuffer_read_raw_int64(FLAC__BitBuffer *bb, FLAC__int64 *val, const unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
141 | #endif | ||
142 | FLAC__bool FLAC__bitbuffer_read_raw_uint32_little_endian(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); /*only for bits=32*/ | ||
143 | FLAC__bool FLAC__bitbuffer_skip_bits_no_crc(FLAC__BitBuffer *bb, unsigned bits, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ | ||
144 | FLAC__bool FLAC__bitbuffer_read_byte_block_aligned_no_crc(FLAC__BitBuffer *bb, FLAC__byte *val, unsigned nvals, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); /* val may be 0 to skip bytes instead of reading them */ /* WATCHOUT: does not CRC the read data! */ | ||
145 | FLAC__bool FLAC__bitbuffer_read_unary_unsigned(FLAC__BitBuffer *bb, unsigned *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
146 | #ifdef FLAC__SYMMETRIC_RICE | ||
147 | FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
148 | #endif | ||
149 | FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
150 | FLAC__bool FLAC__bitbuffer_read_rice_signed_block(FLAC__BitBuffer *bb, int vals[], unsigned nvals, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
151 | #if 0 /* UNUSED */ | ||
152 | FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
153 | FLAC__bool FLAC__bitbuffer_read_golomb_unsigned(FLAC__BitBuffer *bb, unsigned *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data); | ||
154 | #endif | ||
155 | FLAC__bool FLAC__bitbuffer_read_utf8_uint32(FLAC__BitBuffer *bb, FLAC__uint32 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen); | ||
156 | FLAC__bool FLAC__bitbuffer_read_utf8_uint64(FLAC__BitBuffer *bb, FLAC__uint64 *val, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data, FLAC__byte *raw, unsigned *rawlen); | ||
157 | void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out); | ||
158 | |||
159 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/bitmath.h b/apps/codecs/libFLAC/include/private/bitmath.h new file mode 100644 index 0000000000..1615c338c8 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/bitmath.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__BITMATH_H | ||
33 | #define FLAC__PRIVATE__BITMATH_H | ||
34 | |||
35 | #include "FLAC/ordinals.h" | ||
36 | |||
37 | unsigned FLAC__bitmath_ilog2(FLAC__uint32 v); | ||
38 | unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v); | ||
39 | unsigned FLAC__bitmath_silog2(int v); | ||
40 | unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v); | ||
41 | |||
42 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/cpu.h b/apps/codecs/libFLAC/include/private/cpu.h new file mode 100644 index 0000000000..a57936051f --- /dev/null +++ b/apps/codecs/libFLAC/include/private/cpu.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__CPU_H | ||
33 | #define FLAC__PRIVATE__CPU_H | ||
34 | |||
35 | #include "FLAC/ordinals.h" | ||
36 | |||
37 | #ifdef HAVE_CONFIG_H | ||
38 | #include <config.h> | ||
39 | #endif | ||
40 | |||
41 | typedef enum { | ||
42 | FLAC__CPUINFO_TYPE_IA32, | ||
43 | FLAC__CPUINFO_TYPE_PPC, | ||
44 | FLAC__CPUINFO_TYPE_UNKNOWN | ||
45 | } FLAC__CPUInfo_Type; | ||
46 | |||
47 | typedef struct { | ||
48 | FLAC__bool cmov; | ||
49 | FLAC__bool mmx; | ||
50 | FLAC__bool fxsr; | ||
51 | FLAC__bool sse; | ||
52 | FLAC__bool sse2; | ||
53 | FLAC__bool _3dnow; | ||
54 | FLAC__bool ext3dnow; | ||
55 | FLAC__bool extmmx; | ||
56 | } FLAC__CPUInfo_IA32; | ||
57 | |||
58 | typedef struct { | ||
59 | FLAC__bool altivec; | ||
60 | FLAC__bool ppc64; | ||
61 | } FLAC__CPUInfo_PPC; | ||
62 | |||
63 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV; | ||
64 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_MMX; | ||
65 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR; | ||
66 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_SSE; | ||
67 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2; | ||
68 | |||
69 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW; | ||
70 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW; | ||
71 | extern const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX; | ||
72 | |||
73 | typedef struct { | ||
74 | FLAC__bool use_asm; | ||
75 | FLAC__CPUInfo_Type type; | ||
76 | union { | ||
77 | FLAC__CPUInfo_IA32 ia32; | ||
78 | FLAC__CPUInfo_PPC ppc; | ||
79 | } data; | ||
80 | } FLAC__CPUInfo; | ||
81 | |||
82 | void FLAC__cpu_info(FLAC__CPUInfo *info); | ||
83 | |||
84 | #ifndef FLAC__NO_ASM | ||
85 | #ifdef FLAC__CPU_IA32 | ||
86 | #ifdef FLAC__HAS_NASM | ||
87 | unsigned FLAC__cpu_info_asm_ia32(); | ||
88 | unsigned FLAC__cpu_info_extended_amd_asm_ia32(); | ||
89 | unsigned FLAC__cpu_info_sse_test_asm_ia32(); | ||
90 | #endif | ||
91 | #endif | ||
92 | #endif | ||
93 | |||
94 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/crc.h b/apps/codecs/libFLAC/include/private/crc.h new file mode 100644 index 0000000000..487ed04010 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/crc.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__CRC_H | ||
33 | #define FLAC__PRIVATE__CRC_H | ||
34 | |||
35 | #include "FLAC/ordinals.h" | ||
36 | |||
37 | /* 8 bit CRC generator, MSB shifted first | ||
38 | ** polynomial = x^8 + x^2 + x^1 + x^0 | ||
39 | ** init = 0 | ||
40 | */ | ||
41 | extern FLAC__byte const FLAC__crc8_table[256]; | ||
42 | #define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)]; | ||
43 | void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc); | ||
44 | void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc); | ||
45 | FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); | ||
46 | |||
47 | /* 16 bit CRC generator, MSB shifted first | ||
48 | ** polynomial = x^16 + x^15 + x^2 + x^0 | ||
49 | ** init = 0 | ||
50 | */ | ||
51 | extern FLAC__uint16 FLAC__crc16_table[256]; | ||
52 | #define FLAC__CRC16_UPDATE(data, crc) (crc) = ((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]; | ||
53 | void FLAC__crc16_update(const FLAC__byte data, FLAC__uint16 *crc); | ||
54 | void FLAC__crc16_update_block(const FLAC__byte *data, unsigned len, FLAC__uint16 *crc); | ||
55 | FLAC__uint16 FLAC__crc16(const FLAC__byte *data, unsigned len); | ||
56 | |||
57 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/fixed.h b/apps/codecs/libFLAC/include/private/fixed.h new file mode 100644 index 0000000000..8401ffa8ee --- /dev/null +++ b/apps/codecs/libFLAC/include/private/fixed.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__FIXED_H | ||
33 | #define FLAC__PRIVATE__FIXED_H | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include <config.h> | ||
37 | #endif | ||
38 | |||
39 | #include "private/float.h" | ||
40 | #include "FLAC/format.h" | ||
41 | |||
42 | /* | ||
43 | * FLAC__fixed_compute_best_predictor() | ||
44 | * -------------------------------------------------------------------- | ||
45 | * Compute the best fixed predictor and the expected bits-per-sample | ||
46 | * of the residual signal for each order. The _wide() version uses | ||
47 | * 64-bit integers which is statistically necessary when bits-per- | ||
48 | * sample + log2(blocksize) > 30 | ||
49 | * | ||
50 | * IN data[0,data_len-1] | ||
51 | * IN data_len | ||
52 | * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] | ||
53 | */ | ||
54 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
55 | unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
56 | # ifndef FLAC__NO_ASM | ||
57 | # ifdef FLAC__CPU_IA32 | ||
58 | # ifdef FLAC__HAS_NASM | ||
59 | unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
60 | # endif | ||
61 | # endif | ||
62 | # endif | ||
63 | unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
64 | #else | ||
65 | unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
66 | unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
67 | #endif | ||
68 | |||
69 | /* | ||
70 | * FLAC__fixed_compute_residual() | ||
71 | * -------------------------------------------------------------------- | ||
72 | * Compute the residual signal obtained from sutracting the predicted | ||
73 | * signal from the original. | ||
74 | * | ||
75 | * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | ||
76 | * IN data_len length of original signal | ||
77 | * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | ||
78 | * OUT residual[0,data_len-1] residual signal | ||
79 | */ | ||
80 | void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]); | ||
81 | |||
82 | /* | ||
83 | * FLAC__fixed_restore_signal() | ||
84 | * -------------------------------------------------------------------- | ||
85 | * Restore the original signal by summing the residual and the | ||
86 | * predictor. | ||
87 | * | ||
88 | * IN residual[0,data_len-1] residual signal | ||
89 | * IN data_len length of original signal | ||
90 | * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | ||
91 | * *** IMPORTANT: the caller must pass in the historical samples: | ||
92 | * IN data[-order,-1] previously-reconstructed historical samples | ||
93 | * OUT data[0,data_len-1] original signal | ||
94 | */ | ||
95 | void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]); | ||
96 | |||
97 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/float.h b/apps/codecs/libFLAC/include/private/float.h new file mode 100644 index 0000000000..67a5f266e8 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/float.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__FLOAT_H | ||
33 | #define FLAC__PRIVATE__FLOAT_H | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include <config.h> | ||
37 | #endif | ||
38 | |||
39 | #include "FLAC/ordinals.h" | ||
40 | |||
41 | /* | ||
42 | * These typedefs make it easier to ensure that integer versions of | ||
43 | * the library really only contain integer operations. All the code | ||
44 | * in libFLAC should use FLAC__float and FLAC__double in place of | ||
45 | * float and double, and be protected by checks of the macro | ||
46 | * FLAC__INTEGER_ONLY_LIBRARY. | ||
47 | * | ||
48 | * FLAC__real is the basic floating point type used in LPC analysis. | ||
49 | */ | ||
50 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
51 | typedef double FLAC__double; | ||
52 | typedef float FLAC__float; | ||
53 | /* | ||
54 | * WATCHOUT: changing FLAC__real will change the signatures of many | ||
55 | * functions that have assembly language equivalents and break them. | ||
56 | */ | ||
57 | typedef float FLAC__real; | ||
58 | #else | ||
59 | /* | ||
60 | * The convention for FLAC__fixedpoint is to use the upper 16 bits | ||
61 | * for the integer part and lower 16 bits for the fractional part. | ||
62 | */ | ||
63 | typedef FLAC__int32 FLAC__fixedpoint; | ||
64 | extern const FLAC__fixedpoint FLAC__FP_ZERO; | ||
65 | extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; | ||
66 | extern const FLAC__fixedpoint FLAC__FP_ONE; | ||
67 | extern const FLAC__fixedpoint FLAC__FP_LN2; | ||
68 | extern const FLAC__fixedpoint FLAC__FP_E; | ||
69 | |||
70 | #define FLAC__fixedpoint_trunc(x) ((x)>>16) | ||
71 | |||
72 | #define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) ) | ||
73 | |||
74 | #define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) | ||
75 | |||
76 | /* | ||
77 | * FLAC__fixedpoint_log2() | ||
78 | * -------------------------------------------------------------------- | ||
79 | * Returns the base-2 logarithm of the fixed-point number 'x' using an | ||
80 | * algorithm by Knuth for x >= 1.0 | ||
81 | * | ||
82 | * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must | ||
83 | * be < 32 and evenly divisible by 4 (0 is OK but not very precise). | ||
84 | * | ||
85 | * 'precision' roughly limits the number of iterations that are done; | ||
86 | * use (unsigned)(-1) for maximum precision. | ||
87 | * | ||
88 | * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this | ||
89 | * function will punt and return 0. | ||
90 | * | ||
91 | * The return value will also have 'fracbits' fractional bits. | ||
92 | */ | ||
93 | FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision); | ||
94 | |||
95 | #endif | ||
96 | |||
97 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/format.h b/apps/codecs/libFLAC/include/private/format.h new file mode 100644 index 0000000000..69589c873c --- /dev/null +++ b/apps/codecs/libFLAC/include/private/format.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__FORMAT_H | ||
33 | #define FLAC__PRIVATE__FORMAT_H | ||
34 | |||
35 | #include "FLAC/format.h" | ||
36 | |||
37 | unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order); | ||
38 | unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize); | ||
39 | unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order); | ||
40 | void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | ||
41 | void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | ||
42 | FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order); | ||
43 | |||
44 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/lpc.h b/apps/codecs/libFLAC/include/private/lpc.h new file mode 100644 index 0000000000..37286f5185 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/lpc.h | |||
@@ -0,0 +1,197 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__LPC_H | ||
33 | #define FLAC__PRIVATE__LPC_H | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include <config.h> | ||
37 | #endif | ||
38 | |||
39 | #include "private/float.h" | ||
40 | #include "FLAC/format.h" | ||
41 | |||
42 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
43 | |||
44 | /* | ||
45 | * FLAC__lpc_compute_autocorrelation() | ||
46 | * -------------------------------------------------------------------- | ||
47 | * Compute the autocorrelation for lags between 0 and lag-1. | ||
48 | * Assumes data[] outside of [0,data_len-1] == 0. | ||
49 | * Asserts that lag > 0. | ||
50 | * | ||
51 | * IN data[0,data_len-1] | ||
52 | * IN data_len | ||
53 | * IN 0 < lag <= data_len | ||
54 | * OUT autoc[0,lag-1] | ||
55 | */ | ||
56 | void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
57 | #ifndef FLAC__NO_ASM | ||
58 | # ifdef FLAC__CPU_IA32 | ||
59 | # ifdef FLAC__HAS_NASM | ||
60 | void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
61 | void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
62 | void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
63 | void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
64 | void FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
65 | # endif | ||
66 | # endif | ||
67 | #endif | ||
68 | |||
69 | /* | ||
70 | * FLAC__lpc_compute_lp_coefficients() | ||
71 | * -------------------------------------------------------------------- | ||
72 | * Computes LP coefficients for orders 1..max_order. | ||
73 | * Do not call if autoc[0] == 0.0. This means the signal is zero | ||
74 | * and there is no point in calculating a predictor. | ||
75 | * | ||
76 | * IN autoc[0,max_order] autocorrelation values | ||
77 | * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute | ||
78 | * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order | ||
79 | * *** IMPORTANT: | ||
80 | * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched | ||
81 | * OUT error[0,max_order-1] error for each order | ||
82 | * | ||
83 | * Example: if max_order is 9, the LP coefficients for order 9 will be | ||
84 | * in lp_coeff[8][0,8], the LP coefficients for order 8 will be | ||
85 | * in lp_coeff[7][0,7], etc. | ||
86 | */ | ||
87 | void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]); | ||
88 | |||
89 | /* | ||
90 | * FLAC__lpc_quantize_coefficients() | ||
91 | * -------------------------------------------------------------------- | ||
92 | * Quantizes the LP coefficients. NOTE: precision + bits_per_sample | ||
93 | * must be less than 32 (sizeof(FLAC__int32)*8). | ||
94 | * | ||
95 | * IN lp_coeff[0,order-1] LP coefficients | ||
96 | * IN order LP order | ||
97 | * IN FLAC__MIN_QLP_COEFF_PRECISION < precision | ||
98 | * desired precision (in bits, including sign | ||
99 | * bit) of largest coefficient | ||
100 | * OUT qlp_coeff[0,order-1] quantized coefficients | ||
101 | * OUT shift # of bits to shift right to get approximated | ||
102 | * LP coefficients. NOTE: could be negative. | ||
103 | * RETURN 0 => quantization OK | ||
104 | * 1 => coefficients require too much shifting for *shift to | ||
105 | * fit in the LPC subframe header. 'shift' is unset. | ||
106 | * 2 => coefficients are all zero, which is bad. 'shift' is | ||
107 | * unset. | ||
108 | */ | ||
109 | int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift); | ||
110 | |||
111 | /* | ||
112 | * FLAC__lpc_compute_residual_from_qlp_coefficients() | ||
113 | * -------------------------------------------------------------------- | ||
114 | * Compute the residual signal obtained from sutracting the predicted | ||
115 | * signal from the original. | ||
116 | * | ||
117 | * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | ||
118 | * IN data_len length of original signal | ||
119 | * IN qlp_coeff[0,order-1] quantized LP coefficients | ||
120 | * IN order > 0 LP order | ||
121 | * IN lp_quantization quantization of LP coefficients in bits | ||
122 | * OUT residual[0,data_len-1] residual signal | ||
123 | */ | ||
124 | void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
125 | void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
126 | #ifndef FLAC__NO_ASM | ||
127 | # ifdef FLAC__CPU_IA32 | ||
128 | # ifdef FLAC__HAS_NASM | ||
129 | void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
130 | void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
131 | # endif | ||
132 | # endif | ||
133 | #endif | ||
134 | |||
135 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
136 | |||
137 | /* | ||
138 | * FLAC__lpc_restore_signal() | ||
139 | * -------------------------------------------------------------------- | ||
140 | * Restore the original signal by summing the residual and the | ||
141 | * predictor. | ||
142 | * | ||
143 | * IN residual[0,data_len-1] residual signal | ||
144 | * IN data_len length of original signal | ||
145 | * IN qlp_coeff[0,order-1] quantized LP coefficients | ||
146 | * IN order > 0 LP order | ||
147 | * IN lp_quantization quantization of LP coefficients in bits | ||
148 | * *** IMPORTANT: the caller must pass in the historical samples: | ||
149 | * IN data[-order,-1] previously-reconstructed historical samples | ||
150 | * OUT data[0,data_len-1] original signal | ||
151 | */ | ||
152 | void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
153 | void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
154 | #ifndef FLAC__NO_ASM | ||
155 | # ifdef FLAC__CPU_IA32 | ||
156 | # ifdef FLAC__HAS_NASM | ||
157 | void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
158 | void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
159 | # endif /* FLAC__HAS_NASM */ | ||
160 | # elif defined FLAC__CPU_PPC | ||
161 | void FLAC__lpc_restore_signal_asm_ppc_altivec_16(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
162 | void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
163 | # endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */ | ||
164 | #endif /* FLAC__NO_ASM */ | ||
165 | |||
166 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
167 | |||
168 | /* | ||
169 | * FLAC__lpc_compute_expected_bits_per_residual_sample() | ||
170 | * -------------------------------------------------------------------- | ||
171 | * Compute the expected number of bits per residual signal sample | ||
172 | * based on the LP error (which is related to the residual variance). | ||
173 | * | ||
174 | * IN lpc_error >= 0.0 error returned from calculating LP coefficients | ||
175 | * IN total_samples > 0 # of samples in residual signal | ||
176 | * RETURN expected bits per sample | ||
177 | */ | ||
178 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples); | ||
179 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale); | ||
180 | |||
181 | /* | ||
182 | * FLAC__lpc_compute_best_order() | ||
183 | * -------------------------------------------------------------------- | ||
184 | * Compute the best order from the array of signal errors returned | ||
185 | * during coefficient computation. | ||
186 | * | ||
187 | * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients | ||
188 | * IN max_order > 0 max LP order | ||
189 | * IN total_samples > 0 # of samples in residual signal | ||
190 | * IN bits_per_signal_sample # of bits per sample in the original signal | ||
191 | * RETURN [1,max_order] best order | ||
192 | */ | ||
193 | unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample); | ||
194 | |||
195 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
196 | |||
197 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/md5.h b/apps/codecs/libFLAC/include/private/md5.h new file mode 100644 index 0000000000..e85326015f --- /dev/null +++ b/apps/codecs/libFLAC/include/private/md5.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * This is the header file for the MD5 message-digest algorithm. | ||
3 | * The algorithm is due to Ron Rivest. This code was | ||
4 | * written by Colin Plumb in 1993, no copyright is claimed. | ||
5 | * This code is in the public domain; do with it what you wish. | ||
6 | * | ||
7 | * Equivalent code is available from RSA Data Security, Inc. | ||
8 | * This code has been tested against that, and is equivalent, | ||
9 | * except that you don't need to include two pages of legalese | ||
10 | * with every copy. | ||
11 | * | ||
12 | * To compute the message digest of a chunk of bytes, declare an | ||
13 | * MD5Context structure, pass it to MD5Init, call MD5Update as | ||
14 | * needed on buffers full of bytes, and then call MD5Final, which | ||
15 | * will fill a supplied 16-byte array with the digest. | ||
16 | * | ||
17 | * Changed so as no longer to depend on Colin Plumb's `usual.h' | ||
18 | * header definitions; now uses stuff from dpkg's config.h | ||
19 | * - Ian Jackson <ijackson@nyx.cs.du.edu>. | ||
20 | * Still in the public domain. | ||
21 | * | ||
22 | * Josh Coalson: made some changes to integrate with libFLAC. | ||
23 | * Still in the public domain. | ||
24 | */ | ||
25 | |||
26 | #ifndef FLAC__PRIVATE__MD5_H | ||
27 | #define FLAC__PRIVATE__MD5_H | ||
28 | |||
29 | #define md5byte unsigned char | ||
30 | |||
31 | /* | ||
32 | * Due to an unholy abomination in libOggFLAC (it requires access to | ||
33 | * these internal MD5 functions) we have to #include "FLAC/export.h" | ||
34 | * and export them when building a DLL | ||
35 | */ | ||
36 | #include "FLAC/export.h" | ||
37 | #include "FLAC/ordinals.h" | ||
38 | |||
39 | struct FLAC__MD5Context { | ||
40 | FLAC__uint32 buf[4]; | ||
41 | FLAC__uint32 bytes[2]; | ||
42 | FLAC__uint32 in[16]; | ||
43 | FLAC__byte *internal_buf; | ||
44 | unsigned capacity; | ||
45 | }; | ||
46 | |||
47 | FLAC_API void FLAC__MD5Init(struct FLAC__MD5Context *context); | ||
48 | FLAC_API void FLAC__MD5Update(struct FLAC__MD5Context *context, md5byte const *buf, unsigned len); | ||
49 | FLAC_API void FLAC__MD5Final(md5byte digest[16], struct FLAC__MD5Context *context); | ||
50 | void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]); | ||
51 | |||
52 | FLAC_API FLAC__bool FLAC__MD5Accumulate(struct FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample); | ||
53 | |||
54 | #endif /* !MD5_H */ | ||
diff --git a/apps/codecs/libFLAC/include/private/memory.h b/apps/codecs/libFLAC/include/private/memory.h new file mode 100644 index 0000000000..fca808155b --- /dev/null +++ b/apps/codecs/libFLAC/include/private/memory.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__MEMORY_H | ||
33 | #define FLAC__PRIVATE__MEMORY_H | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include <config.h> | ||
37 | #endif | ||
38 | |||
39 | #include <stdlib.h> /* for size_t */ | ||
40 | |||
41 | #include "private/float.h" | ||
42 | #include "FLAC/ordinals.h" /* for FLAC__bool */ | ||
43 | |||
44 | /* Returns the unaligned address returned by malloc. | ||
45 | * Use free() on this address to deallocate. | ||
46 | */ | ||
47 | void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); | ||
48 | FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); | ||
49 | FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); | ||
50 | FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); | ||
51 | FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); | ||
52 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
53 | FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); | ||
54 | #endif | ||
55 | |||
56 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/metadata.h b/apps/codecs/libFLAC/include/private/metadata.h new file mode 100644 index 0000000000..f95e2deab5 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/metadata.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__METADATA_H | ||
33 | #define FLAC__PRIVATE__METADATA_H | ||
34 | |||
35 | #include "FLAC/metadata.h" | ||
36 | |||
37 | void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); | ||
38 | void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); | ||
39 | |||
40 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/private/stream_encoder_framing.h b/apps/codecs/libFLAC/include/private/stream_encoder_framing.h new file mode 100644 index 0000000000..5b5426a3e1 --- /dev/null +++ b/apps/codecs/libFLAC/include/private/stream_encoder_framing.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | ||
33 | #define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | ||
34 | |||
35 | #include "FLAC/format.h" | ||
36 | #include "bitbuffer.h" | ||
37 | |||
38 | FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitBuffer *bb); | ||
39 | FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool streamable_subset, FLAC__BitBuffer *bb); | ||
40 | FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb); | ||
41 | FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb); | ||
42 | FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb); | ||
43 | FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb); | ||
44 | |||
45 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/all.h b/apps/codecs/libFLAC/include/protected/all.h new file mode 100644 index 0000000000..12e7ae2a5e --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/all.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__ALL_H | ||
33 | #define FLAC__PROTECTED__ALL_H | ||
34 | |||
35 | #include "file_decoder.h" | ||
36 | #include "file_encoder.h" | ||
37 | #include "seekable_stream_decoder.h" | ||
38 | #include "seekable_stream_encoder.h" | ||
39 | #include "stream_decoder.h" | ||
40 | #include "stream_encoder.h" | ||
41 | |||
42 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/file_decoder.h b/apps/codecs/libFLAC/include/protected/file_decoder.h new file mode 100644 index 0000000000..88662bb34d --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/file_decoder.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__FILE_DECODER_H | ||
33 | #define FLAC__PROTECTED__FILE_DECODER_H | ||
34 | |||
35 | #include "FLAC/file_decoder.h" | ||
36 | |||
37 | typedef struct FLAC__FileDecoderProtected { | ||
38 | FLAC__FileDecoderState state; | ||
39 | } FLAC__FileDecoderProtected; | ||
40 | |||
41 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/file_encoder.h b/apps/codecs/libFLAC/include/protected/file_encoder.h new file mode 100644 index 0000000000..1d516d1da8 --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/file_encoder.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__FILE_ENCODER_H | ||
33 | #define FLAC__PROTECTED__FILE_ENCODER_H | ||
34 | |||
35 | #include "FLAC/file_encoder.h" | ||
36 | |||
37 | typedef struct FLAC__FileEncoderProtected { | ||
38 | FLAC__FileEncoderState state; | ||
39 | } FLAC__FileEncoderProtected; | ||
40 | |||
41 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/seekable_stream_decoder.h b/apps/codecs/libFLAC/include/protected/seekable_stream_decoder.h new file mode 100644 index 0000000000..71123da898 --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/seekable_stream_decoder.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__SEEKABLE_STREAM_DECODER_H | ||
33 | #define FLAC__PROTECTED__SEEKABLE_STREAM_DECODER_H | ||
34 | |||
35 | #include "FLAC/seekable_stream_decoder.h" | ||
36 | |||
37 | typedef struct FLAC__SeekableStreamDecoderProtected { | ||
38 | FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ | ||
39 | FLAC__SeekableStreamDecoderState state; | ||
40 | } FLAC__SeekableStreamDecoderProtected; | ||
41 | |||
42 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/seekable_stream_encoder.h b/apps/codecs/libFLAC/include/protected/seekable_stream_encoder.h new file mode 100644 index 0000000000..3341d9a5aa --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/seekable_stream_encoder.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H | ||
33 | #define FLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H | ||
34 | |||
35 | #include "FLAC/seekable_stream_encoder.h" | ||
36 | |||
37 | typedef struct FLAC__SeekableStreamEncoderProtected { | ||
38 | FLAC__SeekableStreamEncoderState state; | ||
39 | FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; | ||
40 | } FLAC__SeekableStreamEncoderProtected; | ||
41 | |||
42 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/stream_decoder.h b/apps/codecs/libFLAC/include/protected/stream_decoder.h new file mode 100644 index 0000000000..15eaf28d71 --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/stream_decoder.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__STREAM_DECODER_H | ||
33 | #define FLAC__PROTECTED__STREAM_DECODER_H | ||
34 | |||
35 | #include "FLAC/stream_decoder.h" | ||
36 | |||
37 | typedef struct FLAC__StreamDecoderProtected { | ||
38 | FLAC__StreamDecoderState state; | ||
39 | unsigned channels; | ||
40 | FLAC__ChannelAssignment channel_assignment; | ||
41 | unsigned bits_per_sample; | ||
42 | unsigned sample_rate; /* in Hz */ | ||
43 | unsigned blocksize; /* in samples (per channel) */ | ||
44 | } FLAC__StreamDecoderProtected; | ||
45 | |||
46 | /* | ||
47 | * return the number of input bytes consumed | ||
48 | */ | ||
49 | unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); | ||
50 | |||
51 | #endif | ||
diff --git a/apps/codecs/libFLAC/include/protected/stream_encoder.h b/apps/codecs/libFLAC/include/protected/stream_encoder.h new file mode 100644 index 0000000000..86495cc9ae --- /dev/null +++ b/apps/codecs/libFLAC/include/protected/stream_encoder.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifndef FLAC__PROTECTED__STREAM_ENCODER_H | ||
33 | #define FLAC__PROTECTED__STREAM_ENCODER_H | ||
34 | |||
35 | #include "FLAC/stream_encoder.h" | ||
36 | |||
37 | typedef struct FLAC__StreamEncoderProtected { | ||
38 | FLAC__StreamEncoderState state; | ||
39 | FLAC__bool verify; | ||
40 | FLAC__bool streamable_subset; | ||
41 | FLAC__bool do_mid_side_stereo; | ||
42 | FLAC__bool loose_mid_side_stereo; | ||
43 | unsigned channels; | ||
44 | unsigned bits_per_sample; | ||
45 | unsigned sample_rate; | ||
46 | unsigned blocksize; | ||
47 | unsigned max_lpc_order; | ||
48 | unsigned qlp_coeff_precision; | ||
49 | FLAC__bool do_qlp_coeff_prec_search; | ||
50 | FLAC__bool do_exhaustive_model_search; | ||
51 | FLAC__bool do_escape_coding; | ||
52 | unsigned min_residual_partition_order; | ||
53 | unsigned max_residual_partition_order; | ||
54 | unsigned rice_parameter_search_dist; | ||
55 | FLAC__uint64 total_samples_estimate; | ||
56 | FLAC__StreamMetadata **metadata; | ||
57 | unsigned num_metadata_blocks; | ||
58 | } FLAC__StreamEncoderProtected; | ||
59 | |||
60 | #endif | ||
diff --git a/apps/codecs/libFLAC/lpc.c b/apps/codecs/libFLAC/lpc.c new file mode 100644 index 0000000000..b846db5cb1 --- /dev/null +++ b/apps/codecs/libFLAC/lpc.c | |||
@@ -0,0 +1,430 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <math.h> | ||
33 | #include "FLAC/assert.h" | ||
34 | #include "FLAC/format.h" | ||
35 | #include "private/bitmath.h" | ||
36 | #include "private/lpc.h" | ||
37 | #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE | ||
38 | #include <stdio.h> | ||
39 | #endif | ||
40 | |||
41 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
42 | |||
43 | #ifndef M_LN2 | ||
44 | /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ | ||
45 | #define M_LN2 0.69314718055994530942 | ||
46 | #endif | ||
47 | |||
48 | void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]) | ||
49 | { | ||
50 | /* a readable, but slower, version */ | ||
51 | #if 0 | ||
52 | FLAC__real d; | ||
53 | unsigned i; | ||
54 | |||
55 | FLAC__ASSERT(lag > 0); | ||
56 | FLAC__ASSERT(lag <= data_len); | ||
57 | |||
58 | while(lag--) { | ||
59 | for(i = lag, d = 0.0; i < data_len; i++) | ||
60 | d += data[i] * data[i - lag]; | ||
61 | autoc[lag] = d; | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | /* | ||
66 | * this version tends to run faster because of better data locality | ||
67 | * ('data_len' is usually much larger than 'lag') | ||
68 | */ | ||
69 | FLAC__real d; | ||
70 | unsigned sample, coeff; | ||
71 | const unsigned limit = data_len - lag; | ||
72 | |||
73 | FLAC__ASSERT(lag > 0); | ||
74 | FLAC__ASSERT(lag <= data_len); | ||
75 | |||
76 | for(coeff = 0; coeff < lag; coeff++) | ||
77 | autoc[coeff] = 0.0; | ||
78 | for(sample = 0; sample <= limit; sample++) { | ||
79 | d = data[sample]; | ||
80 | for(coeff = 0; coeff < lag; coeff++) | ||
81 | autoc[coeff] += d * data[sample+coeff]; | ||
82 | } | ||
83 | for(; sample < data_len; sample++) { | ||
84 | d = data[sample]; | ||
85 | for(coeff = 0; coeff < data_len - sample; coeff++) | ||
86 | autoc[coeff] += d * data[sample+coeff]; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]) | ||
91 | { | ||
92 | unsigned i, j; | ||
93 | FLAC__double r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER]; | ||
94 | |||
95 | FLAC__ASSERT(0 < max_order); | ||
96 | FLAC__ASSERT(max_order <= FLAC__MAX_LPC_ORDER); | ||
97 | FLAC__ASSERT(autoc[0] != 0.0); | ||
98 | |||
99 | err = autoc[0]; | ||
100 | |||
101 | for(i = 0; i < max_order; i++) { | ||
102 | /* Sum up this iteration's reflection coefficient. */ | ||
103 | r = -autoc[i+1]; | ||
104 | for(j = 0; j < i; j++) | ||
105 | r -= lpc[j] * autoc[i-j]; | ||
106 | ref[i] = (r/=err); | ||
107 | |||
108 | /* Update LPC coefficients and total error. */ | ||
109 | lpc[i]=r; | ||
110 | for(j = 0; j < (i>>1); j++) { | ||
111 | FLAC__double tmp = lpc[j]; | ||
112 | lpc[j] += r * lpc[i-1-j]; | ||
113 | lpc[i-1-j] += r * tmp; | ||
114 | } | ||
115 | if(i & 1) | ||
116 | lpc[j] += lpc[j] * r; | ||
117 | |||
118 | err *= (1.0 - r * r); | ||
119 | |||
120 | /* save this order */ | ||
121 | for(j = 0; j <= i; j++) | ||
122 | lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ | ||
123 | error[i] = err; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift) | ||
128 | { | ||
129 | unsigned i; | ||
130 | FLAC__double d, cmax = -1e32; | ||
131 | FLAC__int32 qmax, qmin; | ||
132 | const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1; | ||
133 | const int min_shiftlimit = -max_shiftlimit - 1; | ||
134 | |||
135 | FLAC__ASSERT(precision > 0); | ||
136 | FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION); | ||
137 | |||
138 | /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */ | ||
139 | precision--; | ||
140 | qmax = 1 << precision; | ||
141 | qmin = -qmax; | ||
142 | qmax--; | ||
143 | |||
144 | for(i = 0; i < order; i++) { | ||
145 | if(lp_coeff[i] == 0.0) | ||
146 | continue; | ||
147 | d = fabs(lp_coeff[i]); | ||
148 | if(d > cmax) | ||
149 | cmax = d; | ||
150 | } | ||
151 | redo_it: | ||
152 | if(cmax <= 0.0) { | ||
153 | /* => coefficients are all 0, which means our constant-detect didn't work */ | ||
154 | return 2; | ||
155 | } | ||
156 | else { | ||
157 | int log2cmax; | ||
158 | |||
159 | (void)frexp(cmax, &log2cmax); | ||
160 | log2cmax--; | ||
161 | *shift = (int)precision - log2cmax - 1; | ||
162 | |||
163 | if(*shift < min_shiftlimit || *shift > max_shiftlimit) { | ||
164 | #if 0 | ||
165 | /*@@@ this does not seem to help at all, but was not extensively tested either: */ | ||
166 | if(*shift > max_shiftlimit) | ||
167 | *shift = max_shiftlimit; | ||
168 | else | ||
169 | #endif | ||
170 | return 1; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | if(*shift >= 0) { | ||
175 | for(i = 0; i < order; i++) { | ||
176 | qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift)); | ||
177 | |||
178 | /* double-check the result */ | ||
179 | if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) { | ||
180 | #ifdef FLAC__OVERFLOW_DETECT | ||
181 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: compensating for overflow, qlp_coeff[%u]=%d, lp_coeff[%u]=%f, cmax=%f, precision=%u, shift=%d, q=%f, f(q)=%f\n", i, qlp_coeff[i], i, lp_coeff[i], cmax, precision, *shift, (FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift), floor((FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift))); | ||
182 | #endif | ||
183 | cmax *= 2.0; | ||
184 | goto redo_it; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | else { /* (*shift < 0) */ | ||
189 | const int nshift = -(*shift); | ||
190 | #ifdef DEBUG | ||
191 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift = %d\n", *shift); | ||
192 | #endif | ||
193 | for(i = 0; i < order; i++) { | ||
194 | qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift)); | ||
195 | |||
196 | /* double-check the result */ | ||
197 | if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) { | ||
198 | #ifdef FLAC__OVERFLOW_DETECT | ||
199 | fprintf(stderr,"FLAC__lpc_quantize_coefficients: compensating for overflow, qlp_coeff[%u]=%d, lp_coeff[%u]=%f, cmax=%f, precision=%u, shift=%d, q=%f, f(q)=%f\n", i, qlp_coeff[i], i, lp_coeff[i], cmax, precision, *shift, (FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift), floor((FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift))); | ||
200 | #endif | ||
201 | cmax *= 2.0; | ||
202 | goto redo_it; | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) | ||
211 | { | ||
212 | #ifdef FLAC__OVERFLOW_DETECT | ||
213 | FLAC__int64 sumo; | ||
214 | #endif | ||
215 | unsigned i, j; | ||
216 | FLAC__int32 sum; | ||
217 | const FLAC__int32 *history; | ||
218 | |||
219 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE | ||
220 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); | ||
221 | for(i=0;i<order;i++) | ||
222 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); | ||
223 | fprintf(stderr,"\n"); | ||
224 | #endif | ||
225 | FLAC__ASSERT(order > 0); | ||
226 | |||
227 | for(i = 0; i < data_len; i++) { | ||
228 | #ifdef FLAC__OVERFLOW_DETECT | ||
229 | sumo = 0; | ||
230 | #endif | ||
231 | sum = 0; | ||
232 | history = data; | ||
233 | for(j = 0; j < order; j++) { | ||
234 | sum += qlp_coeff[j] * (*(--history)); | ||
235 | #ifdef FLAC__OVERFLOW_DETECT | ||
236 | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | ||
237 | #if defined _MSC_VER | ||
238 | if(sumo > 2147483647I64 || sumo < -2147483648I64) | ||
239 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo); | ||
240 | #else | ||
241 | if(sumo > 2147483647ll || sumo < -2147483648ll) | ||
242 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,sumo); | ||
243 | #endif | ||
244 | #endif | ||
245 | } | ||
246 | *(residual++) = *(data++) - (sum >> lp_quantization); | ||
247 | } | ||
248 | |||
249 | /* Here's a slower but clearer version: | ||
250 | for(i = 0; i < data_len; i++) { | ||
251 | sum = 0; | ||
252 | for(j = 0; j < order; j++) | ||
253 | sum += qlp_coeff[j] * data[i-j-1]; | ||
254 | residual[i] = data[i] - (sum >> lp_quantization); | ||
255 | } | ||
256 | */ | ||
257 | } | ||
258 | |||
259 | void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) | ||
260 | { | ||
261 | unsigned i, j; | ||
262 | FLAC__int64 sum; | ||
263 | const FLAC__int32 *history; | ||
264 | |||
265 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE | ||
266 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); | ||
267 | for(i=0;i<order;i++) | ||
268 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); | ||
269 | fprintf(stderr,"\n"); | ||
270 | #endif | ||
271 | FLAC__ASSERT(order > 0); | ||
272 | |||
273 | for(i = 0; i < data_len; i++) { | ||
274 | sum = 0; | ||
275 | history = data; | ||
276 | for(j = 0; j < order; j++) | ||
277 | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | ||
278 | #ifdef FLAC__OVERFLOW_DETECT | ||
279 | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | ||
280 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization); | ||
281 | break; | ||
282 | } | ||
283 | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { | ||
284 | fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%lld, residual=%lld\n", i, *data, sum >> lp_quantization, (FLAC__int64)(*data) - (sum >> lp_quantization)); | ||
285 | break; | ||
286 | } | ||
287 | #endif | ||
288 | *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
293 | |||
294 | void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) | ||
295 | { | ||
296 | #ifdef FLAC__OVERFLOW_DETECT | ||
297 | FLAC__int64 sumo; | ||
298 | #endif | ||
299 | unsigned i, j; | ||
300 | FLAC__int32 sum; | ||
301 | const FLAC__int32 *history; | ||
302 | |||
303 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE | ||
304 | fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); | ||
305 | for(i=0;i<order;i++) | ||
306 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); | ||
307 | fprintf(stderr,"\n"); | ||
308 | #endif | ||
309 | FLAC__ASSERT(order > 0); | ||
310 | |||
311 | for(i = 0; i < data_len; i++) { | ||
312 | #ifdef FLAC__OVERFLOW_DETECT | ||
313 | sumo = 0; | ||
314 | #endif | ||
315 | sum = 0; | ||
316 | history = data; | ||
317 | for(j = 0; j < order; j++) { | ||
318 | sum += qlp_coeff[j] * (*(--history)); | ||
319 | #ifdef FLAC__OVERFLOW_DETECT | ||
320 | sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); | ||
321 | #if defined _MSC_VER | ||
322 | if(sumo > 2147483647I64 || sumo < -2147483648I64) | ||
323 | fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo); | ||
324 | #else | ||
325 | if(sumo > 2147483647ll || sumo < -2147483648ll) | ||
326 | fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,sumo); | ||
327 | #endif | ||
328 | #endif | ||
329 | } | ||
330 | *(data++) = *(residual++) + (sum >> lp_quantization); | ||
331 | } | ||
332 | |||
333 | /* Here's a slower but clearer version: | ||
334 | for(i = 0; i < data_len; i++) { | ||
335 | sum = 0; | ||
336 | for(j = 0; j < order; j++) | ||
337 | sum += qlp_coeff[j] * data[i-j-1]; | ||
338 | data[i] = residual[i] + (sum >> lp_quantization); | ||
339 | } | ||
340 | */ | ||
341 | } | ||
342 | |||
343 | void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) | ||
344 | { | ||
345 | unsigned i, j; | ||
346 | FLAC__int64 sum; | ||
347 | const FLAC__int32 *history; | ||
348 | |||
349 | #ifdef FLAC__OVERFLOW_DETECT_VERBOSE | ||
350 | fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization); | ||
351 | for(i=0;i<order;i++) | ||
352 | fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]); | ||
353 | fprintf(stderr,"\n"); | ||
354 | #endif | ||
355 | FLAC__ASSERT(order > 0); | ||
356 | |||
357 | for(i = 0; i < data_len; i++) { | ||
358 | sum = 0; | ||
359 | history = data; | ||
360 | for(j = 0; j < order; j++) | ||
361 | sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); | ||
362 | #ifdef FLAC__OVERFLOW_DETECT | ||
363 | if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) { | ||
364 | fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization); | ||
365 | break; | ||
366 | } | ||
367 | if(FLAC__bitmath_silog2_wide((FLAC__int64)(*residual) + (sum >> lp_quantization)) > 32) { | ||
368 | fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%lld, data=%lld\n", i, *residual, sum >> lp_quantization, (FLAC__int64)(*residual) + (sum >> lp_quantization)); | ||
369 | break; | ||
370 | } | ||
371 | #endif | ||
372 | *(data++) = *(residual++) + (FLAC__int32)(sum >> lp_quantization); | ||
373 | } | ||
374 | } | ||
375 | |||
376 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
377 | |||
378 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) | ||
379 | { | ||
380 | FLAC__double error_scale; | ||
381 | |||
382 | FLAC__ASSERT(total_samples > 0); | ||
383 | |||
384 | error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples; | ||
385 | |||
386 | return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale); | ||
387 | } | ||
388 | |||
389 | FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale) | ||
390 | { | ||
391 | if(lpc_error > 0.0) { | ||
392 | FLAC__double bps = (FLAC__double)0.5 * log(error_scale * lpc_error) / M_LN2; | ||
393 | if(bps >= 0.0) | ||
394 | return bps; | ||
395 | else | ||
396 | return 0.0; | ||
397 | } | ||
398 | else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */ | ||
399 | return 1e32; | ||
400 | } | ||
401 | else { | ||
402 | return 0.0; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample) | ||
407 | { | ||
408 | unsigned order, best_order; | ||
409 | FLAC__double best_bits, tmp_bits, error_scale; | ||
410 | |||
411 | FLAC__ASSERT(max_order > 0); | ||
412 | FLAC__ASSERT(total_samples > 0); | ||
413 | |||
414 | error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples; | ||
415 | |||
416 | best_order = 0; | ||
417 | best_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[0], error_scale) * (FLAC__double)total_samples; | ||
418 | |||
419 | for(order = 1; order < max_order; order++) { | ||
420 | tmp_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[order], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * bits_per_signal_sample); | ||
421 | if(tmp_bits < best_bits) { | ||
422 | best_order = order; | ||
423 | best_bits = tmp_bits; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | return best_order+1; /* +1 since index of lpc_error[] is order-1 */ | ||
428 | } | ||
429 | |||
430 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
diff --git a/apps/codecs/libFLAC/md5.c b/apps/codecs/libFLAC/md5.c new file mode 100644 index 0000000000..9679387db9 --- /dev/null +++ b/apps/codecs/libFLAC/md5.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* | ||
2 | * This code implements the MD5 message-digest algorithm. | ||
3 | * The algorithm is due to Ron Rivest. This code was | ||
4 | * written by Colin Plumb in 1993, no copyright is claimed. | ||
5 | * This code is in the public domain; do with it what you wish. | ||
6 | * | ||
7 | * Equivalent code is available from RSA Data Security, Inc. | ||
8 | * This code has been tested against that, and is equivalent, | ||
9 | * except that you don't need to include two pages of legalese | ||
10 | * with every copy. | ||
11 | * | ||
12 | * To compute the message digest of a chunk of bytes, declare an | ||
13 | * MD5Context structure, pass it to MD5Init, call MD5Update as | ||
14 | * needed on buffers full of bytes, and then call MD5Final, which | ||
15 | * will fill a supplied 16-byte array with the digest. | ||
16 | * | ||
17 | * Changed so as no longer to depend on Colin Plumb's `usual.h' header | ||
18 | * definitions; now uses stuff from dpkg's config.h. | ||
19 | * - Ian Jackson <ijackson@nyx.cs.du.edu>. | ||
20 | * Still in the public domain. | ||
21 | * | ||
22 | * Josh Coalson: made some changes to integrate with libFLAC. | ||
23 | * Still in the public domain. | ||
24 | */ | ||
25 | |||
26 | #include <stdlib.h> /* for malloc() */ | ||
27 | #include <string.h> /* for memcpy() */ | ||
28 | |||
29 | #include "private/md5.h" | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include <config.h> | ||
33 | #endif | ||
34 | |||
35 | #ifndef FLaC__INLINE | ||
36 | #define FLaC__INLINE | ||
37 | #endif | ||
38 | |||
39 | static FLAC__bool is_big_endian_host_; | ||
40 | |||
41 | #ifndef ASM_MD5 | ||
42 | |||
43 | /* The four core functions - F1 is optimized somewhat */ | ||
44 | |||
45 | /* #define F1(x, y, z) (x & y | ~x & z) */ | ||
46 | #define F1(x, y, z) (z ^ (x & (y ^ z))) | ||
47 | #define F2(x, y, z) F1(z, x, y) | ||
48 | #define F3(x, y, z) (x ^ y ^ z) | ||
49 | #define F4(x, y, z) (y ^ (x | ~z)) | ||
50 | |||
51 | /* This is the central step in the MD5 algorithm. */ | ||
52 | #define MD5STEP(f,w,x,y,z,in,s) \ | ||
53 | (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) | ||
54 | |||
55 | /* | ||
56 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | ||
57 | * reflect the addition of 16 longwords of new data. MD5Update blocks | ||
58 | * the data and converts bytes into longwords for this routine. | ||
59 | */ | ||
60 | FLaC__INLINE | ||
61 | void | ||
62 | FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) | ||
63 | { | ||
64 | register FLAC__uint32 a, b, c, d; | ||
65 | |||
66 | a = buf[0]; | ||
67 | b = buf[1]; | ||
68 | c = buf[2]; | ||
69 | d = buf[3]; | ||
70 | |||
71 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); | ||
72 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); | ||
73 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); | ||
74 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); | ||
75 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); | ||
76 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); | ||
77 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); | ||
78 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); | ||
79 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); | ||
80 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); | ||
81 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); | ||
82 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); | ||
83 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); | ||
84 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); | ||
85 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); | ||
86 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); | ||
87 | |||
88 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); | ||
89 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); | ||
90 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); | ||
91 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); | ||
92 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); | ||
93 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); | ||
94 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); | ||
95 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); | ||
96 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); | ||
97 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); | ||
98 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); | ||
99 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); | ||
100 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); | ||
101 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); | ||
102 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); | ||
103 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); | ||
104 | |||
105 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); | ||
106 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); | ||
107 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); | ||
108 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); | ||
109 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); | ||
110 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); | ||
111 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); | ||
112 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); | ||
113 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); | ||
114 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); | ||
115 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); | ||
116 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); | ||
117 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); | ||
118 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); | ||
119 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); | ||
120 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); | ||
121 | |||
122 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); | ||
123 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); | ||
124 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); | ||
125 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); | ||
126 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); | ||
127 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); | ||
128 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); | ||
129 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); | ||
130 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); | ||
131 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | ||
132 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | ||
133 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | ||
134 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | ||
135 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | ||
136 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | ||
137 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | ||
138 | |||
139 | buf[0] += a; | ||
140 | buf[1] += b; | ||
141 | buf[2] += c; | ||
142 | buf[3] += d; | ||
143 | } | ||
144 | |||
145 | #endif | ||
146 | |||
147 | FLaC__INLINE | ||
148 | void | ||
149 | byteSwap(FLAC__uint32 *buf, unsigned words) | ||
150 | { | ||
151 | md5byte *p = (md5byte *)buf; | ||
152 | |||
153 | if(!is_big_endian_host_) | ||
154 | return; | ||
155 | do { | ||
156 | *buf++ = (FLAC__uint32)((unsigned)p[3] << 8 | p[2]) << 16 | ((unsigned)p[1] << 8 | p[0]); | ||
157 | p += 4; | ||
158 | } while (--words); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | ||
163 | * initialization constants. | ||
164 | */ | ||
165 | void | ||
166 | FLAC__MD5Init(struct FLAC__MD5Context *ctx) | ||
167 | { | ||
168 | FLAC__uint32 test = 1; | ||
169 | |||
170 | is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true; | ||
171 | |||
172 | ctx->buf[0] = 0x67452301; | ||
173 | ctx->buf[1] = 0xefcdab89; | ||
174 | ctx->buf[2] = 0x98badcfe; | ||
175 | ctx->buf[3] = 0x10325476; | ||
176 | |||
177 | ctx->bytes[0] = 0; | ||
178 | ctx->bytes[1] = 0; | ||
179 | |||
180 | ctx->internal_buf = 0; | ||
181 | ctx->capacity = 0; | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Update context to reflect the concatenation of another buffer full | ||
186 | * of bytes. | ||
187 | */ | ||
188 | void | ||
189 | FLAC__MD5Update(struct FLAC__MD5Context *ctx, md5byte const *buf, unsigned len) | ||
190 | { | ||
191 | FLAC__uint32 t; | ||
192 | |||
193 | /* Update byte count */ | ||
194 | |||
195 | t = ctx->bytes[0]; | ||
196 | if ((ctx->bytes[0] = t + len) < t) | ||
197 | ctx->bytes[1]++; /* Carry from low to high */ | ||
198 | |||
199 | t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ | ||
200 | if (t > len) { | ||
201 | memcpy((md5byte *)ctx->in + 64 - t, buf, len); | ||
202 | return; | ||
203 | } | ||
204 | /* First chunk is an odd size */ | ||
205 | memcpy((md5byte *)ctx->in + 64 - t, buf, t); | ||
206 | byteSwap(ctx->in, 16); | ||
207 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
208 | buf += t; | ||
209 | len -= t; | ||
210 | |||
211 | /* Process data in 64-byte chunks */ | ||
212 | while (len >= 64) { | ||
213 | memcpy(ctx->in, buf, 64); | ||
214 | byteSwap(ctx->in, 16); | ||
215 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
216 | buf += 64; | ||
217 | len -= 64; | ||
218 | } | ||
219 | |||
220 | /* Handle any remaining bytes of data. */ | ||
221 | memcpy(ctx->in, buf, len); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. | ||
226 | */ | ||
227 | FLAC__bool | ||
228 | FLAC__MD5Accumulate(struct FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) | ||
229 | { | ||
230 | unsigned channel, sample, a_byte; | ||
231 | FLAC__int32 a_word; | ||
232 | FLAC__byte *buf_; | ||
233 | const unsigned bytes_needed = channels * samples * bytes_per_sample; | ||
234 | |||
235 | if(ctx->capacity < bytes_needed) { | ||
236 | FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed); | ||
237 | if(0 == tmp) { | ||
238 | free(ctx->internal_buf); | ||
239 | if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed))) | ||
240 | return false; | ||
241 | } | ||
242 | ctx->internal_buf = tmp; | ||
243 | ctx->capacity = bytes_needed; | ||
244 | } | ||
245 | |||
246 | buf_ = ctx->internal_buf; | ||
247 | |||
248 | #ifdef FLAC__CPU_IA32 | ||
249 | if(channels == 2 && bytes_per_sample == 2) { | ||
250 | memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples); | ||
251 | buf_ += sizeof(FLAC__int16); | ||
252 | for(sample = 0; sample < samples; sample++) | ||
253 | ((FLAC__int16 *)buf_)[2 * sample] = (FLAC__int16)signal[1][sample]; | ||
254 | } | ||
255 | else if(channels == 1 && bytes_per_sample == 2) { | ||
256 | for(sample = 0; sample < samples; sample++) | ||
257 | ((FLAC__int16 *)buf_)[sample] = (FLAC__int16)signal[0][sample]; | ||
258 | } | ||
259 | else | ||
260 | #endif | ||
261 | for(sample = 0; sample < samples; sample++) { | ||
262 | for(channel = 0; channel < channels; channel++) { | ||
263 | a_word = signal[channel][sample]; | ||
264 | for(a_byte = 0; a_byte < bytes_per_sample; a_byte++) { | ||
265 | *buf_++ = (FLAC__byte)(a_word & 0xff); | ||
266 | a_word >>= 8; | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed); | ||
272 | |||
273 | return true; | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * Final wrapup - pad to 64-byte boundary with the bit pattern | ||
278 | * 1 0* (64-bit count of bits processed, MSB-first) | ||
279 | */ | ||
280 | void | ||
281 | FLAC__MD5Final(md5byte digest[16], struct FLAC__MD5Context *ctx) | ||
282 | { | ||
283 | int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ | ||
284 | md5byte *p = (md5byte *)ctx->in + count; | ||
285 | |||
286 | /* Set the first char of padding to 0x80. There is always room. */ | ||
287 | *p++ = 0x80; | ||
288 | |||
289 | /* Bytes of padding needed to make 56 bytes (-8..55) */ | ||
290 | count = 56 - 1 - count; | ||
291 | |||
292 | if (count < 0) { /* Padding forces an extra block */ | ||
293 | memset(p, 0, count + 8); | ||
294 | byteSwap(ctx->in, 16); | ||
295 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
296 | p = (md5byte *)ctx->in; | ||
297 | count = 56; | ||
298 | } | ||
299 | memset(p, 0, count); | ||
300 | byteSwap(ctx->in, 14); | ||
301 | |||
302 | /* Append length in bits and transform */ | ||
303 | ctx->in[14] = ctx->bytes[0] << 3; | ||
304 | ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; | ||
305 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
306 | |||
307 | byteSwap(ctx->buf, 4); | ||
308 | memcpy(digest, ctx->buf, 16); | ||
309 | memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ | ||
310 | if(0 != ctx->internal_buf) { | ||
311 | free(ctx->internal_buf); | ||
312 | ctx->internal_buf = 0; | ||
313 | ctx->capacity = 0; | ||
314 | } | ||
315 | } | ||
diff --git a/apps/codecs/libFLAC/memory.c b/apps/codecs/libFLAC/memory.c new file mode 100644 index 0000000000..9718b261b8 --- /dev/null +++ b/apps/codecs/libFLAC/memory.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include "private/memory.h" | ||
33 | #include "FLAC/assert.h" | ||
34 | |||
35 | #ifdef HAVE_CONFIG_H | ||
36 | #include <config.h> | ||
37 | #endif | ||
38 | |||
39 | void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) | ||
40 | { | ||
41 | void *x; | ||
42 | |||
43 | FLAC__ASSERT(0 != aligned_address); | ||
44 | |||
45 | #ifdef FLAC__ALIGN_MALLOC_DATA | ||
46 | /* align on 32-byte (256-bit) boundary */ | ||
47 | x = malloc(bytes+31); | ||
48 | *aligned_address = (void*)(((unsigned)x + 31) & -32); | ||
49 | #else | ||
50 | x = malloc(bytes); | ||
51 | *aligned_address = x; | ||
52 | #endif | ||
53 | return x; | ||
54 | } | ||
55 | |||
56 | FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) | ||
57 | { | ||
58 | FLAC__int32 *pu; /* unaligned pointer */ | ||
59 | union { /* union needed to comply with C99 pointer aliasing rules */ | ||
60 | FLAC__int32 *pa; /* aligned pointer */ | ||
61 | void *pv; /* aligned pointer alias */ | ||
62 | } u; | ||
63 | |||
64 | FLAC__ASSERT(elements > 0); | ||
65 | FLAC__ASSERT(0 != unaligned_pointer); | ||
66 | FLAC__ASSERT(0 != aligned_pointer); | ||
67 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||
68 | |||
69 | pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv); | ||
70 | if(0 == pu) { | ||
71 | return false; | ||
72 | } | ||
73 | else { | ||
74 | if(*unaligned_pointer != 0) | ||
75 | free(*unaligned_pointer); | ||
76 | *unaligned_pointer = pu; | ||
77 | *aligned_pointer = u.pa; | ||
78 | return true; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | ||
83 | { | ||
84 | FLAC__uint32 *pu; /* unaligned pointer */ | ||
85 | union { /* union needed to comply with C99 pointer aliasing rules */ | ||
86 | FLAC__uint32 *pa; /* aligned pointer */ | ||
87 | void *pv; /* aligned pointer alias */ | ||
88 | } u; | ||
89 | |||
90 | FLAC__ASSERT(elements > 0); | ||
91 | FLAC__ASSERT(0 != unaligned_pointer); | ||
92 | FLAC__ASSERT(0 != aligned_pointer); | ||
93 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||
94 | |||
95 | pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv); | ||
96 | if(0 == pu) { | ||
97 | return false; | ||
98 | } | ||
99 | else { | ||
100 | if(*unaligned_pointer != 0) | ||
101 | free(*unaligned_pointer); | ||
102 | *unaligned_pointer = pu; | ||
103 | *aligned_pointer = u.pa; | ||
104 | return true; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | ||
109 | { | ||
110 | FLAC__uint64 *pu; /* unaligned pointer */ | ||
111 | union { /* union needed to comply with C99 pointer aliasing rules */ | ||
112 | FLAC__uint64 *pa; /* aligned pointer */ | ||
113 | void *pv; /* aligned pointer alias */ | ||
114 | } u; | ||
115 | |||
116 | FLAC__ASSERT(elements > 0); | ||
117 | FLAC__ASSERT(0 != unaligned_pointer); | ||
118 | FLAC__ASSERT(0 != aligned_pointer); | ||
119 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||
120 | |||
121 | pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv); | ||
122 | if(0 == pu) { | ||
123 | return false; | ||
124 | } | ||
125 | else { | ||
126 | if(*unaligned_pointer != 0) | ||
127 | free(*unaligned_pointer); | ||
128 | *unaligned_pointer = pu; | ||
129 | *aligned_pointer = u.pa; | ||
130 | return true; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) | ||
135 | { | ||
136 | unsigned *pu; /* unaligned pointer */ | ||
137 | union { /* union needed to comply with C99 pointer aliasing rules */ | ||
138 | unsigned *pa; /* aligned pointer */ | ||
139 | void *pv; /* aligned pointer alias */ | ||
140 | } u; | ||
141 | |||
142 | FLAC__ASSERT(elements > 0); | ||
143 | FLAC__ASSERT(0 != unaligned_pointer); | ||
144 | FLAC__ASSERT(0 != aligned_pointer); | ||
145 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||
146 | |||
147 | pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv); | ||
148 | if(0 == pu) { | ||
149 | return false; | ||
150 | } | ||
151 | else { | ||
152 | if(*unaligned_pointer != 0) | ||
153 | free(*unaligned_pointer); | ||
154 | *unaligned_pointer = pu; | ||
155 | *aligned_pointer = u.pa; | ||
156 | return true; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
161 | |||
162 | FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) | ||
163 | { | ||
164 | FLAC__real *pu; /* unaligned pointer */ | ||
165 | union { /* union needed to comply with C99 pointer aliasing rules */ | ||
166 | FLAC__real *pa; /* aligned pointer */ | ||
167 | void *pv; /* aligned pointer alias */ | ||
168 | } u; | ||
169 | |||
170 | FLAC__ASSERT(elements > 0); | ||
171 | FLAC__ASSERT(0 != unaligned_pointer); | ||
172 | FLAC__ASSERT(0 != aligned_pointer); | ||
173 | FLAC__ASSERT(unaligned_pointer != aligned_pointer); | ||
174 | |||
175 | pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv); | ||
176 | if(0 == pu) { | ||
177 | return false; | ||
178 | } | ||
179 | else { | ||
180 | if(*unaligned_pointer != 0) | ||
181 | free(*unaligned_pointer); | ||
182 | *unaligned_pointer = pu; | ||
183 | *aligned_pointer = u.pa; | ||
184 | return true; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | #endif | ||
diff --git a/apps/codecs/libFLAC/metadata_iterators.c b/apps/codecs/libFLAC/metadata_iterators.c new file mode 100644 index 0000000000..2d50dd2bdb --- /dev/null +++ b/apps/codecs/libFLAC/metadata_iterators.c | |||
@@ -0,0 +1,2964 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <errno.h> | ||
33 | #include <stdio.h> | ||
34 | #include <stdlib.h> | ||
35 | #include <string.h> | ||
36 | |||
37 | #if defined _MSC_VER || defined __MINGW32__ | ||
38 | #include <sys/utime.h> /* for utime() */ | ||
39 | #include <io.h> /* for chmod() */ | ||
40 | #else | ||
41 | #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ | ||
42 | #include <utime.h> /* for utime() */ | ||
43 | #include <unistd.h> /* for chown(), unlink() */ | ||
44 | #endif | ||
45 | #include <sys/stat.h> /* for stat(), maybe chmod() */ | ||
46 | |||
47 | #include "private/metadata.h" | ||
48 | |||
49 | #include "FLAC/assert.h" | ||
50 | #include "FLAC/file_decoder.h" | ||
51 | |||
52 | #ifdef max | ||
53 | #undef max | ||
54 | #endif | ||
55 | #define max(a,b) ((a)>(b)?(a):(b)) | ||
56 | #ifdef min | ||
57 | #undef min | ||
58 | #endif | ||
59 | #define min(a,b) ((a)<(b)?(a):(b)) | ||
60 | |||
61 | |||
62 | /**************************************************************************** | ||
63 | * | ||
64 | * Local function declarations | ||
65 | * | ||
66 | ***************************************************************************/ | ||
67 | |||
68 | static void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes); | ||
69 | static void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes); | ||
70 | static void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes); | ||
71 | static FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes); | ||
72 | static FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes); | ||
73 | static FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes); | ||
74 | |||
75 | static FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator); | ||
76 | static FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block); | ||
77 | static FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length); | ||
78 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block); | ||
79 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block); | ||
80 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length); | ||
81 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length); | ||
82 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length); | ||
83 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry); | ||
84 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block); | ||
85 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track); | ||
86 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block); | ||
87 | static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length); | ||
88 | |||
89 | static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); | ||
90 | static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); | ||
91 | static FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); | ||
92 | static FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block); | ||
93 | static FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block); | ||
94 | static FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length); | ||
95 | static FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length); | ||
96 | static FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block); | ||
97 | static FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block); | ||
98 | static FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block); | ||
99 | static FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length); | ||
100 | |||
101 | static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block); | ||
102 | static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last); | ||
103 | static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append); | ||
104 | |||
105 | static void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator); | ||
106 | static FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator); | ||
107 | |||
108 | static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb); | ||
109 | static unsigned seek_to_first_metadata_block_(FILE *f); | ||
110 | |||
111 | static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append); | ||
112 | static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup); | ||
113 | |||
114 | static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status); | ||
115 | static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status); | ||
116 | static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status); | ||
117 | static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status); | ||
118 | |||
119 | static FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); | ||
120 | static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status); | ||
121 | static void cleanup_tempfile_(FILE **tempfile, char **tempfilename); | ||
122 | |||
123 | static FLAC__bool get_file_stats_(const char *filename, struct stat *stats); | ||
124 | static void set_file_stats_(const char *filename, struct stat *stats); | ||
125 | |||
126 | static int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence); | ||
127 | static FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle); | ||
128 | |||
129 | static FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status); | ||
130 | |||
131 | |||
132 | #ifdef FLAC__VALGRIND_TESTING | ||
133 | static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) | ||
134 | { | ||
135 | size_t ret = fwrite(ptr, size, nmemb, stream); | ||
136 | if(!ferror(stream)) | ||
137 | fflush(stream); | ||
138 | return ret; | ||
139 | } | ||
140 | #else | ||
141 | #define local__fwrite fwrite | ||
142 | #endif | ||
143 | |||
144 | /**************************************************************************** | ||
145 | * | ||
146 | * Level 0 implementation | ||
147 | * | ||
148 | ***************************************************************************/ | ||
149 | |||
150 | static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
151 | static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
152 | static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
153 | |||
154 | typedef struct { | ||
155 | FLAC__bool got_error; | ||
156 | FLAC__bool got_object; | ||
157 | FLAC__StreamMetadata *object; | ||
158 | } level0_client_data; | ||
159 | |||
160 | FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo) | ||
161 | { | ||
162 | level0_client_data cd; | ||
163 | FLAC__FileDecoder *decoder; | ||
164 | |||
165 | FLAC__ASSERT(0 != filename); | ||
166 | FLAC__ASSERT(0 != streaminfo); | ||
167 | |||
168 | decoder = FLAC__file_decoder_new(); | ||
169 | |||
170 | if(0 == decoder) | ||
171 | return false; | ||
172 | |||
173 | cd.got_error = false; | ||
174 | cd.got_object = false; | ||
175 | cd.object = 0; | ||
176 | |||
177 | FLAC__file_decoder_set_md5_checking(decoder, false); | ||
178 | FLAC__file_decoder_set_filename(decoder, filename); | ||
179 | FLAC__file_decoder_set_metadata_ignore_all(decoder); | ||
180 | FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); | ||
181 | FLAC__file_decoder_set_write_callback(decoder, write_callback_); | ||
182 | FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); | ||
183 | FLAC__file_decoder_set_error_callback(decoder, error_callback_); | ||
184 | FLAC__file_decoder_set_client_data(decoder, &cd); | ||
185 | |||
186 | if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) { | ||
187 | FLAC__file_decoder_finish(decoder); | ||
188 | FLAC__file_decoder_delete(decoder); | ||
189 | return false; | ||
190 | } | ||
191 | |||
192 | if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) { | ||
193 | FLAC__file_decoder_finish(decoder); | ||
194 | FLAC__file_decoder_delete(decoder); | ||
195 | if(0 != cd.object) | ||
196 | FLAC__metadata_object_delete(cd.object); | ||
197 | return false; | ||
198 | } | ||
199 | |||
200 | FLAC__file_decoder_finish(decoder); | ||
201 | FLAC__file_decoder_delete(decoder); | ||
202 | |||
203 | if(cd.got_object) { | ||
204 | /* can just copy the contents since STREAMINFO has no internal structure */ | ||
205 | *streaminfo = *(cd.object); | ||
206 | } | ||
207 | |||
208 | if(0 != cd.object) | ||
209 | FLAC__metadata_object_delete(cd.object); | ||
210 | |||
211 | return cd.got_object; | ||
212 | } | ||
213 | |||
214 | FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags) | ||
215 | { | ||
216 | level0_client_data cd; | ||
217 | FLAC__FileDecoder *decoder; | ||
218 | |||
219 | FLAC__ASSERT(0 != filename); | ||
220 | FLAC__ASSERT(0 != tags); | ||
221 | |||
222 | decoder = FLAC__file_decoder_new(); | ||
223 | |||
224 | if(0 == decoder) | ||
225 | return false; | ||
226 | |||
227 | *tags = 0; | ||
228 | |||
229 | cd.got_error = false; | ||
230 | cd.got_object = false; | ||
231 | cd.object = 0; | ||
232 | |||
233 | FLAC__file_decoder_set_md5_checking(decoder, false); | ||
234 | FLAC__file_decoder_set_filename(decoder, filename); | ||
235 | FLAC__file_decoder_set_metadata_ignore_all(decoder); | ||
236 | FLAC__file_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
237 | FLAC__file_decoder_set_write_callback(decoder, write_callback_); | ||
238 | FLAC__file_decoder_set_metadata_callback(decoder, metadata_callback_); | ||
239 | FLAC__file_decoder_set_error_callback(decoder, error_callback_); | ||
240 | FLAC__file_decoder_set_client_data(decoder, &cd); | ||
241 | |||
242 | if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK || cd.got_error) { | ||
243 | FLAC__file_decoder_finish(decoder); | ||
244 | FLAC__file_decoder_delete(decoder); | ||
245 | return false; | ||
246 | } | ||
247 | |||
248 | if(!FLAC__file_decoder_process_until_end_of_metadata(decoder) || cd.got_error) { | ||
249 | FLAC__file_decoder_finish(decoder); | ||
250 | FLAC__file_decoder_delete(decoder); | ||
251 | if(0 != cd.object) | ||
252 | FLAC__metadata_object_delete(cd.object); | ||
253 | return false; | ||
254 | } | ||
255 | |||
256 | FLAC__file_decoder_finish(decoder); | ||
257 | FLAC__file_decoder_delete(decoder); | ||
258 | |||
259 | if(cd.got_object) | ||
260 | *tags = cd.object; | ||
261 | |||
262 | return cd.got_object; | ||
263 | } | ||
264 | |||
265 | FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) | ||
266 | { | ||
267 | (void)decoder, (void)frame, (void)buffer, (void)client_data; | ||
268 | |||
269 | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | ||
270 | } | ||
271 | |||
272 | void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) | ||
273 | { | ||
274 | level0_client_data *cd = (level0_client_data *)client_data; | ||
275 | (void)decoder; | ||
276 | |||
277 | /* | ||
278 | * we assume we only get here when the one metadata block we were | ||
279 | * looking for was passed to us | ||
280 | */ | ||
281 | if(!cd->got_object) { | ||
282 | if(0 == (cd->object = FLAC__metadata_object_clone(metadata))) | ||
283 | cd->got_error = true; | ||
284 | else | ||
285 | cd->got_object = true; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) | ||
290 | { | ||
291 | level0_client_data *cd = (level0_client_data *)client_data; | ||
292 | (void)decoder; | ||
293 | |||
294 | if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) | ||
295 | cd->got_error = true; | ||
296 | } | ||
297 | |||
298 | |||
299 | /**************************************************************************** | ||
300 | * | ||
301 | * Level 1 implementation | ||
302 | * | ||
303 | ***************************************************************************/ | ||
304 | |||
305 | #define SIMPLE_ITERATOR_MAX_PUSH_DEPTH (1+4) | ||
306 | /* 1 for initial offset, +4 for our own personal use */ | ||
307 | |||
308 | struct FLAC__Metadata_SimpleIterator { | ||
309 | FILE *file; | ||
310 | char *filename, *tempfile_path_prefix; | ||
311 | struct stat stats; | ||
312 | FLAC__bool has_stats; | ||
313 | FLAC__bool is_writable; | ||
314 | FLAC__Metadata_SimpleIteratorStatus status; | ||
315 | /*@@@ 2G limits here because of the offset type: */ | ||
316 | long offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH]; | ||
317 | long first_offset; /* this is the offset to the STREAMINFO block */ | ||
318 | unsigned depth; | ||
319 | /* this is the metadata block header of the current block we are pointing to: */ | ||
320 | FLAC__bool is_last; | ||
321 | FLAC__MetadataType type; | ||
322 | unsigned length; | ||
323 | }; | ||
324 | |||
325 | FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = { | ||
326 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK", | ||
327 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT", | ||
328 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE", | ||
329 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE", | ||
330 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE", | ||
331 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA", | ||
332 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR", | ||
333 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR", | ||
334 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR", | ||
335 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR", | ||
336 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR", | ||
337 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR", | ||
338 | "FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR" | ||
339 | }; | ||
340 | |||
341 | |||
342 | FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new() | ||
343 | { | ||
344 | FLAC__Metadata_SimpleIterator *iterator = (FLAC__Metadata_SimpleIterator*)calloc(1, sizeof(FLAC__Metadata_SimpleIterator)); | ||
345 | |||
346 | if(0 != iterator) { | ||
347 | iterator->file = 0; | ||
348 | iterator->filename = 0; | ||
349 | iterator->tempfile_path_prefix = 0; | ||
350 | iterator->has_stats = false; | ||
351 | iterator->is_writable = false; | ||
352 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
353 | iterator->first_offset = iterator->offset[0] = -1; | ||
354 | iterator->depth = 0; | ||
355 | } | ||
356 | |||
357 | return iterator; | ||
358 | } | ||
359 | |||
360 | static void simple_iterator_free_guts_(FLAC__Metadata_SimpleIterator *iterator) | ||
361 | { | ||
362 | FLAC__ASSERT(0 != iterator); | ||
363 | |||
364 | if(0 != iterator->file) { | ||
365 | fclose(iterator->file); | ||
366 | iterator->file = 0; | ||
367 | if(iterator->has_stats) | ||
368 | set_file_stats_(iterator->filename, &iterator->stats); | ||
369 | } | ||
370 | if(0 != iterator->filename) { | ||
371 | free(iterator->filename); | ||
372 | iterator->filename = 0; | ||
373 | } | ||
374 | if(0 != iterator->tempfile_path_prefix) { | ||
375 | free(iterator->tempfile_path_prefix); | ||
376 | iterator->tempfile_path_prefix = 0; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator) | ||
381 | { | ||
382 | FLAC__ASSERT(0 != iterator); | ||
383 | |||
384 | simple_iterator_free_guts_(iterator); | ||
385 | free(iterator); | ||
386 | } | ||
387 | |||
388 | FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator) | ||
389 | { | ||
390 | FLAC__Metadata_SimpleIteratorStatus status; | ||
391 | |||
392 | FLAC__ASSERT(0 != iterator); | ||
393 | |||
394 | status = iterator->status; | ||
395 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
396 | return status; | ||
397 | } | ||
398 | |||
399 | static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool read_only) | ||
400 | { | ||
401 | unsigned ret; | ||
402 | |||
403 | FLAC__ASSERT(0 != iterator); | ||
404 | |||
405 | if(read_only || 0 == (iterator->file = fopen(iterator->filename, "r+b"))) { | ||
406 | iterator->is_writable = false; | ||
407 | if(read_only || errno == EACCES) { | ||
408 | if(0 == (iterator->file = fopen(iterator->filename, "rb"))) { | ||
409 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; | ||
410 | return false; | ||
411 | } | ||
412 | } | ||
413 | else { | ||
414 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; | ||
415 | return false; | ||
416 | } | ||
417 | } | ||
418 | else { | ||
419 | iterator->is_writable = true; | ||
420 | } | ||
421 | |||
422 | ret = seek_to_first_metadata_block_(iterator->file); | ||
423 | switch(ret) { | ||
424 | case 0: | ||
425 | iterator->depth = 0; | ||
426 | iterator->first_offset = iterator->offset[iterator->depth] = ftell(iterator->file); | ||
427 | return read_metadata_block_header_(iterator); | ||
428 | case 1: | ||
429 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
430 | return false; | ||
431 | case 2: | ||
432 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
433 | return false; | ||
434 | case 3: | ||
435 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE; | ||
436 | return false; | ||
437 | default: | ||
438 | FLAC__ASSERT(0); | ||
439 | return false; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | #if 0 | ||
444 | @@@ If we decide to finish implementing this, put this comment back in metadata.h | ||
445 | /* | ||
446 | * The 'tempfile_path_prefix' allows you to specify a directory where | ||
447 | * tempfiles should go. Remember that if your metadata edits cause the | ||
448 | * FLAC file to grow, the entire file will have to be rewritten. If | ||
449 | * 'tempfile_path_prefix' is NULL, the temp file will be written in the | ||
450 | * same directory as the original FLAC file. This makes replacing the | ||
451 | * original with the tempfile fast but requires extra space in the same | ||
452 | * partition for the tempfile. If space is a problem, you can pass a | ||
453 | * directory name belonging to a different partition in | ||
454 | * 'tempfile_path_prefix'. Note that you should use the forward slash | ||
455 | * '/' as the directory separator. A trailing slash is not needed; it | ||
456 | * will be added automatically. | ||
457 | */ | ||
458 | FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool preserve_file_stats, const char *tempfile_path_prefix); | ||
459 | #endif | ||
460 | |||
461 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats) | ||
462 | { | ||
463 | const char *tempfile_path_prefix = 0; /*@@@ search for comments near 'rename(...)' for what it will take to finish implementing this */ | ||
464 | |||
465 | FLAC__ASSERT(0 != iterator); | ||
466 | FLAC__ASSERT(0 != filename); | ||
467 | |||
468 | simple_iterator_free_guts_(iterator); | ||
469 | |||
470 | if(!read_only && preserve_file_stats) | ||
471 | iterator->has_stats = get_file_stats_(filename, &iterator->stats); | ||
472 | |||
473 | if(0 == (iterator->filename = strdup(filename))) { | ||
474 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
475 | return false; | ||
476 | } | ||
477 | if(0 != tempfile_path_prefix && 0 == (iterator->tempfile_path_prefix = strdup(tempfile_path_prefix))) { | ||
478 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
479 | return false; | ||
480 | } | ||
481 | |||
482 | return simple_iterator_prime_input_(iterator, read_only); | ||
483 | } | ||
484 | |||
485 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator) | ||
486 | { | ||
487 | FLAC__ASSERT(0 != iterator); | ||
488 | FLAC__ASSERT(0 != iterator->file); | ||
489 | |||
490 | return iterator->is_writable; | ||
491 | } | ||
492 | |||
493 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator) | ||
494 | { | ||
495 | FLAC__ASSERT(0 != iterator); | ||
496 | FLAC__ASSERT(0 != iterator->file); | ||
497 | |||
498 | if(iterator->is_last) | ||
499 | return false; | ||
500 | |||
501 | if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) { | ||
502 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
503 | return false; | ||
504 | } | ||
505 | |||
506 | iterator->offset[iterator->depth] = ftell(iterator->file); | ||
507 | |||
508 | return read_metadata_block_header_(iterator); | ||
509 | } | ||
510 | |||
511 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator) | ||
512 | { | ||
513 | long this_offset; | ||
514 | |||
515 | FLAC__ASSERT(0 != iterator); | ||
516 | FLAC__ASSERT(0 != iterator->file); | ||
517 | |||
518 | if(iterator->offset[iterator->depth] == iterator->first_offset) | ||
519 | return false; | ||
520 | |||
521 | if(0 != fseek(iterator->file, iterator->first_offset, SEEK_SET)) { | ||
522 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
523 | return false; | ||
524 | } | ||
525 | this_offset = iterator->first_offset; | ||
526 | if(!read_metadata_block_header_(iterator)) | ||
527 | return false; | ||
528 | |||
529 | /* we ignore any error from ftell() and catch it in fseek() */ | ||
530 | while(ftell(iterator->file) + (long)iterator->length < iterator->offset[iterator->depth]) { | ||
531 | if(0 != fseek(iterator->file, iterator->length, SEEK_CUR)) { | ||
532 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
533 | return false; | ||
534 | } | ||
535 | this_offset = ftell(iterator->file); | ||
536 | if(!read_metadata_block_header_(iterator)) | ||
537 | return false; | ||
538 | } | ||
539 | |||
540 | iterator->offset[iterator->depth] = this_offset; | ||
541 | |||
542 | return true; | ||
543 | } | ||
544 | |||
545 | FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator) | ||
546 | { | ||
547 | FLAC__ASSERT(0 != iterator); | ||
548 | FLAC__ASSERT(0 != iterator->file); | ||
549 | |||
550 | return iterator->type; | ||
551 | } | ||
552 | |||
553 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator) | ||
554 | { | ||
555 | FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type); | ||
556 | |||
557 | FLAC__ASSERT(0 != iterator); | ||
558 | FLAC__ASSERT(0 != iterator->file); | ||
559 | |||
560 | if(0 != block) { | ||
561 | block->is_last = iterator->is_last; | ||
562 | block->length = iterator->length; | ||
563 | |||
564 | if(!read_metadata_block_data_(iterator, block)) { | ||
565 | FLAC__metadata_object_delete(block); | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | /* back up to the beginning of the block data to stay consistent */ | ||
570 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH, SEEK_SET)) { | ||
571 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
572 | FLAC__metadata_object_delete(block); | ||
573 | return 0; | ||
574 | } | ||
575 | } | ||
576 | else | ||
577 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
578 | |||
579 | return block; | ||
580 | } | ||
581 | |||
582 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding) | ||
583 | { | ||
584 | FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];) | ||
585 | FLAC__bool ret; | ||
586 | |||
587 | FLAC__ASSERT(0 != iterator); | ||
588 | FLAC__ASSERT(0 != iterator->file); | ||
589 | FLAC__ASSERT(0 != block); | ||
590 | |||
591 | if(!iterator->is_writable) { | ||
592 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE; | ||
593 | return false; | ||
594 | } | ||
595 | |||
596 | if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO || block->type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
597 | if(iterator->type != block->type) { | ||
598 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; | ||
599 | return false; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | block->is_last = iterator->is_last; | ||
604 | |||
605 | if(iterator->length == block->length) | ||
606 | return write_metadata_block_stationary_(iterator, block); | ||
607 | else if(iterator->length > block->length) { | ||
608 | if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) { | ||
609 | ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last); | ||
610 | FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); | ||
611 | FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
612 | return ret; | ||
613 | } | ||
614 | else { | ||
615 | ret = rewrite_whole_file_(iterator, block, /*append=*/false); | ||
616 | FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); | ||
617 | FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
618 | return ret; | ||
619 | } | ||
620 | } | ||
621 | else /* iterator->length < block->length */ { | ||
622 | unsigned padding_leftover = 0; | ||
623 | FLAC__bool padding_is_last = false; | ||
624 | if(use_padding) { | ||
625 | /* first see if we can even use padding */ | ||
626 | if(iterator->is_last) { | ||
627 | use_padding = false; | ||
628 | } | ||
629 | else { | ||
630 | const unsigned extra_padding_bytes_required = block->length - iterator->length; | ||
631 | simple_iterator_push_(iterator); | ||
632 | if(!FLAC__metadata_simple_iterator_next(iterator)) { | ||
633 | (void)simple_iterator_pop_(iterator); | ||
634 | return false; | ||
635 | } | ||
636 | if(iterator->type != FLAC__METADATA_TYPE_PADDING) { | ||
637 | use_padding = false; | ||
638 | } | ||
639 | else { | ||
640 | if(FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length == extra_padding_bytes_required) { | ||
641 | padding_leftover = 0; | ||
642 | block->is_last = iterator->is_last; | ||
643 | } | ||
644 | else if(iterator->length < extra_padding_bytes_required) | ||
645 | use_padding = false; | ||
646 | else { | ||
647 | padding_leftover = FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length - extra_padding_bytes_required; | ||
648 | padding_is_last = iterator->is_last; | ||
649 | block->is_last = false; | ||
650 | } | ||
651 | } | ||
652 | if(!simple_iterator_pop_(iterator)) | ||
653 | return false; | ||
654 | } | ||
655 | } | ||
656 | if(use_padding) { | ||
657 | if(padding_leftover == 0) { | ||
658 | ret = write_metadata_block_stationary_(iterator, block); | ||
659 | FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); | ||
660 | FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
661 | return ret; | ||
662 | } | ||
663 | else { | ||
664 | FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
665 | ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); | ||
666 | FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); | ||
667 | FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
668 | return ret; | ||
669 | } | ||
670 | } | ||
671 | else { | ||
672 | ret = rewrite_whole_file_(iterator, block, /*append=*/false); | ||
673 | FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); | ||
674 | FLAC__ASSERT(!ret || ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
675 | return ret; | ||
676 | } | ||
677 | } | ||
678 | } | ||
679 | |||
680 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding) | ||
681 | { | ||
682 | unsigned padding_leftover = 0; | ||
683 | FLAC__bool padding_is_last = false; | ||
684 | |||
685 | FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;) | ||
686 | FLAC__bool ret; | ||
687 | |||
688 | FLAC__ASSERT(0 != iterator); | ||
689 | FLAC__ASSERT(0 != iterator->file); | ||
690 | FLAC__ASSERT(0 != block); | ||
691 | |||
692 | if(!iterator->is_writable) | ||
693 | return false; | ||
694 | |||
695 | if(block->type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
696 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; | ||
697 | return false; | ||
698 | } | ||
699 | |||
700 | block->is_last = iterator->is_last; | ||
701 | |||
702 | if(use_padding) { | ||
703 | /* first see if we can even use padding */ | ||
704 | if(iterator->is_last) { | ||
705 | use_padding = false; | ||
706 | } | ||
707 | else { | ||
708 | simple_iterator_push_(iterator); | ||
709 | if(!FLAC__metadata_simple_iterator_next(iterator)) { | ||
710 | (void)simple_iterator_pop_(iterator); | ||
711 | return false; | ||
712 | } | ||
713 | if(iterator->type != FLAC__METADATA_TYPE_PADDING) { | ||
714 | use_padding = false; | ||
715 | } | ||
716 | else { | ||
717 | if(iterator->length == block->length) { | ||
718 | padding_leftover = 0; | ||
719 | block->is_last = iterator->is_last; | ||
720 | } | ||
721 | else if(iterator->length < FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) | ||
722 | use_padding = false; | ||
723 | else { | ||
724 | padding_leftover = iterator->length - block->length; | ||
725 | padding_is_last = iterator->is_last; | ||
726 | block->is_last = false; | ||
727 | } | ||
728 | } | ||
729 | if(!simple_iterator_pop_(iterator)) | ||
730 | return false; | ||
731 | } | ||
732 | } | ||
733 | if(use_padding) { | ||
734 | /* move to the next block, which is suitable padding */ | ||
735 | if(!FLAC__metadata_simple_iterator_next(iterator)) | ||
736 | return false; | ||
737 | if(padding_leftover == 0) { | ||
738 | ret = write_metadata_block_stationary_(iterator, block); | ||
739 | FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); | ||
740 | FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
741 | return ret; | ||
742 | } | ||
743 | else { | ||
744 | FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
745 | ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); | ||
746 | FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); | ||
747 | FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
748 | return ret; | ||
749 | } | ||
750 | } | ||
751 | else { | ||
752 | ret = rewrite_whole_file_(iterator, block, /*append=*/true); | ||
753 | FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); | ||
754 | FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + (long)FLAC__STREAM_METADATA_HEADER_LENGTH); | ||
755 | return ret; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding) | ||
760 | { | ||
761 | FLAC__ASSERT_DECLARATION(long debug_target_offset = iterator->offset[iterator->depth];) | ||
762 | FLAC__bool ret; | ||
763 | |||
764 | if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
765 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; | ||
766 | return false; | ||
767 | } | ||
768 | |||
769 | if(use_padding) { | ||
770 | FLAC__StreamMetadata *padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING); | ||
771 | if(0 == padding) { | ||
772 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
773 | return false; | ||
774 | } | ||
775 | padding->length = iterator->length; | ||
776 | if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false)) { | ||
777 | FLAC__metadata_object_delete(padding); | ||
778 | return false; | ||
779 | } | ||
780 | FLAC__metadata_object_delete(padding); | ||
781 | if(!FLAC__metadata_simple_iterator_prev(iterator)) | ||
782 | return false; | ||
783 | FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset); | ||
784 | FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset); | ||
785 | return true; | ||
786 | } | ||
787 | else { | ||
788 | ret = rewrite_whole_file_(iterator, 0, /*append=*/false); | ||
789 | FLAC__ASSERT(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length == debug_target_offset); | ||
790 | FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset); | ||
791 | return ret; | ||
792 | } | ||
793 | } | ||
794 | |||
795 | |||
796 | |||
797 | /**************************************************************************** | ||
798 | * | ||
799 | * Level 2 implementation | ||
800 | * | ||
801 | ***************************************************************************/ | ||
802 | |||
803 | |||
804 | typedef struct FLAC__Metadata_Node { | ||
805 | FLAC__StreamMetadata *data; | ||
806 | struct FLAC__Metadata_Node *prev, *next; | ||
807 | } FLAC__Metadata_Node; | ||
808 | |||
809 | struct FLAC__Metadata_Chain { | ||
810 | char *filename; /* will be NULL if using callbacks */ | ||
811 | FLAC__Metadata_Node *head; | ||
812 | FLAC__Metadata_Node *tail; | ||
813 | unsigned nodes; | ||
814 | FLAC__Metadata_ChainStatus status; | ||
815 | long first_offset, last_offset; /*@@@ 2G limit */ | ||
816 | /* | ||
817 | * This is the length of the chain initially read from the FLAC file. | ||
818 | * it is used to compare against the current length to decide whether | ||
819 | * or not the whole file has to be rewritten. | ||
820 | */ | ||
821 | unsigned initial_length; /*@@@ 4G limit */ | ||
822 | }; | ||
823 | |||
824 | struct FLAC__Metadata_Iterator { | ||
825 | FLAC__Metadata_Chain *chain; | ||
826 | FLAC__Metadata_Node *current; | ||
827 | }; | ||
828 | |||
829 | FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = { | ||
830 | "FLAC__METADATA_CHAIN_STATUS_OK", | ||
831 | "FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT", | ||
832 | "FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE", | ||
833 | "FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE", | ||
834 | "FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE", | ||
835 | "FLAC__METADATA_CHAIN_STATUS_BAD_METADATA", | ||
836 | "FLAC__METADATA_CHAIN_STATUS_READ_ERROR", | ||
837 | "FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR", | ||
838 | "FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR", | ||
839 | "FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR", | ||
840 | "FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR", | ||
841 | "FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR", | ||
842 | "FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR", | ||
843 | "FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS", | ||
844 | "FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", | ||
845 | "FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL" | ||
846 | }; | ||
847 | |||
848 | |||
849 | static FLAC__Metadata_Node *node_new_() | ||
850 | { | ||
851 | return (FLAC__Metadata_Node*)calloc(1, sizeof(FLAC__Metadata_Node)); | ||
852 | } | ||
853 | |||
854 | static void node_delete_(FLAC__Metadata_Node *node) | ||
855 | { | ||
856 | FLAC__ASSERT(0 != node); | ||
857 | if(0 != node->data) | ||
858 | FLAC__metadata_object_delete(node->data); | ||
859 | free(node); | ||
860 | } | ||
861 | |||
862 | static void chain_init_(FLAC__Metadata_Chain *chain) | ||
863 | { | ||
864 | FLAC__ASSERT(0 != chain); | ||
865 | |||
866 | chain->filename = 0; | ||
867 | chain->head = chain->tail = 0; | ||
868 | chain->nodes = 0; | ||
869 | chain->status = FLAC__METADATA_CHAIN_STATUS_OK; | ||
870 | chain->initial_length = 0; | ||
871 | } | ||
872 | |||
873 | static void chain_clear_(FLAC__Metadata_Chain *chain) | ||
874 | { | ||
875 | FLAC__Metadata_Node *node, *next; | ||
876 | |||
877 | FLAC__ASSERT(0 != chain); | ||
878 | |||
879 | for(node = chain->head; node; ) { | ||
880 | next = node->next; | ||
881 | node_delete_(node); | ||
882 | node = next; | ||
883 | } | ||
884 | |||
885 | if(0 != chain->filename) | ||
886 | free(chain->filename); | ||
887 | |||
888 | chain_init_(chain); | ||
889 | } | ||
890 | |||
891 | static void chain_append_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) | ||
892 | { | ||
893 | FLAC__ASSERT(0 != chain); | ||
894 | FLAC__ASSERT(0 != node); | ||
895 | FLAC__ASSERT(0 != node->data); | ||
896 | |||
897 | node->next = node->prev = 0; | ||
898 | node->data->is_last = true; | ||
899 | if(0 != chain->tail) | ||
900 | chain->tail->data->is_last = false; | ||
901 | |||
902 | if(0 == chain->head) | ||
903 | chain->head = node; | ||
904 | else { | ||
905 | FLAC__ASSERT(0 != chain->tail); | ||
906 | chain->tail->next = node; | ||
907 | node->prev = chain->tail; | ||
908 | } | ||
909 | chain->tail = node; | ||
910 | chain->nodes++; | ||
911 | } | ||
912 | |||
913 | static void chain_remove_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) | ||
914 | { | ||
915 | FLAC__ASSERT(0 != chain); | ||
916 | FLAC__ASSERT(0 != node); | ||
917 | |||
918 | if(node == chain->head) | ||
919 | chain->head = node->next; | ||
920 | else | ||
921 | node->prev->next = node->next; | ||
922 | |||
923 | if(node == chain->tail) | ||
924 | chain->tail = node->prev; | ||
925 | else | ||
926 | node->next->prev = node->prev; | ||
927 | |||
928 | if(0 != chain->tail) | ||
929 | chain->tail->data->is_last = true; | ||
930 | |||
931 | chain->nodes--; | ||
932 | } | ||
933 | |||
934 | static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) | ||
935 | { | ||
936 | chain_remove_node_(chain, node); | ||
937 | node_delete_(node); | ||
938 | } | ||
939 | |||
940 | static unsigned chain_calculate_length_(FLAC__Metadata_Chain *chain) | ||
941 | { | ||
942 | const FLAC__Metadata_Node *node; | ||
943 | unsigned length = 0; | ||
944 | for(node = chain->head; node; node = node->next) | ||
945 | length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); | ||
946 | return length; | ||
947 | } | ||
948 | |||
949 | static void iterator_insert_node_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node) | ||
950 | { | ||
951 | FLAC__ASSERT(0 != node); | ||
952 | FLAC__ASSERT(0 != node->data); | ||
953 | FLAC__ASSERT(0 != iterator); | ||
954 | FLAC__ASSERT(0 != iterator->current); | ||
955 | FLAC__ASSERT(0 != iterator->chain); | ||
956 | FLAC__ASSERT(0 != iterator->chain->head); | ||
957 | FLAC__ASSERT(0 != iterator->chain->tail); | ||
958 | |||
959 | node->data->is_last = false; | ||
960 | |||
961 | node->prev = iterator->current->prev; | ||
962 | node->next = iterator->current; | ||
963 | |||
964 | if(0 == node->prev) | ||
965 | iterator->chain->head = node; | ||
966 | else | ||
967 | node->prev->next = node; | ||
968 | |||
969 | iterator->current->prev = node; | ||
970 | |||
971 | iterator->chain->nodes++; | ||
972 | } | ||
973 | |||
974 | static void iterator_insert_node_after_(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Node *node) | ||
975 | { | ||
976 | FLAC__ASSERT(0 != node); | ||
977 | FLAC__ASSERT(0 != node->data); | ||
978 | FLAC__ASSERT(0 != iterator); | ||
979 | FLAC__ASSERT(0 != iterator->current); | ||
980 | FLAC__ASSERT(0 != iterator->chain); | ||
981 | FLAC__ASSERT(0 != iterator->chain->head); | ||
982 | FLAC__ASSERT(0 != iterator->chain->tail); | ||
983 | |||
984 | iterator->current->data->is_last = false; | ||
985 | |||
986 | node->prev = iterator->current; | ||
987 | node->next = iterator->current->next; | ||
988 | |||
989 | if(0 == node->next) | ||
990 | iterator->chain->tail = node; | ||
991 | else | ||
992 | node->next->prev = node; | ||
993 | |||
994 | node->prev->next = node; | ||
995 | |||
996 | iterator->chain->tail->data->is_last = true; | ||
997 | |||
998 | iterator->chain->nodes++; | ||
999 | } | ||
1000 | |||
1001 | /* return true iff node and node->next are both padding */ | ||
1002 | static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node *node) | ||
1003 | { | ||
1004 | if(node->data->type == FLAC__METADATA_TYPE_PADDING && 0 != node->next && node->next->data->type == FLAC__METADATA_TYPE_PADDING) { | ||
1005 | const unsigned growth = FLAC__STREAM_METADATA_HEADER_LENGTH + node->next->data->length; | ||
1006 | node->data->length += growth; | ||
1007 | |||
1008 | chain_delete_node_(chain, node->next); | ||
1009 | return true; | ||
1010 | } | ||
1011 | else | ||
1012 | return false; | ||
1013 | } | ||
1014 | |||
1015 | /* Returns the new length of the chain, or 0 if there was an error. */ | ||
1016 | /* WATCHOUT: This can get called multiple times before a write, so | ||
1017 | * it should still work when this happens. | ||
1018 | */ | ||
1019 | /* WATCHOUT: Make sure to also update the logic in | ||
1020 | * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes. | ||
1021 | */ | ||
1022 | static unsigned chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) | ||
1023 | { | ||
1024 | unsigned current_length = chain_calculate_length_(chain); | ||
1025 | |||
1026 | if(use_padding) { | ||
1027 | /* if the metadata shrank and the last block is padding, we just extend the last padding block */ | ||
1028 | if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { | ||
1029 | const unsigned delta = chain->initial_length - current_length; | ||
1030 | chain->tail->data->length += delta; | ||
1031 | current_length += delta; | ||
1032 | FLAC__ASSERT(current_length == chain->initial_length); | ||
1033 | } | ||
1034 | /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ | ||
1035 | else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) { | ||
1036 | FLAC__StreamMetadata *padding; | ||
1037 | FLAC__Metadata_Node *node; | ||
1038 | if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) { | ||
1039 | chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1040 | return 0; | ||
1041 | } | ||
1042 | padding->length = chain->initial_length - (FLAC__STREAM_METADATA_HEADER_LENGTH + current_length); | ||
1043 | if(0 == (node = node_new_())) { | ||
1044 | FLAC__metadata_object_delete(padding); | ||
1045 | chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1046 | return 0; | ||
1047 | } | ||
1048 | node->data = padding; | ||
1049 | chain_append_node_(chain, node); | ||
1050 | current_length = chain_calculate_length_(chain); | ||
1051 | FLAC__ASSERT(current_length == chain->initial_length); | ||
1052 | } | ||
1053 | /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ | ||
1054 | else if(current_length > chain->initial_length) { | ||
1055 | const unsigned delta = current_length - chain->initial_length; | ||
1056 | if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { | ||
1057 | /* if the delta is exactly the size of the last padding block, remove the padding block */ | ||
1058 | if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta) { | ||
1059 | chain_delete_node_(chain, chain->tail); | ||
1060 | current_length = chain_calculate_length_(chain); | ||
1061 | FLAC__ASSERT(current_length == chain->initial_length); | ||
1062 | } | ||
1063 | /* if there is at least 'delta' bytes of padding, trim the padding down */ | ||
1064 | else if(chain->tail->data->length >= delta) { | ||
1065 | chain->tail->data->length -= delta; | ||
1066 | current_length -= delta; | ||
1067 | FLAC__ASSERT(current_length == chain->initial_length); | ||
1068 | } | ||
1069 | } | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | return current_length; | ||
1074 | } | ||
1075 | |||
1076 | static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Tell tell_cb) | ||
1077 | { | ||
1078 | FLAC__Metadata_Node *node; | ||
1079 | |||
1080 | FLAC__ASSERT(0 != chain); | ||
1081 | |||
1082 | /* we assume we're already at the beginning of the file */ | ||
1083 | |||
1084 | switch(seek_to_first_metadata_block_cb_(handle, read_cb, seek_cb)) { | ||
1085 | case 0: | ||
1086 | break; | ||
1087 | case 1: | ||
1088 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; | ||
1089 | return false; | ||
1090 | case 2: | ||
1091 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1092 | return false; | ||
1093 | case 3: | ||
1094 | chain->status = FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE; | ||
1095 | return false; | ||
1096 | default: | ||
1097 | FLAC__ASSERT(0); | ||
1098 | return false; | ||
1099 | } | ||
1100 | |||
1101 | { | ||
1102 | FLAC__int64 pos = tell_cb(handle); | ||
1103 | if(pos < 0) { | ||
1104 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; | ||
1105 | return false; | ||
1106 | } | ||
1107 | chain->first_offset = (long)pos; | ||
1108 | } | ||
1109 | |||
1110 | { | ||
1111 | FLAC__bool is_last; | ||
1112 | FLAC__MetadataType type; | ||
1113 | unsigned length; | ||
1114 | |||
1115 | do { | ||
1116 | node = node_new_(); | ||
1117 | if(0 == node) { | ||
1118 | chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1119 | return false; | ||
1120 | } | ||
1121 | |||
1122 | if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) { | ||
1123 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; | ||
1124 | return false; | ||
1125 | } | ||
1126 | |||
1127 | node->data = FLAC__metadata_object_new(type); | ||
1128 | if(0 == node->data) { | ||
1129 | node_delete_(node); | ||
1130 | chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1131 | return false; | ||
1132 | } | ||
1133 | |||
1134 | node->data->is_last = is_last; | ||
1135 | node->data->length = length; | ||
1136 | |||
1137 | chain->status = get_equivalent_status_(read_metadata_block_data_cb_(handle, read_cb, seek_cb, node->data)); | ||
1138 | if(chain->status != FLAC__METADATA_CHAIN_STATUS_OK) { | ||
1139 | node_delete_(node); | ||
1140 | return false; | ||
1141 | } | ||
1142 | chain_append_node_(chain, node); | ||
1143 | } while(!is_last); | ||
1144 | } | ||
1145 | |||
1146 | { | ||
1147 | FLAC__int64 pos = tell_cb(handle); | ||
1148 | if(pos < 0) { | ||
1149 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; | ||
1150 | return false; | ||
1151 | } | ||
1152 | chain->last_offset = (long)pos; | ||
1153 | } | ||
1154 | |||
1155 | chain->initial_length = chain_calculate_length_(chain); | ||
1156 | |||
1157 | return true; | ||
1158 | } | ||
1159 | |||
1160 | static FLAC__bool chain_rewrite_metadata_in_place_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, FLAC__IOCallback_Seek seek_cb) | ||
1161 | { | ||
1162 | FLAC__Metadata_Node *node; | ||
1163 | |||
1164 | FLAC__ASSERT(0 != chain); | ||
1165 | FLAC__ASSERT(0 != chain->head); | ||
1166 | |||
1167 | if(0 != seek_cb(handle, chain->first_offset, SEEK_SET)) { | ||
1168 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1169 | return false; | ||
1170 | } | ||
1171 | |||
1172 | for(node = chain->head; node; node = node->next) { | ||
1173 | if(!write_metadata_block_header_cb_(handle, write_cb, node->data)) { | ||
1174 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; | ||
1175 | return false; | ||
1176 | } | ||
1177 | if(!write_metadata_block_data_cb_(handle, write_cb, node->data)) { | ||
1178 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; | ||
1179 | return false; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/ | ||
1184 | |||
1185 | chain->status = FLAC__METADATA_CHAIN_STATUS_OK; | ||
1186 | return true; | ||
1187 | } | ||
1188 | |||
1189 | static FLAC__bool chain_rewrite_metadata_in_place_(FLAC__Metadata_Chain *chain) | ||
1190 | { | ||
1191 | FILE *file; | ||
1192 | FLAC__bool ret; | ||
1193 | |||
1194 | FLAC__ASSERT(0 != chain->filename); | ||
1195 | |||
1196 | if(0 == (file = fopen(chain->filename, "r+b"))) { | ||
1197 | chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; | ||
1198 | return false; | ||
1199 | } | ||
1200 | |||
1201 | /* chain_rewrite_metadata_in_place_cb_() sets chain->status for us */ | ||
1202 | ret = chain_rewrite_metadata_in_place_cb_(chain, (FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, fseek_wrapper_); | ||
1203 | |||
1204 | fclose(file); | ||
1205 | |||
1206 | return ret; | ||
1207 | } | ||
1208 | |||
1209 | static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *tempfile_path_prefix) | ||
1210 | { | ||
1211 | FILE *f, *tempfile; | ||
1212 | char *tempfilename; | ||
1213 | FLAC__Metadata_SimpleIteratorStatus status; | ||
1214 | const FLAC__Metadata_Node *node; | ||
1215 | |||
1216 | FLAC__ASSERT(0 != chain); | ||
1217 | FLAC__ASSERT(0 != chain->filename); | ||
1218 | FLAC__ASSERT(0 != chain->head); | ||
1219 | |||
1220 | /* copy the file prefix (data up to first metadata block */ | ||
1221 | if(0 == (f = fopen(chain->filename, "rb"))) { | ||
1222 | chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; | ||
1223 | return false; | ||
1224 | } | ||
1225 | if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) { | ||
1226 | chain->status = get_equivalent_status_(status); | ||
1227 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
1228 | return false; | ||
1229 | } | ||
1230 | if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) { | ||
1231 | chain->status = get_equivalent_status_(status); | ||
1232 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
1233 | return false; | ||
1234 | } | ||
1235 | |||
1236 | /* write the metadata */ | ||
1237 | for(node = chain->head; node; node = node->next) { | ||
1238 | if(!write_metadata_block_header_(tempfile, &status, node->data)) { | ||
1239 | chain->status = get_equivalent_status_(status); | ||
1240 | return false; | ||
1241 | } | ||
1242 | if(!write_metadata_block_data_(tempfile, &status, node->data)) { | ||
1243 | chain->status = get_equivalent_status_(status); | ||
1244 | return false; | ||
1245 | } | ||
1246 | } | ||
1247 | /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/ | ||
1248 | |||
1249 | /* copy the file postfix (everything after the metadata) */ | ||
1250 | if(0 != fseek(f, chain->last_offset, SEEK_SET)) { | ||
1251 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
1252 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1253 | return false; | ||
1254 | } | ||
1255 | if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) { | ||
1256 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
1257 | chain->status = get_equivalent_status_(status); | ||
1258 | return false; | ||
1259 | } | ||
1260 | |||
1261 | /* move the tempfile on top of the original */ | ||
1262 | (void)fclose(f); | ||
1263 | if(!transport_tempfile_(chain->filename, &tempfile, &tempfilename, &status)) | ||
1264 | return false; | ||
1265 | |||
1266 | return true; | ||
1267 | } | ||
1268 | |||
1269 | /* assumes 'handle' is already at beginning of file */ | ||
1270 | static FLAC__bool chain_rewrite_file_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb) | ||
1271 | { | ||
1272 | FLAC__Metadata_SimpleIteratorStatus status; | ||
1273 | const FLAC__Metadata_Node *node; | ||
1274 | |||
1275 | FLAC__ASSERT(0 != chain); | ||
1276 | FLAC__ASSERT(0 == chain->filename); | ||
1277 | FLAC__ASSERT(0 != chain->head); | ||
1278 | |||
1279 | /* copy the file prefix (data up to first metadata block */ | ||
1280 | if(!copy_n_bytes_from_file_cb_(handle, read_cb, temp_handle, temp_write_cb, chain->first_offset, &status)) { | ||
1281 | chain->status = get_equivalent_status_(status); | ||
1282 | return false; | ||
1283 | } | ||
1284 | |||
1285 | /* write the metadata */ | ||
1286 | for(node = chain->head; node; node = node->next) { | ||
1287 | if(!write_metadata_block_header_cb_(temp_handle, temp_write_cb, node->data)) { | ||
1288 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; | ||
1289 | return false; | ||
1290 | } | ||
1291 | if(!write_metadata_block_data_cb_(temp_handle, temp_write_cb, node->data)) { | ||
1292 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; | ||
1293 | return false; | ||
1294 | } | ||
1295 | } | ||
1296 | /*FLAC__ASSERT(fflush(), ftell() == chain->last_offset);*/ | ||
1297 | |||
1298 | /* copy the file postfix (everything after the metadata) */ | ||
1299 | if(0 != seek_cb(handle, chain->last_offset, SEEK_SET)) { | ||
1300 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1301 | return false; | ||
1302 | } | ||
1303 | if(!copy_remaining_bytes_from_file_cb_(handle, read_cb, eof_cb, temp_handle, temp_write_cb, &status)) { | ||
1304 | chain->status = get_equivalent_status_(status); | ||
1305 | return false; | ||
1306 | } | ||
1307 | |||
1308 | return true; | ||
1309 | } | ||
1310 | |||
1311 | FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new() | ||
1312 | { | ||
1313 | FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)calloc(1, sizeof(FLAC__Metadata_Chain)); | ||
1314 | |||
1315 | if(0 != chain) | ||
1316 | chain_init_(chain); | ||
1317 | |||
1318 | return chain; | ||
1319 | } | ||
1320 | |||
1321 | FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain) | ||
1322 | { | ||
1323 | FLAC__ASSERT(0 != chain); | ||
1324 | |||
1325 | chain_clear_(chain); | ||
1326 | |||
1327 | free(chain); | ||
1328 | } | ||
1329 | |||
1330 | FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain) | ||
1331 | { | ||
1332 | FLAC__Metadata_ChainStatus status; | ||
1333 | |||
1334 | FLAC__ASSERT(0 != chain); | ||
1335 | |||
1336 | status = chain->status; | ||
1337 | chain->status = FLAC__METADATA_CHAIN_STATUS_OK; | ||
1338 | return status; | ||
1339 | } | ||
1340 | |||
1341 | FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename) | ||
1342 | { | ||
1343 | FILE *file; | ||
1344 | FLAC__bool ret; | ||
1345 | |||
1346 | FLAC__ASSERT(0 != chain); | ||
1347 | FLAC__ASSERT(0 != filename); | ||
1348 | |||
1349 | chain_clear_(chain); | ||
1350 | |||
1351 | if(0 == (chain->filename = strdup(filename))) { | ||
1352 | chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1353 | return false; | ||
1354 | } | ||
1355 | |||
1356 | if(0 == (file = fopen(filename, "rb"))) { | ||
1357 | chain->status = FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; | ||
1358 | return false; | ||
1359 | } | ||
1360 | |||
1361 | /* chain_read_cb_() sets chain->status for us */ | ||
1362 | ret = chain_read_cb_(chain, file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, ftell_wrapper_); | ||
1363 | |||
1364 | fclose(file); | ||
1365 | |||
1366 | return ret; | ||
1367 | } | ||
1368 | |||
1369 | FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) | ||
1370 | { | ||
1371 | FLAC__ASSERT(0 != chain); | ||
1372 | |||
1373 | chain_clear_(chain); | ||
1374 | |||
1375 | if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.tell) { | ||
1376 | chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; | ||
1377 | return false; | ||
1378 | } | ||
1379 | |||
1380 | /* rewind */ | ||
1381 | if(0 != callbacks.seek(handle, 0, SEEK_SET)) { | ||
1382 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1383 | return false; | ||
1384 | } | ||
1385 | |||
1386 | if(!chain_read_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.tell)) | ||
1387 | return false; /* chain->status is already set by chain_read_cb_ */ | ||
1388 | |||
1389 | return true; | ||
1390 | } | ||
1391 | |||
1392 | FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) | ||
1393 | { | ||
1394 | /* This does all the same checks that are in chain_prepare_for_write_() | ||
1395 | * but doesn't actually alter the chain. Make sure to update the logic | ||
1396 | * here if chain_prepare_for_write_() changes. | ||
1397 | */ | ||
1398 | const unsigned current_length = chain_calculate_length_(chain); | ||
1399 | |||
1400 | FLAC__ASSERT(0 != chain); | ||
1401 | |||
1402 | if(use_padding) { | ||
1403 | /* if the metadata shrank and the last block is padding, we just extend the last padding block */ | ||
1404 | if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) | ||
1405 | return false; | ||
1406 | /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ | ||
1407 | else if(current_length + FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) | ||
1408 | return false; | ||
1409 | /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ | ||
1410 | else if(current_length > chain->initial_length) { | ||
1411 | const unsigned delta = current_length - chain->initial_length; | ||
1412 | if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { | ||
1413 | /* if the delta is exactly the size of the last padding block, remove the padding block */ | ||
1414 | if(chain->tail->data->length + FLAC__STREAM_METADATA_HEADER_LENGTH == delta) | ||
1415 | return false; | ||
1416 | /* if there is at least 'delta' bytes of padding, trim the padding down */ | ||
1417 | else if(chain->tail->data->length >= delta) | ||
1418 | return false; | ||
1419 | } | ||
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | return (current_length != chain->initial_length); | ||
1424 | } | ||
1425 | |||
1426 | FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats) | ||
1427 | { | ||
1428 | struct stat stats; | ||
1429 | const char *tempfile_path_prefix = 0; | ||
1430 | unsigned current_length; | ||
1431 | |||
1432 | FLAC__ASSERT(0 != chain); | ||
1433 | |||
1434 | if (0 == chain->filename) { | ||
1435 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; | ||
1436 | return false; | ||
1437 | } | ||
1438 | |||
1439 | current_length = chain_prepare_for_write_(chain, use_padding); | ||
1440 | |||
1441 | /* a return value of 0 means there was an error; chain->status is already set */ | ||
1442 | if (0 == current_length) | ||
1443 | return false; | ||
1444 | |||
1445 | if(preserve_file_stats) | ||
1446 | get_file_stats_(chain->filename, &stats); | ||
1447 | |||
1448 | if(current_length == chain->initial_length) { | ||
1449 | if(!chain_rewrite_metadata_in_place_(chain)) | ||
1450 | return false; | ||
1451 | } | ||
1452 | else { | ||
1453 | if(!chain_rewrite_file_(chain, tempfile_path_prefix)) | ||
1454 | return false; | ||
1455 | |||
1456 | /* recompute lengths and offsets */ | ||
1457 | { | ||
1458 | const FLAC__Metadata_Node *node; | ||
1459 | chain->initial_length = current_length; | ||
1460 | chain->last_offset = chain->first_offset; | ||
1461 | for(node = chain->head; node; node = node->next) | ||
1462 | chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); | ||
1463 | } | ||
1464 | } | ||
1465 | |||
1466 | if(preserve_file_stats) | ||
1467 | set_file_stats_(chain->filename, &stats); | ||
1468 | |||
1469 | return true; | ||
1470 | } | ||
1471 | |||
1472 | FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) | ||
1473 | { | ||
1474 | unsigned current_length; | ||
1475 | |||
1476 | FLAC__ASSERT(0 != chain); | ||
1477 | |||
1478 | if (0 != chain->filename) { | ||
1479 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; | ||
1480 | return false; | ||
1481 | } | ||
1482 | |||
1483 | if (0 == callbacks.write || 0 == callbacks.seek) { | ||
1484 | chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; | ||
1485 | return false; | ||
1486 | } | ||
1487 | |||
1488 | if (FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) { | ||
1489 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL; | ||
1490 | return false; | ||
1491 | } | ||
1492 | |||
1493 | current_length = chain_prepare_for_write_(chain, use_padding); | ||
1494 | |||
1495 | /* a return value of 0 means there was an error; chain->status is already set */ | ||
1496 | if (0 == current_length) | ||
1497 | return false; | ||
1498 | |||
1499 | FLAC__ASSERT(current_length == chain->initial_length); | ||
1500 | |||
1501 | return chain_rewrite_metadata_in_place_cb_(chain, handle, callbacks.write, callbacks.seek); | ||
1502 | } | ||
1503 | |||
1504 | FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks) | ||
1505 | { | ||
1506 | unsigned current_length; | ||
1507 | |||
1508 | FLAC__ASSERT(0 != chain); | ||
1509 | |||
1510 | if (0 != chain->filename) { | ||
1511 | chain->status = FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH; | ||
1512 | return false; | ||
1513 | } | ||
1514 | |||
1515 | if (0 == callbacks.read || 0 == callbacks.seek || 0 == callbacks.eof) { | ||
1516 | chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; | ||
1517 | return false; | ||
1518 | } | ||
1519 | if (0 == temp_callbacks.write) { | ||
1520 | chain->status = FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS; | ||
1521 | return false; | ||
1522 | } | ||
1523 | |||
1524 | if (!FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) { | ||
1525 | chain->status = FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL; | ||
1526 | return false; | ||
1527 | } | ||
1528 | |||
1529 | current_length = chain_prepare_for_write_(chain, use_padding); | ||
1530 | |||
1531 | /* a return value of 0 means there was an error; chain->status is already set */ | ||
1532 | if (0 == current_length) | ||
1533 | return false; | ||
1534 | |||
1535 | FLAC__ASSERT(current_length != chain->initial_length); | ||
1536 | |||
1537 | /* rewind */ | ||
1538 | if(0 != callbacks.seek(handle, 0, SEEK_SET)) { | ||
1539 | chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
1540 | return false; | ||
1541 | } | ||
1542 | |||
1543 | if(!chain_rewrite_file_cb_(chain, handle, callbacks.read, callbacks.seek, callbacks.eof, temp_handle, temp_callbacks.write)) | ||
1544 | return false; | ||
1545 | |||
1546 | /* recompute lengths and offsets */ | ||
1547 | { | ||
1548 | const FLAC__Metadata_Node *node; | ||
1549 | chain->initial_length = current_length; | ||
1550 | chain->last_offset = chain->first_offset; | ||
1551 | for(node = chain->head; node; node = node->next) | ||
1552 | chain->last_offset += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); | ||
1553 | } | ||
1554 | |||
1555 | return true; | ||
1556 | } | ||
1557 | |||
1558 | FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain) | ||
1559 | { | ||
1560 | FLAC__Metadata_Node *node; | ||
1561 | |||
1562 | FLAC__ASSERT(0 != chain); | ||
1563 | |||
1564 | for(node = chain->head; node; ) { | ||
1565 | if(!chain_merge_adjacent_padding_(chain, node)) | ||
1566 | node = node->next; | ||
1567 | } | ||
1568 | } | ||
1569 | |||
1570 | FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain) | ||
1571 | { | ||
1572 | FLAC__Metadata_Node *node, *save; | ||
1573 | unsigned i; | ||
1574 | |||
1575 | FLAC__ASSERT(0 != chain); | ||
1576 | |||
1577 | /* | ||
1578 | * Don't try and be too smart... this simple algo is good enough for | ||
1579 | * the small number of nodes that we deal with. | ||
1580 | */ | ||
1581 | for(i = 0, node = chain->head; i < chain->nodes; i++) { | ||
1582 | if(node->data->type == FLAC__METADATA_TYPE_PADDING) { | ||
1583 | save = node->next; | ||
1584 | chain_remove_node_(chain, node); | ||
1585 | chain_append_node_(chain, node); | ||
1586 | node = save; | ||
1587 | } | ||
1588 | else { | ||
1589 | node = node->next; | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | FLAC__metadata_chain_merge_padding(chain); | ||
1594 | } | ||
1595 | |||
1596 | |||
1597 | FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new() | ||
1598 | { | ||
1599 | FLAC__Metadata_Iterator *iterator = (FLAC__Metadata_Iterator*)calloc(1, sizeof(FLAC__Metadata_Iterator)); | ||
1600 | |||
1601 | /* calloc() implies: | ||
1602 | iterator->current = 0; | ||
1603 | iterator->chain = 0; | ||
1604 | */ | ||
1605 | |||
1606 | return iterator; | ||
1607 | } | ||
1608 | |||
1609 | FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator) | ||
1610 | { | ||
1611 | FLAC__ASSERT(0 != iterator); | ||
1612 | |||
1613 | free(iterator); | ||
1614 | } | ||
1615 | |||
1616 | FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain) | ||
1617 | { | ||
1618 | FLAC__ASSERT(0 != iterator); | ||
1619 | FLAC__ASSERT(0 != chain); | ||
1620 | FLAC__ASSERT(0 != chain->head); | ||
1621 | |||
1622 | iterator->chain = chain; | ||
1623 | iterator->current = chain->head; | ||
1624 | } | ||
1625 | |||
1626 | FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator) | ||
1627 | { | ||
1628 | FLAC__ASSERT(0 != iterator); | ||
1629 | |||
1630 | if(0 == iterator->current || 0 == iterator->current->next) | ||
1631 | return false; | ||
1632 | |||
1633 | iterator->current = iterator->current->next; | ||
1634 | return true; | ||
1635 | } | ||
1636 | |||
1637 | FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator) | ||
1638 | { | ||
1639 | FLAC__ASSERT(0 != iterator); | ||
1640 | |||
1641 | if(0 == iterator->current || 0 == iterator->current->prev) | ||
1642 | return false; | ||
1643 | |||
1644 | iterator->current = iterator->current->prev; | ||
1645 | return true; | ||
1646 | } | ||
1647 | |||
1648 | FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator) | ||
1649 | { | ||
1650 | FLAC__ASSERT(0 != iterator); | ||
1651 | FLAC__ASSERT(0 != iterator->current); | ||
1652 | FLAC__ASSERT(0 != iterator->current->data); | ||
1653 | |||
1654 | return iterator->current->data->type; | ||
1655 | } | ||
1656 | |||
1657 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator) | ||
1658 | { | ||
1659 | FLAC__ASSERT(0 != iterator); | ||
1660 | FLAC__ASSERT(0 != iterator->current); | ||
1661 | |||
1662 | return iterator->current->data; | ||
1663 | } | ||
1664 | |||
1665 | FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) | ||
1666 | { | ||
1667 | FLAC__ASSERT(0 != iterator); | ||
1668 | FLAC__ASSERT(0 != block); | ||
1669 | return FLAC__metadata_iterator_delete_block(iterator, false) && FLAC__metadata_iterator_insert_block_after(iterator, block); | ||
1670 | } | ||
1671 | |||
1672 | FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding) | ||
1673 | { | ||
1674 | FLAC__Metadata_Node *save; | ||
1675 | |||
1676 | FLAC__ASSERT(0 != iterator); | ||
1677 | FLAC__ASSERT(0 != iterator->current); | ||
1678 | |||
1679 | if(0 == iterator->current->prev) { | ||
1680 | FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO); | ||
1681 | return false; | ||
1682 | } | ||
1683 | |||
1684 | save = iterator->current->prev; | ||
1685 | |||
1686 | if(replace_with_padding) { | ||
1687 | FLAC__metadata_object_delete_data(iterator->current->data); | ||
1688 | iterator->current->data->type = FLAC__METADATA_TYPE_PADDING; | ||
1689 | } | ||
1690 | else { | ||
1691 | chain_delete_node_(iterator->chain, iterator->current); | ||
1692 | } | ||
1693 | |||
1694 | iterator->current = save; | ||
1695 | return true; | ||
1696 | } | ||
1697 | |||
1698 | FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) | ||
1699 | { | ||
1700 | FLAC__Metadata_Node *node; | ||
1701 | |||
1702 | FLAC__ASSERT(0 != iterator); | ||
1703 | FLAC__ASSERT(0 != iterator->current); | ||
1704 | FLAC__ASSERT(0 != block); | ||
1705 | |||
1706 | if(block->type == FLAC__METADATA_TYPE_STREAMINFO) | ||
1707 | return false; | ||
1708 | |||
1709 | if(0 == iterator->current->prev) { | ||
1710 | FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO); | ||
1711 | return false; | ||
1712 | } | ||
1713 | |||
1714 | if(0 == (node = node_new_())) | ||
1715 | return false; | ||
1716 | |||
1717 | node->data = block; | ||
1718 | iterator_insert_node_(iterator, node); | ||
1719 | iterator->current = node; | ||
1720 | return true; | ||
1721 | } | ||
1722 | |||
1723 | FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block) | ||
1724 | { | ||
1725 | FLAC__Metadata_Node *node; | ||
1726 | |||
1727 | FLAC__ASSERT(0 != iterator); | ||
1728 | FLAC__ASSERT(0 != iterator->current); | ||
1729 | FLAC__ASSERT(0 != block); | ||
1730 | |||
1731 | if(block->type == FLAC__METADATA_TYPE_STREAMINFO) | ||
1732 | return false; | ||
1733 | |||
1734 | if(0 == (node = node_new_())) | ||
1735 | return false; | ||
1736 | |||
1737 | node->data = block; | ||
1738 | iterator_insert_node_after_(iterator, node); | ||
1739 | iterator->current = node; | ||
1740 | return true; | ||
1741 | } | ||
1742 | |||
1743 | |||
1744 | /**************************************************************************** | ||
1745 | * | ||
1746 | * Local function definitions | ||
1747 | * | ||
1748 | ***************************************************************************/ | ||
1749 | |||
1750 | void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes) | ||
1751 | { | ||
1752 | unsigned i; | ||
1753 | |||
1754 | b += bytes; | ||
1755 | |||
1756 | for(i = 0; i < bytes; i++) { | ||
1757 | *(--b) = (FLAC__byte)(val & 0xff); | ||
1758 | val >>= 8; | ||
1759 | } | ||
1760 | } | ||
1761 | |||
1762 | void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes) | ||
1763 | { | ||
1764 | unsigned i; | ||
1765 | |||
1766 | for(i = 0; i < bytes; i++) { | ||
1767 | *(b++) = (FLAC__byte)(val & 0xff); | ||
1768 | val >>= 8; | ||
1769 | } | ||
1770 | } | ||
1771 | |||
1772 | void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes) | ||
1773 | { | ||
1774 | unsigned i; | ||
1775 | |||
1776 | b += bytes; | ||
1777 | |||
1778 | for(i = 0; i < bytes; i++) { | ||
1779 | *(--b) = (FLAC__byte)(val & 0xff); | ||
1780 | val >>= 8; | ||
1781 | } | ||
1782 | } | ||
1783 | |||
1784 | FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes) | ||
1785 | { | ||
1786 | FLAC__uint32 ret = 0; | ||
1787 | unsigned i; | ||
1788 | |||
1789 | for(i = 0; i < bytes; i++) | ||
1790 | ret = (ret << 8) | (FLAC__uint32)(*b++); | ||
1791 | |||
1792 | return ret; | ||
1793 | } | ||
1794 | |||
1795 | FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes) | ||
1796 | { | ||
1797 | FLAC__uint32 ret = 0; | ||
1798 | unsigned i; | ||
1799 | |||
1800 | b += bytes; | ||
1801 | |||
1802 | for(i = 0; i < bytes; i++) | ||
1803 | ret = (ret << 8) | (FLAC__uint32)(*--b); | ||
1804 | |||
1805 | return ret; | ||
1806 | } | ||
1807 | |||
1808 | FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes) | ||
1809 | { | ||
1810 | FLAC__uint64 ret = 0; | ||
1811 | unsigned i; | ||
1812 | |||
1813 | for(i = 0; i < bytes; i++) | ||
1814 | ret = (ret << 8) | (FLAC__uint64)(*b++); | ||
1815 | |||
1816 | return ret; | ||
1817 | } | ||
1818 | |||
1819 | FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator) | ||
1820 | { | ||
1821 | FLAC__ASSERT(0 != iterator); | ||
1822 | FLAC__ASSERT(0 != iterator->file); | ||
1823 | |||
1824 | if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) { | ||
1825 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1826 | return false; | ||
1827 | } | ||
1828 | |||
1829 | return true; | ||
1830 | } | ||
1831 | |||
1832 | FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block) | ||
1833 | { | ||
1834 | FLAC__ASSERT(0 != iterator); | ||
1835 | FLAC__ASSERT(0 != iterator->file); | ||
1836 | |||
1837 | iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block); | ||
1838 | |||
1839 | return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK); | ||
1840 | } | ||
1841 | |||
1842 | FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length) | ||
1843 | { | ||
1844 | FLAC__byte raw_header[FLAC__STREAM_METADATA_HEADER_LENGTH]; | ||
1845 | |||
1846 | if(read_cb(raw_header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH) | ||
1847 | return false; | ||
1848 | |||
1849 | *is_last = raw_header[0] & 0x80? true : false; | ||
1850 | *type = (FLAC__MetadataType)(raw_header[0] & 0x7f); | ||
1851 | *length = unpack_uint32_(raw_header + 1, 3); | ||
1852 | |||
1853 | /* Note that we don't check: | ||
1854 | * if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED) | ||
1855 | * we just will read in an opaque block | ||
1856 | */ | ||
1857 | |||
1858 | return true; | ||
1859 | } | ||
1860 | |||
1861 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block) | ||
1862 | { | ||
1863 | switch(block->type) { | ||
1864 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
1865 | return read_metadata_block_data_streaminfo_cb_(handle, read_cb, &block->data.stream_info); | ||
1866 | case FLAC__METADATA_TYPE_PADDING: | ||
1867 | return read_metadata_block_data_padding_cb_(handle, seek_cb, &block->data.padding, block->length); | ||
1868 | case FLAC__METADATA_TYPE_APPLICATION: | ||
1869 | return read_metadata_block_data_application_cb_(handle, read_cb, &block->data.application, block->length); | ||
1870 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
1871 | return read_metadata_block_data_seektable_cb_(handle, read_cb, &block->data.seek_table, block->length); | ||
1872 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
1873 | return read_metadata_block_data_vorbis_comment_cb_(handle, read_cb, &block->data.vorbis_comment); | ||
1874 | case FLAC__METADATA_TYPE_CUESHEET: | ||
1875 | return read_metadata_block_data_cuesheet_cb_(handle, read_cb, &block->data.cue_sheet); | ||
1876 | default: | ||
1877 | return read_metadata_block_data_unknown_cb_(handle, read_cb, &block->data.unknown, block->length); | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block) | ||
1882 | { | ||
1883 | FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH], *b; | ||
1884 | |||
1885 | if(read_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) | ||
1886 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1887 | |||
1888 | b = buffer; | ||
1889 | |||
1890 | /* we are using hardcoded numbers for simplicity but we should | ||
1891 | * probably eventually write a bit-level unpacker and use the | ||
1892 | * _STREAMINFO_ constants. | ||
1893 | */ | ||
1894 | block->min_blocksize = unpack_uint32_(b, 2); b += 2; | ||
1895 | block->max_blocksize = unpack_uint32_(b, 2); b += 2; | ||
1896 | block->min_framesize = unpack_uint32_(b, 3); b += 3; | ||
1897 | block->max_framesize = unpack_uint32_(b, 3); b += 3; | ||
1898 | block->sample_rate = (unpack_uint32_(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4); | ||
1899 | block->channels = (unsigned)((b[2] & 0x0e) >> 1) + 1; | ||
1900 | block->bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 4) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1; | ||
1901 | block->total_samples = (((FLAC__uint64)(b[3] & 0x0f)) << 32) | unpack_uint64_(b+4, 4); | ||
1902 | memcpy(block->md5sum, b+8, 16); | ||
1903 | |||
1904 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
1905 | } | ||
1906 | |||
1907 | |||
1908 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length) | ||
1909 | { | ||
1910 | (void)block; /* nothing to do; we don't care about reading the padding bytes */ | ||
1911 | |||
1912 | if(0 != seek_cb(handle, block_length, SEEK_CUR)) | ||
1913 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
1914 | |||
1915 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
1916 | } | ||
1917 | |||
1918 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length) | ||
1919 | { | ||
1920 | const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; | ||
1921 | |||
1922 | if(read_cb(block->id, 1, id_bytes, handle) != id_bytes) | ||
1923 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1924 | |||
1925 | block_length -= id_bytes; | ||
1926 | |||
1927 | if(block_length == 0) { | ||
1928 | block->data = 0; | ||
1929 | } | ||
1930 | else { | ||
1931 | if(0 == (block->data = (FLAC__byte*)malloc(block_length))) | ||
1932 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1933 | |||
1934 | if(read_cb(block->data, 1, block_length, handle) != block_length) | ||
1935 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1936 | } | ||
1937 | |||
1938 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
1939 | } | ||
1940 | |||
1941 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length) | ||
1942 | { | ||
1943 | unsigned i; | ||
1944 | FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; | ||
1945 | |||
1946 | FLAC__ASSERT(block_length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH == 0); | ||
1947 | |||
1948 | block->num_points = block_length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; | ||
1949 | |||
1950 | if(block->num_points == 0) | ||
1951 | block->points = 0; | ||
1952 | else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) | ||
1953 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1954 | |||
1955 | for(i = 0; i < block->num_points; i++) { | ||
1956 | if(read_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) | ||
1957 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1958 | /* some MAGIC NUMBERs here */ | ||
1959 | block->points[i].sample_number = unpack_uint64_(buffer, 8); | ||
1960 | block->points[i].stream_offset = unpack_uint64_(buffer+8, 8); | ||
1961 | block->points[i].frame_samples = unpack_uint32_(buffer+16, 2); | ||
1962 | } | ||
1963 | |||
1964 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
1965 | } | ||
1966 | |||
1967 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry) | ||
1968 | { | ||
1969 | const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8; | ||
1970 | FLAC__byte buffer[4]; /* magic number is asserted below */ | ||
1971 | |||
1972 | FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8 == 4); | ||
1973 | |||
1974 | if(read_cb(buffer, 1, entry_length_len, handle) != entry_length_len) | ||
1975 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1976 | entry->length = unpack_uint32_little_endian_(buffer, entry_length_len); | ||
1977 | |||
1978 | if(0 != entry->entry) | ||
1979 | free(entry->entry); | ||
1980 | |||
1981 | if(entry->length == 0) { | ||
1982 | entry->entry = 0; | ||
1983 | } | ||
1984 | else { | ||
1985 | if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) | ||
1986 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
1987 | |||
1988 | if(read_cb(entry->entry, 1, entry->length, handle) != entry->length) | ||
1989 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
1990 | |||
1991 | entry->entry[entry->length] = '\0'; | ||
1992 | } | ||
1993 | |||
1994 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
1995 | } | ||
1996 | |||
1997 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block) | ||
1998 | { | ||
1999 | unsigned i; | ||
2000 | FLAC__Metadata_SimpleIteratorStatus status; | ||
2001 | const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; | ||
2002 | FLAC__byte buffer[4]; /* magic number is asserted below */ | ||
2003 | |||
2004 | FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8 == 4); | ||
2005 | |||
2006 | if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, &(block->vendor_string)))) | ||
2007 | return status; | ||
2008 | |||
2009 | if(read_cb(buffer, 1, num_comments_len, handle) != num_comments_len) | ||
2010 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2011 | block->num_comments = unpack_uint32_little_endian_(buffer, num_comments_len); | ||
2012 | |||
2013 | if(block->num_comments == 0) { | ||
2014 | block->comments = 0; | ||
2015 | } | ||
2016 | else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) | ||
2017 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2018 | |||
2019 | for(i = 0; i < block->num_comments; i++) { | ||
2020 | if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, block->comments + i))) | ||
2021 | return status; | ||
2022 | } | ||
2023 | |||
2024 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
2025 | } | ||
2026 | |||
2027 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track) | ||
2028 | { | ||
2029 | unsigned i, len; | ||
2030 | FLAC__byte buffer[32]; /* asserted below that this is big enough */ | ||
2031 | |||
2032 | FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64)); | ||
2033 | FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8); | ||
2034 | FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8); | ||
2035 | |||
2036 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0); | ||
2037 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8; | ||
2038 | if(read_cb(buffer, 1, len, handle) != len) | ||
2039 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2040 | track->offset = unpack_uint64_(buffer, len); | ||
2041 | |||
2042 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0); | ||
2043 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8; | ||
2044 | if(read_cb(buffer, 1, len, handle) != len) | ||
2045 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2046 | track->number = (FLAC__byte)unpack_uint32_(buffer, len); | ||
2047 | |||
2048 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | ||
2049 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8; | ||
2050 | if(read_cb(track->isrc, 1, len, handle) != len) | ||
2051 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2052 | |||
2053 | FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0); | ||
2054 | len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8; | ||
2055 | if(read_cb(buffer, 1, len, handle) != len) | ||
2056 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2057 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN == 1); | ||
2058 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN == 1); | ||
2059 | track->type = buffer[0] >> 7; | ||
2060 | track->pre_emphasis = (buffer[0] >> 6) & 1; | ||
2061 | |||
2062 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0); | ||
2063 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8; | ||
2064 | if(read_cb(buffer, 1, len, handle) != len) | ||
2065 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2066 | track->num_indices = (FLAC__byte)unpack_uint32_(buffer, len); | ||
2067 | |||
2068 | if(track->num_indices == 0) { | ||
2069 | track->indices = 0; | ||
2070 | } | ||
2071 | else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) | ||
2072 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2073 | |||
2074 | for(i = 0; i < track->num_indices; i++) { | ||
2075 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0); | ||
2076 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8; | ||
2077 | if(read_cb(buffer, 1, len, handle) != len) | ||
2078 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2079 | track->indices[i].offset = unpack_uint64_(buffer, len); | ||
2080 | |||
2081 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0); | ||
2082 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8; | ||
2083 | if(read_cb(buffer, 1, len, handle) != len) | ||
2084 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2085 | track->indices[i].number = (FLAC__byte)unpack_uint32_(buffer, len); | ||
2086 | |||
2087 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0); | ||
2088 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8; | ||
2089 | if(read_cb(buffer, 1, len, handle) != len) | ||
2090 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2091 | } | ||
2092 | |||
2093 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
2094 | } | ||
2095 | |||
2096 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet *block) | ||
2097 | { | ||
2098 | unsigned i, len; | ||
2099 | FLAC__Metadata_SimpleIteratorStatus status; | ||
2100 | FLAC__byte buffer[1024]; /* MSVC needs a constant expression so we put a magic number and assert */ | ||
2101 | |||
2102 | FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)/8 <= sizeof(buffer)); | ||
2103 | FLAC__ASSERT(sizeof(FLAC__uint64) <= sizeof(buffer)); | ||
2104 | |||
2105 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | ||
2106 | len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8; | ||
2107 | if(read_cb(block->media_catalog_number, 1, len, handle) != len) | ||
2108 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2109 | |||
2110 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0); | ||
2111 | len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8; | ||
2112 | if(read_cb(buffer, 1, len, handle) != len) | ||
2113 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2114 | block->lead_in = unpack_uint64_(buffer, len); | ||
2115 | |||
2116 | FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0); | ||
2117 | len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8; | ||
2118 | if(read_cb(buffer, 1, len, handle) != len) | ||
2119 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2120 | block->is_cd = buffer[0]&0x80? true : false; | ||
2121 | |||
2122 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0); | ||
2123 | len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8; | ||
2124 | if(read_cb(buffer, 1, len, handle) != len) | ||
2125 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2126 | block->num_tracks = unpack_uint32_(buffer, len); | ||
2127 | |||
2128 | if(block->num_tracks == 0) { | ||
2129 | block->tracks = 0; | ||
2130 | } | ||
2131 | else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) | ||
2132 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2133 | |||
2134 | for(i = 0; i < block->num_tracks; i++) { | ||
2135 | if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_cuesheet_track_cb_(handle, read_cb, block->tracks + i))) | ||
2136 | return status; | ||
2137 | } | ||
2138 | |||
2139 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
2140 | } | ||
2141 | |||
2142 | FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Unknown *block, unsigned block_length) | ||
2143 | { | ||
2144 | if(block_length == 0) { | ||
2145 | block->data = 0; | ||
2146 | } | ||
2147 | else { | ||
2148 | if(0 == (block->data = (FLAC__byte*)malloc(block_length))) | ||
2149 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2150 | |||
2151 | if(read_cb(block->data, 1, block_length, handle) != block_length) | ||
2152 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2153 | } | ||
2154 | |||
2155 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
2156 | } | ||
2157 | |||
2158 | FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) | ||
2159 | { | ||
2160 | FLAC__ASSERT(0 != file); | ||
2161 | FLAC__ASSERT(0 != status); | ||
2162 | |||
2163 | if(!write_metadata_block_header_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { | ||
2164 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2165 | return false; | ||
2166 | } | ||
2167 | |||
2168 | return true; | ||
2169 | } | ||
2170 | |||
2171 | FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) | ||
2172 | { | ||
2173 | FLAC__ASSERT(0 != file); | ||
2174 | FLAC__ASSERT(0 != status); | ||
2175 | |||
2176 | if (write_metadata_block_data_cb_((FLAC__IOHandle)file, (FLAC__IOCallback_Write)fwrite, block)) { | ||
2177 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; | ||
2178 | return true; | ||
2179 | } | ||
2180 | else { | ||
2181 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2182 | return false; | ||
2183 | } | ||
2184 | } | ||
2185 | |||
2186 | FLAC__bool write_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block) | ||
2187 | { | ||
2188 | FLAC__byte buffer[FLAC__STREAM_METADATA_HEADER_LENGTH]; | ||
2189 | |||
2190 | FLAC__ASSERT(block->length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); | ||
2191 | |||
2192 | buffer[0] = (block->is_last? 0x80 : 0) | (FLAC__byte)block->type; | ||
2193 | pack_uint32_(block->length, buffer + 1, 3); | ||
2194 | |||
2195 | if(write_cb(buffer, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH) | ||
2196 | return false; | ||
2197 | |||
2198 | return true; | ||
2199 | } | ||
2200 | |||
2201 | FLAC__bool write_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata *block) | ||
2202 | { | ||
2203 | FLAC__ASSERT(0 != block); | ||
2204 | |||
2205 | switch(block->type) { | ||
2206 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
2207 | return write_metadata_block_data_streaminfo_cb_(handle, write_cb, &block->data.stream_info); | ||
2208 | case FLAC__METADATA_TYPE_PADDING: | ||
2209 | return write_metadata_block_data_padding_cb_(handle, write_cb, &block->data.padding, block->length); | ||
2210 | case FLAC__METADATA_TYPE_APPLICATION: | ||
2211 | return write_metadata_block_data_application_cb_(handle, write_cb, &block->data.application, block->length); | ||
2212 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
2213 | return write_metadata_block_data_seektable_cb_(handle, write_cb, &block->data.seek_table); | ||
2214 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
2215 | return write_metadata_block_data_vorbis_comment_cb_(handle, write_cb, &block->data.vorbis_comment); | ||
2216 | case FLAC__METADATA_TYPE_CUESHEET: | ||
2217 | return write_metadata_block_data_cuesheet_cb_(handle, write_cb, &block->data.cue_sheet); | ||
2218 | default: | ||
2219 | return write_metadata_block_data_unknown_cb_(handle, write_cb, &block->data.unknown, block->length); | ||
2220 | } | ||
2221 | } | ||
2222 | |||
2223 | FLAC__bool write_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_StreamInfo *block) | ||
2224 | { | ||
2225 | FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH]; | ||
2226 | const unsigned channels1 = block->channels - 1; | ||
2227 | const unsigned bps1 = block->bits_per_sample - 1; | ||
2228 | |||
2229 | /* we are using hardcoded numbers for simplicity but we should | ||
2230 | * probably eventually write a bit-level packer and use the | ||
2231 | * _STREAMINFO_ constants. | ||
2232 | */ | ||
2233 | pack_uint32_(block->min_blocksize, buffer, 2); | ||
2234 | pack_uint32_(block->max_blocksize, buffer+2, 2); | ||
2235 | pack_uint32_(block->min_framesize, buffer+4, 3); | ||
2236 | pack_uint32_(block->max_framesize, buffer+7, 3); | ||
2237 | buffer[10] = (block->sample_rate >> 12) & 0xff; | ||
2238 | buffer[11] = (block->sample_rate >> 4) & 0xff; | ||
2239 | buffer[12] = ((block->sample_rate & 0x0f) << 4) | (channels1 << 1) | (bps1 >> 4); | ||
2240 | buffer[13] = (FLAC__byte)(((bps1 & 0x0f) << 4) | ((block->total_samples >> 32) & 0x0f)); | ||
2241 | pack_uint32_((FLAC__uint32)block->total_samples, buffer+14, 4); | ||
2242 | memcpy(buffer+18, block->md5sum, 16); | ||
2243 | |||
2244 | if(write_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) | ||
2245 | return false; | ||
2246 | |||
2247 | return true; | ||
2248 | } | ||
2249 | |||
2250 | FLAC__bool write_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Padding *block, unsigned block_length) | ||
2251 | { | ||
2252 | unsigned i, n = block_length; | ||
2253 | FLAC__byte buffer[1024]; | ||
2254 | |||
2255 | (void)block; | ||
2256 | |||
2257 | memset(buffer, 0, 1024); | ||
2258 | |||
2259 | for(i = 0; i < n/1024; i++) | ||
2260 | if(write_cb(buffer, 1, 1024, handle) != 1024) | ||
2261 | return false; | ||
2262 | |||
2263 | n %= 1024; | ||
2264 | |||
2265 | if(write_cb(buffer, 1, n, handle) != n) | ||
2266 | return false; | ||
2267 | |||
2268 | return true; | ||
2269 | } | ||
2270 | |||
2271 | FLAC__bool write_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Application *block, unsigned block_length) | ||
2272 | { | ||
2273 | const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; | ||
2274 | |||
2275 | if(write_cb(block->id, 1, id_bytes, handle) != id_bytes) | ||
2276 | return false; | ||
2277 | |||
2278 | block_length -= id_bytes; | ||
2279 | |||
2280 | if(write_cb(block->data, 1, block_length, handle) != block_length) | ||
2281 | return false; | ||
2282 | |||
2283 | return true; | ||
2284 | } | ||
2285 | |||
2286 | FLAC__bool write_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_SeekTable *block) | ||
2287 | { | ||
2288 | unsigned i; | ||
2289 | FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; | ||
2290 | |||
2291 | for(i = 0; i < block->num_points; i++) { | ||
2292 | /* some MAGIC NUMBERs here */ | ||
2293 | pack_uint64_(block->points[i].sample_number, buffer, 8); | ||
2294 | pack_uint64_(block->points[i].stream_offset, buffer+8, 8); | ||
2295 | pack_uint32_(block->points[i].frame_samples, buffer+16, 2); | ||
2296 | if(write_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) | ||
2297 | return false; | ||
2298 | } | ||
2299 | |||
2300 | return true; | ||
2301 | } | ||
2302 | |||
2303 | FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_VorbisComment *block) | ||
2304 | { | ||
2305 | unsigned i; | ||
2306 | const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8; | ||
2307 | const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; | ||
2308 | FLAC__byte buffer[4]; /* magic number is asserted below */ | ||
2309 | |||
2310 | FLAC__ASSERT(max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == 4); | ||
2311 | |||
2312 | pack_uint32_little_endian_(block->vendor_string.length, buffer, entry_length_len); | ||
2313 | if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len) | ||
2314 | return false; | ||
2315 | if(write_cb(block->vendor_string.entry, 1, block->vendor_string.length, handle) != block->vendor_string.length) | ||
2316 | return false; | ||
2317 | |||
2318 | pack_uint32_little_endian_(block->num_comments, buffer, num_comments_len); | ||
2319 | if(write_cb(buffer, 1, num_comments_len, handle) != num_comments_len) | ||
2320 | return false; | ||
2321 | |||
2322 | for(i = 0; i < block->num_comments; i++) { | ||
2323 | pack_uint32_little_endian_(block->comments[i].length, buffer, entry_length_len); | ||
2324 | if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len) | ||
2325 | return false; | ||
2326 | if(write_cb(block->comments[i].entry, 1, block->comments[i].length, handle) != block->comments[i].length) | ||
2327 | return false; | ||
2328 | } | ||
2329 | |||
2330 | return true; | ||
2331 | } | ||
2332 | |||
2333 | FLAC__bool write_metadata_block_data_cuesheet_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_CueSheet *block) | ||
2334 | { | ||
2335 | unsigned i, j, len; | ||
2336 | FLAC__byte buffer[1024]; /* asserted below that this is big enough */ | ||
2337 | |||
2338 | FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64)); | ||
2339 | FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN/8); | ||
2340 | FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)/8); | ||
2341 | FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8); | ||
2342 | |||
2343 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | ||
2344 | len = FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN / 8; | ||
2345 | if(write_cb(block->media_catalog_number, 1, len, handle) != len) | ||
2346 | return false; | ||
2347 | |||
2348 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN % 8 == 0); | ||
2349 | len = FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN / 8; | ||
2350 | pack_uint64_(block->lead_in, buffer, len); | ||
2351 | if(write_cb(buffer, 1, len, handle) != len) | ||
2352 | return false; | ||
2353 | |||
2354 | FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) % 8 == 0); | ||
2355 | len = (FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN) / 8; | ||
2356 | memset(buffer, 0, len); | ||
2357 | if(block->is_cd) | ||
2358 | buffer[0] |= 0x80; | ||
2359 | if(write_cb(buffer, 1, len, handle) != len) | ||
2360 | return false; | ||
2361 | |||
2362 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN % 8 == 0); | ||
2363 | len = FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN / 8; | ||
2364 | pack_uint32_(block->num_tracks, buffer, len); | ||
2365 | if(write_cb(buffer, 1, len, handle) != len) | ||
2366 | return false; | ||
2367 | |||
2368 | for(i = 0; i < block->num_tracks; i++) { | ||
2369 | FLAC__StreamMetadata_CueSheet_Track *track = block->tracks + i; | ||
2370 | |||
2371 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0); | ||
2372 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8; | ||
2373 | pack_uint64_(track->offset, buffer, len); | ||
2374 | if(write_cb(buffer, 1, len, handle) != len) | ||
2375 | return false; | ||
2376 | |||
2377 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0); | ||
2378 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8; | ||
2379 | pack_uint32_(track->number, buffer, len); | ||
2380 | if(write_cb(buffer, 1, len, handle) != len) | ||
2381 | return false; | ||
2382 | |||
2383 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | ||
2384 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8; | ||
2385 | if(write_cb(track->isrc, 1, len, handle) != len) | ||
2386 | return false; | ||
2387 | |||
2388 | FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0); | ||
2389 | len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8; | ||
2390 | memset(buffer, 0, len); | ||
2391 | buffer[0] = (track->type << 7) | (track->pre_emphasis << 6); | ||
2392 | if(write_cb(buffer, 1, len, handle) != len) | ||
2393 | return false; | ||
2394 | |||
2395 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN % 8 == 0); | ||
2396 | len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN / 8; | ||
2397 | pack_uint32_(track->num_indices, buffer, len); | ||
2398 | if(write_cb(buffer, 1, len, handle) != len) | ||
2399 | return false; | ||
2400 | |||
2401 | for(j = 0; j < track->num_indices; j++) { | ||
2402 | FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j; | ||
2403 | |||
2404 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN % 8 == 0); | ||
2405 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN / 8; | ||
2406 | pack_uint64_(index->offset, buffer, len); | ||
2407 | if(write_cb(buffer, 1, len, handle) != len) | ||
2408 | return false; | ||
2409 | |||
2410 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN % 8 == 0); | ||
2411 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN / 8; | ||
2412 | pack_uint32_(index->number, buffer, len); | ||
2413 | if(write_cb(buffer, 1, len, handle) != len) | ||
2414 | return false; | ||
2415 | |||
2416 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN % 8 == 0); | ||
2417 | len = FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN / 8; | ||
2418 | memset(buffer, 0, len); | ||
2419 | if(write_cb(buffer, 1, len, handle) != len) | ||
2420 | return false; | ||
2421 | } | ||
2422 | } | ||
2423 | |||
2424 | return true; | ||
2425 | } | ||
2426 | |||
2427 | FLAC__bool write_metadata_block_data_unknown_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Write write_cb, const FLAC__StreamMetadata_Unknown *block, unsigned block_length) | ||
2428 | { | ||
2429 | if(write_cb(block->data, 1, block_length, handle) != block_length) | ||
2430 | return false; | ||
2431 | |||
2432 | return true; | ||
2433 | } | ||
2434 | |||
2435 | FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block) | ||
2436 | { | ||
2437 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { | ||
2438 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2439 | return false; | ||
2440 | } | ||
2441 | |||
2442 | if(!write_metadata_block_header_(iterator->file, &iterator->status, block)) | ||
2443 | return false; | ||
2444 | |||
2445 | if(!write_metadata_block_data_(iterator->file, &iterator->status, block)) | ||
2446 | return false; | ||
2447 | |||
2448 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { | ||
2449 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2450 | return false; | ||
2451 | } | ||
2452 | |||
2453 | return read_metadata_block_header_(iterator); | ||
2454 | } | ||
2455 | |||
2456 | FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last) | ||
2457 | { | ||
2458 | FLAC__StreamMetadata *padding; | ||
2459 | |||
2460 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { | ||
2461 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2462 | return false; | ||
2463 | } | ||
2464 | |||
2465 | block->is_last = false; | ||
2466 | |||
2467 | if(!write_metadata_block_header_(iterator->file, &iterator->status, block)) | ||
2468 | return false; | ||
2469 | |||
2470 | if(!write_metadata_block_data_(iterator->file, &iterator->status, block)) | ||
2471 | return false; | ||
2472 | |||
2473 | if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) | ||
2474 | return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2475 | |||
2476 | padding->is_last = padding_is_last; | ||
2477 | padding->length = padding_length; | ||
2478 | |||
2479 | if(!write_metadata_block_header_(iterator->file, &iterator->status, padding)) { | ||
2480 | FLAC__metadata_object_delete(padding); | ||
2481 | return false; | ||
2482 | } | ||
2483 | |||
2484 | if(!write_metadata_block_data_(iterator->file, &iterator->status, padding)) { | ||
2485 | FLAC__metadata_object_delete(padding); | ||
2486 | return false; | ||
2487 | } | ||
2488 | |||
2489 | FLAC__metadata_object_delete(padding); | ||
2490 | |||
2491 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { | ||
2492 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2493 | return false; | ||
2494 | } | ||
2495 | |||
2496 | return read_metadata_block_header_(iterator); | ||
2497 | } | ||
2498 | |||
2499 | FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append) | ||
2500 | { | ||
2501 | FILE *tempfile; | ||
2502 | char *tempfilename; | ||
2503 | int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */ | ||
2504 | long fixup_is_last_flag_offset = -1; | ||
2505 | |||
2506 | FLAC__ASSERT(0 != block || append == false); | ||
2507 | |||
2508 | if(iterator->is_last) { | ||
2509 | if(append) { | ||
2510 | fixup_is_last_code = 1; /* 1 => clear the is_last flag at the following offset */ | ||
2511 | fixup_is_last_flag_offset = iterator->offset[iterator->depth]; | ||
2512 | } | ||
2513 | else if(0 == block) { | ||
2514 | simple_iterator_push_(iterator); | ||
2515 | if(!FLAC__metadata_simple_iterator_prev(iterator)) { | ||
2516 | (void)simple_iterator_pop_(iterator); | ||
2517 | return false; | ||
2518 | } | ||
2519 | fixup_is_last_code = -1; /* -1 => set the is_last the flag at the following offset */ | ||
2520 | fixup_is_last_flag_offset = iterator->offset[iterator->depth]; | ||
2521 | if(!simple_iterator_pop_(iterator)) | ||
2522 | return false; | ||
2523 | } | ||
2524 | } | ||
2525 | |||
2526 | if(!simple_iterator_copy_file_prefix_(iterator, &tempfile, &tempfilename, append)) | ||
2527 | return false; | ||
2528 | |||
2529 | if(0 != block) { | ||
2530 | if(!write_metadata_block_header_(tempfile, &iterator->status, block)) { | ||
2531 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
2532 | return false; | ||
2533 | } | ||
2534 | |||
2535 | if(!write_metadata_block_data_(tempfile, &iterator->status, block)) { | ||
2536 | cleanup_tempfile_(&tempfile, &tempfilename); | ||
2537 | return false; | ||
2538 | } | ||
2539 | } | ||
2540 | |||
2541 | if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_code, fixup_is_last_flag_offset, block==0)) | ||
2542 | return false; | ||
2543 | |||
2544 | if(append) | ||
2545 | return FLAC__metadata_simple_iterator_next(iterator); | ||
2546 | |||
2547 | return true; | ||
2548 | } | ||
2549 | |||
2550 | void simple_iterator_push_(FLAC__Metadata_SimpleIterator *iterator) | ||
2551 | { | ||
2552 | FLAC__ASSERT(iterator->depth+1 < SIMPLE_ITERATOR_MAX_PUSH_DEPTH); | ||
2553 | iterator->offset[iterator->depth+1] = iterator->offset[iterator->depth]; | ||
2554 | iterator->depth++; | ||
2555 | } | ||
2556 | |||
2557 | FLAC__bool simple_iterator_pop_(FLAC__Metadata_SimpleIterator *iterator) | ||
2558 | { | ||
2559 | FLAC__ASSERT(iterator->depth > 0); | ||
2560 | iterator->depth--; | ||
2561 | if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { | ||
2562 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2563 | return false; | ||
2564 | } | ||
2565 | |||
2566 | return read_metadata_block_header_(iterator); | ||
2567 | } | ||
2568 | |||
2569 | /* return meanings: | ||
2570 | * 0: ok | ||
2571 | * 1: read error | ||
2572 | * 2: seek error | ||
2573 | * 3: not a FLAC file | ||
2574 | */ | ||
2575 | unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb) | ||
2576 | { | ||
2577 | FLAC__byte buffer[4]; | ||
2578 | size_t n; | ||
2579 | unsigned i; | ||
2580 | |||
2581 | FLAC__ASSERT(FLAC__STREAM_SYNC_LENGTH == 4); | ||
2582 | |||
2583 | /* skip any id3v2 tag */ | ||
2584 | errno = 0; | ||
2585 | n = read_cb(buffer, 1, 4, handle); | ||
2586 | if(errno) | ||
2587 | return 1; | ||
2588 | else if(n != 4) | ||
2589 | return 3; | ||
2590 | else if(0 == memcmp(buffer, "ID3", 3)) { | ||
2591 | unsigned tag_length = 0; | ||
2592 | |||
2593 | /* skip to the tag length */ | ||
2594 | if(seek_cb(handle, 2, SEEK_CUR) < 0) | ||
2595 | return 2; | ||
2596 | |||
2597 | /* read the length */ | ||
2598 | for(i = 0; i < 4; i++) { | ||
2599 | if(read_cb(buffer, 1, 1, handle) < 1 || buffer[0] & 0x80) | ||
2600 | return 1; | ||
2601 | tag_length <<= 7; | ||
2602 | tag_length |= (buffer[0] & 0x7f); | ||
2603 | } | ||
2604 | |||
2605 | /* skip the rest of the tag */ | ||
2606 | if(seek_cb(handle, tag_length, SEEK_CUR) < 0) | ||
2607 | return 2; | ||
2608 | |||
2609 | /* read the stream sync code */ | ||
2610 | errno = 0; | ||
2611 | n = read_cb(buffer, 1, 4, handle); | ||
2612 | if(errno) | ||
2613 | return 1; | ||
2614 | else if(n != 4) | ||
2615 | return 3; | ||
2616 | } | ||
2617 | |||
2618 | /* check for the fLaC signature */ | ||
2619 | if(0 == memcmp(FLAC__STREAM_SYNC_STRING, buffer, FLAC__STREAM_SYNC_LENGTH)) | ||
2620 | return 0; | ||
2621 | else | ||
2622 | return 3; | ||
2623 | } | ||
2624 | |||
2625 | unsigned seek_to_first_metadata_block_(FILE *f) | ||
2626 | { | ||
2627 | return seek_to_first_metadata_block_cb_((FLAC__IOHandle)f, (FLAC__IOCallback_Read)fread, fseek_wrapper_); | ||
2628 | } | ||
2629 | |||
2630 | FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append) | ||
2631 | { | ||
2632 | const long offset_end = append? iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length : iterator->offset[iterator->depth]; | ||
2633 | |||
2634 | if(0 != fseek(iterator->file, 0, SEEK_SET)) { | ||
2635 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2636 | return false; | ||
2637 | } | ||
2638 | if(!open_tempfile_(iterator->filename, iterator->tempfile_path_prefix, tempfile, tempfilename, &iterator->status)) { | ||
2639 | cleanup_tempfile_(tempfile, tempfilename); | ||
2640 | return false; | ||
2641 | } | ||
2642 | if(!copy_n_bytes_from_file_(iterator->file, *tempfile, offset_end, &iterator->status)) { | ||
2643 | cleanup_tempfile_(tempfile, tempfilename); | ||
2644 | return false; | ||
2645 | } | ||
2646 | |||
2647 | return true; | ||
2648 | } | ||
2649 | |||
2650 | FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, long fixup_is_last_flag_offset, FLAC__bool backup) | ||
2651 | { | ||
2652 | long save_offset = iterator->offset[iterator->depth]; /*@@@ 2G limit */ | ||
2653 | FLAC__ASSERT(0 != *tempfile); | ||
2654 | |||
2655 | if(0 != fseek(iterator->file, save_offset + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length, SEEK_SET)) { | ||
2656 | cleanup_tempfile_(tempfile, tempfilename); | ||
2657 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2658 | return false; | ||
2659 | } | ||
2660 | if(!copy_remaining_bytes_from_file_(iterator->file, *tempfile, &iterator->status)) { | ||
2661 | cleanup_tempfile_(tempfile, tempfilename); | ||
2662 | return false; | ||
2663 | } | ||
2664 | |||
2665 | if(fixup_is_last_code != 0) { | ||
2666 | /* | ||
2667 | * if code == 1, it means a block was appended to the end so | ||
2668 | * we have to clear the is_last flag of the previous block | ||
2669 | * if code == -1, it means the last block was deleted so | ||
2670 | * we have to set the is_last flag of the previous block | ||
2671 | */ | ||
2672 | /* MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */ | ||
2673 | FLAC__byte x; | ||
2674 | if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { | ||
2675 | cleanup_tempfile_(tempfile, tempfilename); | ||
2676 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2677 | return false; | ||
2678 | } | ||
2679 | if(fread(&x, 1, 1, *tempfile) != 1) { | ||
2680 | cleanup_tempfile_(tempfile, tempfilename); | ||
2681 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2682 | return false; | ||
2683 | } | ||
2684 | if(fixup_is_last_code > 0) { | ||
2685 | FLAC__ASSERT(x & 0x80); | ||
2686 | x &= 0x7f; | ||
2687 | } | ||
2688 | else { | ||
2689 | FLAC__ASSERT(!(x & 0x80)); | ||
2690 | x |= 0x80; | ||
2691 | } | ||
2692 | if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) { | ||
2693 | cleanup_tempfile_(tempfile, tempfilename); | ||
2694 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; | ||
2695 | return false; | ||
2696 | } | ||
2697 | if(local__fwrite(&x, 1, 1, *tempfile) != 1) { | ||
2698 | cleanup_tempfile_(tempfile, tempfilename); | ||
2699 | iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2700 | return false; | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | (void)fclose(iterator->file); | ||
2705 | |||
2706 | if(!transport_tempfile_(iterator->filename, tempfile, tempfilename, &iterator->status)) | ||
2707 | return false; | ||
2708 | |||
2709 | if(iterator->has_stats) | ||
2710 | set_file_stats_(iterator->filename, &iterator->stats); | ||
2711 | |||
2712 | if(!simple_iterator_prime_input_(iterator, !iterator->is_writable)) | ||
2713 | return false; | ||
2714 | if(backup) { | ||
2715 | while(iterator->offset[iterator->depth] + (long)FLAC__STREAM_METADATA_HEADER_LENGTH + (long)iterator->length < save_offset) | ||
2716 | if(!FLAC__metadata_simple_iterator_next(iterator)) | ||
2717 | return false; | ||
2718 | return true; | ||
2719 | } | ||
2720 | else { | ||
2721 | /* move the iterator to it's original block faster by faking a push, then doing a pop_ */ | ||
2722 | FLAC__ASSERT(iterator->depth == 0); | ||
2723 | iterator->offset[0] = save_offset; | ||
2724 | iterator->depth++; | ||
2725 | return simple_iterator_pop_(iterator); | ||
2726 | } | ||
2727 | } | ||
2728 | |||
2729 | FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2730 | { | ||
2731 | FLAC__byte buffer[8192]; | ||
2732 | unsigned n; | ||
2733 | |||
2734 | while(bytes > 0) { | ||
2735 | n = min(sizeof(buffer), bytes); | ||
2736 | if(fread(buffer, 1, n, file) != n) { | ||
2737 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2738 | return false; | ||
2739 | } | ||
2740 | if(local__fwrite(buffer, 1, n, tempfile) != n) { | ||
2741 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2742 | return false; | ||
2743 | } | ||
2744 | bytes -= n; | ||
2745 | } | ||
2746 | |||
2747 | return true; | ||
2748 | } | ||
2749 | |||
2750 | FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, unsigned bytes/*@@@ 4G limit*/, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2751 | { | ||
2752 | FLAC__byte buffer[8192]; | ||
2753 | unsigned n; | ||
2754 | |||
2755 | while(bytes > 0) { | ||
2756 | n = min(sizeof(buffer), bytes); | ||
2757 | if(read_cb(buffer, 1, n, handle) != n) { | ||
2758 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2759 | return false; | ||
2760 | } | ||
2761 | if(temp_write_cb(buffer, 1, n, temp_handle) != n) { | ||
2762 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2763 | return false; | ||
2764 | } | ||
2765 | bytes -= n; | ||
2766 | } | ||
2767 | |||
2768 | return true; | ||
2769 | } | ||
2770 | |||
2771 | FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2772 | { | ||
2773 | FLAC__byte buffer[8192]; | ||
2774 | size_t n; | ||
2775 | |||
2776 | while(!feof(file)) { | ||
2777 | n = fread(buffer, 1, sizeof(buffer), file); | ||
2778 | if(n == 0 && !feof(file)) { | ||
2779 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2780 | return false; | ||
2781 | } | ||
2782 | if(n > 0 && local__fwrite(buffer, 1, n, tempfile) != n) { | ||
2783 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2784 | return false; | ||
2785 | } | ||
2786 | } | ||
2787 | |||
2788 | return true; | ||
2789 | } | ||
2790 | |||
2791 | FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2792 | { | ||
2793 | FLAC__byte buffer[8192]; | ||
2794 | size_t n; | ||
2795 | |||
2796 | while(!eof_cb(handle)) { | ||
2797 | n = read_cb(buffer, 1, sizeof(buffer), handle); | ||
2798 | if(n == 0 && !eof_cb(handle)) { | ||
2799 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; | ||
2800 | return false; | ||
2801 | } | ||
2802 | if(n > 0 && temp_write_cb(buffer, 1, n, temp_handle) != n) { | ||
2803 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; | ||
2804 | return false; | ||
2805 | } | ||
2806 | } | ||
2807 | |||
2808 | return true; | ||
2809 | } | ||
2810 | |||
2811 | FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2812 | { | ||
2813 | static const char *tempfile_suffix = ".metadata_edit"; | ||
2814 | if(0 == tempfile_path_prefix) { | ||
2815 | if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) { | ||
2816 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2817 | return false; | ||
2818 | } | ||
2819 | strcpy(*tempfilename, filename); | ||
2820 | strcat(*tempfilename, tempfile_suffix); | ||
2821 | } | ||
2822 | else { | ||
2823 | const char *p = strrchr(filename, '/'); | ||
2824 | if(0 == p) | ||
2825 | p = filename; | ||
2826 | else | ||
2827 | p++; | ||
2828 | |||
2829 | if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) { | ||
2830 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2831 | return false; | ||
2832 | } | ||
2833 | strcpy(*tempfilename, tempfile_path_prefix); | ||
2834 | strcat(*tempfilename, "/"); | ||
2835 | strcat(*tempfilename, p); | ||
2836 | strcat(*tempfilename, tempfile_suffix); | ||
2837 | } | ||
2838 | |||
2839 | if(0 == (*tempfile = fopen(*tempfilename, "w+b"))) { | ||
2840 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE; | ||
2841 | return false; | ||
2842 | } | ||
2843 | |||
2844 | return true; | ||
2845 | } | ||
2846 | |||
2847 | FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename, FLAC__Metadata_SimpleIteratorStatus *status) | ||
2848 | { | ||
2849 | FLAC__ASSERT(0 != filename); | ||
2850 | FLAC__ASSERT(0 != tempfile); | ||
2851 | FLAC__ASSERT(0 != *tempfile); | ||
2852 | FLAC__ASSERT(0 != tempfilename); | ||
2853 | FLAC__ASSERT(0 != *tempfilename); | ||
2854 | FLAC__ASSERT(0 != status); | ||
2855 | |||
2856 | (void)fclose(*tempfile); | ||
2857 | *tempfile = 0; | ||
2858 | |||
2859 | #if defined _MSC_VER || defined __MINGW32__ | ||
2860 | if(unlink(filename) < 0) { | ||
2861 | cleanup_tempfile_(tempfile, tempfilename); | ||
2862 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR; | ||
2863 | return false; | ||
2864 | } | ||
2865 | #endif | ||
2866 | |||
2867 | /*@@@ to fully support the tempfile_path_prefix we need to update this piece to actually copy across filesystems instead of just rename(): */ | ||
2868 | if(0 != rename(*tempfilename, filename)) { | ||
2869 | cleanup_tempfile_(tempfile, tempfilename); | ||
2870 | *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR; | ||
2871 | return false; | ||
2872 | } | ||
2873 | |||
2874 | cleanup_tempfile_(tempfile, tempfilename); | ||
2875 | |||
2876 | return true; | ||
2877 | } | ||
2878 | |||
2879 | void cleanup_tempfile_(FILE **tempfile, char **tempfilename) | ||
2880 | { | ||
2881 | if(0 != *tempfile) { | ||
2882 | (void)fclose(*tempfile); | ||
2883 | *tempfile = 0; | ||
2884 | } | ||
2885 | |||
2886 | if(0 != *tempfilename) { | ||
2887 | (void)unlink(*tempfilename); | ||
2888 | free(*tempfilename); | ||
2889 | *tempfilename = 0; | ||
2890 | } | ||
2891 | } | ||
2892 | |||
2893 | FLAC__bool get_file_stats_(const char *filename, struct stat *stats) | ||
2894 | { | ||
2895 | FLAC__ASSERT(0 != filename); | ||
2896 | FLAC__ASSERT(0 != stats); | ||
2897 | return (0 == stat(filename, stats)); | ||
2898 | } | ||
2899 | |||
2900 | void set_file_stats_(const char *filename, struct stat *stats) | ||
2901 | { | ||
2902 | struct utimbuf srctime; | ||
2903 | |||
2904 | FLAC__ASSERT(0 != filename); | ||
2905 | FLAC__ASSERT(0 != stats); | ||
2906 | |||
2907 | srctime.actime = stats->st_atime; | ||
2908 | srctime.modtime = stats->st_mtime; | ||
2909 | (void)chmod(filename, stats->st_mode); | ||
2910 | (void)utime(filename, &srctime); | ||
2911 | #if !defined _MSC_VER && !defined __MINGW32__ | ||
2912 | (void)chown(filename, stats->st_uid, -1); | ||
2913 | (void)chown(filename, -1, stats->st_gid); | ||
2914 | #endif | ||
2915 | } | ||
2916 | |||
2917 | /* @@@ WATCHOUT @@@ | ||
2918 | * We cast FLAC__int64 to long and use fseek()/ftell() because | ||
2919 | * none of our operations on metadata is ever likely to go past | ||
2920 | * 2 gigabytes. | ||
2921 | */ | ||
2922 | int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence) | ||
2923 | { | ||
2924 | FLAC__ASSERT(offset <= 0x7fffffff); | ||
2925 | return fseek((FILE*)handle, (long)offset, whence); | ||
2926 | } | ||
2927 | |||
2928 | FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle) | ||
2929 | { | ||
2930 | return (long)ftell((FILE*)handle); | ||
2931 | } | ||
2932 | |||
2933 | FLAC__Metadata_ChainStatus get_equivalent_status_(FLAC__Metadata_SimpleIteratorStatus status) | ||
2934 | { | ||
2935 | switch(status) { | ||
2936 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK: | ||
2937 | return FLAC__METADATA_CHAIN_STATUS_OK; | ||
2938 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT: | ||
2939 | return FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT; | ||
2940 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE: | ||
2941 | return FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE; | ||
2942 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE: | ||
2943 | return FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE; | ||
2944 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE: | ||
2945 | return FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE; | ||
2946 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA: | ||
2947 | return FLAC__METADATA_CHAIN_STATUS_BAD_METADATA; | ||
2948 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR: | ||
2949 | return FLAC__METADATA_CHAIN_STATUS_READ_ERROR; | ||
2950 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR: | ||
2951 | return FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; | ||
2952 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR: | ||
2953 | return FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR; | ||
2954 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR: | ||
2955 | return FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR; | ||
2956 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR: | ||
2957 | return FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR; | ||
2958 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR: | ||
2959 | return FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; | ||
2960 | case FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR: | ||
2961 | default: | ||
2962 | return FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR; | ||
2963 | } | ||
2964 | } | ||
diff --git a/apps/codecs/libFLAC/metadata_object.c b/apps/codecs/libFLAC/metadata_object.c new file mode 100644 index 0000000000..290036ce26 --- /dev/null +++ b/apps/codecs/libFLAC/metadata_object.c | |||
@@ -0,0 +1,1472 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdlib.h> | ||
33 | #include <string.h> | ||
34 | |||
35 | #include "private/metadata.h" | ||
36 | |||
37 | #include "FLAC/assert.h" | ||
38 | |||
39 | |||
40 | /**************************************************************************** | ||
41 | * | ||
42 | * Local routines | ||
43 | * | ||
44 | ***************************************************************************/ | ||
45 | |||
46 | static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes) | ||
47 | { | ||
48 | if(bytes > 0 && 0 != from) { | ||
49 | FLAC__byte *x; | ||
50 | if(0 == (x = (FLAC__byte*)malloc(bytes))) | ||
51 | return false; | ||
52 | memcpy(x, from, bytes); | ||
53 | *to = x; | ||
54 | } | ||
55 | else { | ||
56 | FLAC__ASSERT(0 == from); | ||
57 | FLAC__ASSERT(bytes == 0); | ||
58 | *to = 0; | ||
59 | } | ||
60 | return true; | ||
61 | } | ||
62 | |||
63 | static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length) | ||
64 | { | ||
65 | FLAC__byte *x = (FLAC__byte*)realloc(*entry, length+1); | ||
66 | if(0 != x) { | ||
67 | x[length] = '\0'; | ||
68 | *entry = x; | ||
69 | return true; | ||
70 | } | ||
71 | else | ||
72 | return false; | ||
73 | } | ||
74 | |||
75 | static FLAC__bool copy_vcentry_(FLAC__StreamMetadata_VorbisComment_Entry *to, const FLAC__StreamMetadata_VorbisComment_Entry *from) | ||
76 | { | ||
77 | to->length = from->length; | ||
78 | if(0 == from->entry) { | ||
79 | FLAC__ASSERT(from->length == 0); | ||
80 | to->entry = 0; | ||
81 | } | ||
82 | else { | ||
83 | FLAC__byte *x; | ||
84 | FLAC__ASSERT(from->length > 0); | ||
85 | if(0 == (x = (FLAC__byte*)malloc(from->length+1))) | ||
86 | return false; | ||
87 | memcpy(x, from->entry, from->length); | ||
88 | x[from->length] = '\0'; | ||
89 | to->entry = x; | ||
90 | } | ||
91 | return true; | ||
92 | } | ||
93 | |||
94 | static FLAC__bool copy_track_(FLAC__StreamMetadata_CueSheet_Track *to, const FLAC__StreamMetadata_CueSheet_Track *from) | ||
95 | { | ||
96 | memcpy(to, from, sizeof(FLAC__StreamMetadata_CueSheet_Track)); | ||
97 | if(0 == from->indices) { | ||
98 | FLAC__ASSERT(from->num_indices == 0); | ||
99 | } | ||
100 | else { | ||
101 | FLAC__StreamMetadata_CueSheet_Index *x; | ||
102 | FLAC__ASSERT(from->num_indices > 0); | ||
103 | if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)malloc(from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)))) | ||
104 | return false; | ||
105 | memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index)); | ||
106 | to->indices = x; | ||
107 | } | ||
108 | return true; | ||
109 | } | ||
110 | |||
111 | static void seektable_calculate_length_(FLAC__StreamMetadata *object) | ||
112 | { | ||
113 | FLAC__ASSERT(0 != object); | ||
114 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
115 | |||
116 | object->length = object->data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; | ||
117 | } | ||
118 | |||
119 | static FLAC__StreamMetadata_SeekPoint *seekpoint_array_new_(unsigned num_points) | ||
120 | { | ||
121 | FLAC__StreamMetadata_SeekPoint *object_array; | ||
122 | |||
123 | FLAC__ASSERT(num_points > 0); | ||
124 | |||
125 | object_array = (FLAC__StreamMetadata_SeekPoint*)malloc(num_points * sizeof(FLAC__StreamMetadata_SeekPoint)); | ||
126 | |||
127 | if(0 != object_array) { | ||
128 | unsigned i; | ||
129 | for(i = 0; i < num_points; i++) { | ||
130 | object_array[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | ||
131 | object_array[i].stream_offset = 0; | ||
132 | object_array[i].frame_samples = 0; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | return object_array; | ||
137 | } | ||
138 | |||
139 | static void vorbiscomment_calculate_length_(FLAC__StreamMetadata *object) | ||
140 | { | ||
141 | unsigned i; | ||
142 | |||
143 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
144 | |||
145 | object->length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN) / 8; | ||
146 | object->length += object->data.vorbis_comment.vendor_string.length; | ||
147 | object->length += (FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8; | ||
148 | for(i = 0; i < object->data.vorbis_comment.num_comments; i++) { | ||
149 | object->length += (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8); | ||
150 | object->length += object->data.vorbis_comment.comments[i].length; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_new_(unsigned num_comments) | ||
155 | { | ||
156 | FLAC__ASSERT(num_comments > 0); | ||
157 | |||
158 | return (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)); | ||
159 | } | ||
160 | |||
161 | static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments) | ||
162 | { | ||
163 | unsigned i; | ||
164 | |||
165 | FLAC__ASSERT(0 != object_array && num_comments > 0); | ||
166 | |||
167 | for(i = 0; i < num_comments; i++) | ||
168 | if(0 != object_array[i].entry) | ||
169 | free(object_array[i].entry); | ||
170 | |||
171 | if(0 != object_array) | ||
172 | free(object_array); | ||
173 | } | ||
174 | |||
175 | static FLAC__StreamMetadata_VorbisComment_Entry *vorbiscomment_entry_array_copy_(const FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments) | ||
176 | { | ||
177 | FLAC__StreamMetadata_VorbisComment_Entry *return_array; | ||
178 | |||
179 | FLAC__ASSERT(0 != object_array); | ||
180 | FLAC__ASSERT(num_comments > 0); | ||
181 | |||
182 | return_array = vorbiscomment_entry_array_new_(num_comments); | ||
183 | |||
184 | if(0 != return_array) { | ||
185 | unsigned i; | ||
186 | |||
187 | for(i = 0; i < num_comments; i++) { | ||
188 | if(!copy_vcentry_(return_array+i, object_array+i)) { | ||
189 | vorbiscomment_entry_array_delete_(return_array, num_comments); | ||
190 | return 0; | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | return return_array; | ||
196 | } | ||
197 | |||
198 | static FLAC__bool vorbiscomment_set_entry_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry *dest, const FLAC__StreamMetadata_VorbisComment_Entry *src, FLAC__bool copy) | ||
199 | { | ||
200 | FLAC__byte *save; | ||
201 | |||
202 | FLAC__ASSERT(0 != object); | ||
203 | FLAC__ASSERT(0 != dest); | ||
204 | FLAC__ASSERT(0 != src); | ||
205 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
206 | FLAC__ASSERT((0 != src->entry && src->length > 0) || (0 == src->entry && src->length == 0)); | ||
207 | |||
208 | save = dest->entry; | ||
209 | |||
210 | if(0 != src->entry && src->length > 0) { | ||
211 | if(copy) { | ||
212 | /* do the copy first so that if we fail we leave the dest object untouched */ | ||
213 | if(!copy_vcentry_(dest, src)) | ||
214 | return false; | ||
215 | } | ||
216 | else { | ||
217 | /* we have to make sure that the string we're taking over is null-terminated */ | ||
218 | |||
219 | /* | ||
220 | * Stripping the const from src->entry is OK since we're taking | ||
221 | * ownership of the pointer. This is a hack around a deficiency | ||
222 | * in the API where the same function is used for 'copy' and | ||
223 | * 'own', but the source entry is a const pointer. If we were | ||
224 | * precise, the 'own' flavor would be a separate function with a | ||
225 | * non-const source pointer. But it's not, so we hack away. | ||
226 | */ | ||
227 | if(!ensure_null_terminated_((FLAC__byte**)(&src->entry), src->length)) | ||
228 | return false; | ||
229 | *dest = *src; | ||
230 | } | ||
231 | } | ||
232 | else { | ||
233 | /* the src is null */ | ||
234 | *dest = *src; | ||
235 | } | ||
236 | |||
237 | if(0 != save) | ||
238 | free(save); | ||
239 | |||
240 | vorbiscomment_calculate_length_(object); | ||
241 | return true; | ||
242 | } | ||
243 | |||
244 | static int vorbiscomment_find_entry_from_(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name, unsigned field_name_length) | ||
245 | { | ||
246 | unsigned i; | ||
247 | |||
248 | FLAC__ASSERT(0 != object); | ||
249 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
250 | FLAC__ASSERT(0 != field_name); | ||
251 | |||
252 | for(i = offset; i < object->data.vorbis_comment.num_comments; i++) { | ||
253 | if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) | ||
254 | return (int)i; | ||
255 | } | ||
256 | |||
257 | return -1; | ||
258 | } | ||
259 | |||
260 | static void cuesheet_calculate_length_(FLAC__StreamMetadata *object) | ||
261 | { | ||
262 | unsigned i; | ||
263 | |||
264 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
265 | |||
266 | object->length = ( | ||
267 | FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN + | ||
268 | FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN + | ||
269 | FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN + | ||
270 | FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN + | ||
271 | FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN | ||
272 | ) / 8; | ||
273 | |||
274 | object->length += object->data.cue_sheet.num_tracks * ( | ||
275 | FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN + | ||
276 | FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN + | ||
277 | FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN + | ||
278 | FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + | ||
279 | FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + | ||
280 | FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN + | ||
281 | FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN | ||
282 | ) / 8; | ||
283 | |||
284 | for(i = 0; i < object->data.cue_sheet.num_tracks; i++) { | ||
285 | object->length += object->data.cue_sheet.tracks[i].num_indices * ( | ||
286 | FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN + | ||
287 | FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN + | ||
288 | FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN | ||
289 | ) / 8; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | static FLAC__StreamMetadata_CueSheet_Index *cuesheet_track_index_array_new_(unsigned num_indices) | ||
294 | { | ||
295 | FLAC__ASSERT(num_indices > 0); | ||
296 | |||
297 | return (FLAC__StreamMetadata_CueSheet_Index*)calloc(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)); | ||
298 | } | ||
299 | |||
300 | static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks) | ||
301 | { | ||
302 | FLAC__ASSERT(num_tracks > 0); | ||
303 | |||
304 | return (FLAC__StreamMetadata_CueSheet_Track*)calloc(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)); | ||
305 | } | ||
306 | |||
307 | static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks) | ||
308 | { | ||
309 | unsigned i; | ||
310 | |||
311 | FLAC__ASSERT(0 != object_array && num_tracks > 0); | ||
312 | |||
313 | for(i = 0; i < num_tracks; i++) { | ||
314 | if(0 != object_array[i].indices) { | ||
315 | FLAC__ASSERT(object_array[i].num_indices > 0); | ||
316 | free(object_array[i].indices); | ||
317 | } | ||
318 | } | ||
319 | |||
320 | if(0 != object_array) | ||
321 | free(object_array); | ||
322 | } | ||
323 | |||
324 | static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_copy_(const FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks) | ||
325 | { | ||
326 | FLAC__StreamMetadata_CueSheet_Track *return_array; | ||
327 | |||
328 | FLAC__ASSERT(0 != object_array); | ||
329 | FLAC__ASSERT(num_tracks > 0); | ||
330 | |||
331 | return_array = cuesheet_track_array_new_(num_tracks); | ||
332 | |||
333 | if(0 != return_array) { | ||
334 | unsigned i; | ||
335 | |||
336 | for(i = 0; i < num_tracks; i++) { | ||
337 | if(!copy_track_(return_array+i, object_array+i)) { | ||
338 | cuesheet_track_array_delete_(return_array, num_tracks); | ||
339 | return 0; | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | return return_array; | ||
345 | } | ||
346 | |||
347 | static FLAC__bool cuesheet_set_track_(FLAC__StreamMetadata *object, FLAC__StreamMetadata_CueSheet_Track *dest, const FLAC__StreamMetadata_CueSheet_Track *src, FLAC__bool copy) | ||
348 | { | ||
349 | FLAC__StreamMetadata_CueSheet_Index *save; | ||
350 | |||
351 | FLAC__ASSERT(0 != object); | ||
352 | FLAC__ASSERT(0 != dest); | ||
353 | FLAC__ASSERT(0 != src); | ||
354 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
355 | FLAC__ASSERT((0 != src->indices && src->num_indices > 0) || (0 == src->indices && src->num_indices == 0)); | ||
356 | |||
357 | save = dest->indices; | ||
358 | |||
359 | /* do the copy first so that if we fail we leave the object untouched */ | ||
360 | if(copy) { | ||
361 | if(!copy_track_(dest, src)) | ||
362 | return false; | ||
363 | } | ||
364 | else { | ||
365 | *dest = *src; | ||
366 | } | ||
367 | |||
368 | if(0 != save) | ||
369 | free(save); | ||
370 | |||
371 | cuesheet_calculate_length_(object); | ||
372 | return true; | ||
373 | } | ||
374 | |||
375 | |||
376 | /**************************************************************************** | ||
377 | * | ||
378 | * Metadata object routines | ||
379 | * | ||
380 | ***************************************************************************/ | ||
381 | |||
382 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type) | ||
383 | { | ||
384 | FLAC__StreamMetadata *object; | ||
385 | |||
386 | if(type > FLAC__MAX_METADATA_TYPE_CODE) | ||
387 | return 0; | ||
388 | |||
389 | object = (FLAC__StreamMetadata*)calloc(1, sizeof(FLAC__StreamMetadata)); | ||
390 | if(0 != object) { | ||
391 | object->is_last = false; | ||
392 | object->type = type; | ||
393 | switch(type) { | ||
394 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
395 | object->length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; | ||
396 | break; | ||
397 | case FLAC__METADATA_TYPE_PADDING: | ||
398 | /* calloc() took care of this for us: | ||
399 | object->length = 0; | ||
400 | */ | ||
401 | break; | ||
402 | case FLAC__METADATA_TYPE_APPLICATION: | ||
403 | object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; | ||
404 | /* calloc() took care of this for us: | ||
405 | object->data.application.data = 0; | ||
406 | */ | ||
407 | break; | ||
408 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
409 | /* calloc() took care of this for us: | ||
410 | object->length = 0; | ||
411 | object->data.seek_table.num_points = 0; | ||
412 | object->data.seek_table.points = 0; | ||
413 | */ | ||
414 | break; | ||
415 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
416 | { | ||
417 | object->data.vorbis_comment.vendor_string.length = (unsigned)strlen(FLAC__VENDOR_STRING); | ||
418 | if(!copy_bytes_(&object->data.vorbis_comment.vendor_string.entry, (const FLAC__byte*)FLAC__VENDOR_STRING, object->data.vorbis_comment.vendor_string.length+1)) { | ||
419 | free(object); | ||
420 | return 0; | ||
421 | } | ||
422 | vorbiscomment_calculate_length_(object); | ||
423 | } | ||
424 | break; | ||
425 | case FLAC__METADATA_TYPE_CUESHEET: | ||
426 | cuesheet_calculate_length_(object); | ||
427 | break; | ||
428 | default: | ||
429 | /* calloc() took care of this for us: | ||
430 | object->length = 0; | ||
431 | object->data.unknown.data = 0; | ||
432 | */ | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | return object; | ||
438 | } | ||
439 | |||
440 | FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object) | ||
441 | { | ||
442 | FLAC__StreamMetadata *to; | ||
443 | |||
444 | FLAC__ASSERT(0 != object); | ||
445 | |||
446 | if(0 != (to = FLAC__metadata_object_new(object->type))) { | ||
447 | to->is_last = object->is_last; | ||
448 | to->type = object->type; | ||
449 | to->length = object->length; | ||
450 | switch(to->type) { | ||
451 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
452 | memcpy(&to->data.stream_info, &object->data.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo)); | ||
453 | break; | ||
454 | case FLAC__METADATA_TYPE_PADDING: | ||
455 | break; | ||
456 | case FLAC__METADATA_TYPE_APPLICATION: | ||
457 | memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8); | ||
458 | if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) { | ||
459 | FLAC__metadata_object_delete(to); | ||
460 | return 0; | ||
461 | } | ||
462 | break; | ||
463 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
464 | to->data.seek_table.num_points = object->data.seek_table.num_points; | ||
465 | if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) { | ||
466 | FLAC__metadata_object_delete(to); | ||
467 | return 0; | ||
468 | } | ||
469 | break; | ||
470 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
471 | if(0 != to->data.vorbis_comment.vendor_string.entry) { | ||
472 | free(to->data.vorbis_comment.vendor_string.entry); | ||
473 | to->data.vorbis_comment.vendor_string.entry = 0; | ||
474 | } | ||
475 | if(!copy_vcentry_(&to->data.vorbis_comment.vendor_string, &object->data.vorbis_comment.vendor_string)) { | ||
476 | FLAC__metadata_object_delete(to); | ||
477 | return 0; | ||
478 | } | ||
479 | if(object->data.vorbis_comment.num_comments == 0) { | ||
480 | FLAC__ASSERT(0 == object->data.vorbis_comment.comments); | ||
481 | to->data.vorbis_comment.comments = 0; | ||
482 | } | ||
483 | else { | ||
484 | FLAC__ASSERT(0 != object->data.vorbis_comment.comments); | ||
485 | to->data.vorbis_comment.comments = vorbiscomment_entry_array_copy_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments); | ||
486 | if(0 == to->data.vorbis_comment.comments) { | ||
487 | FLAC__metadata_object_delete(to); | ||
488 | return 0; | ||
489 | } | ||
490 | } | ||
491 | to->data.vorbis_comment.num_comments = object->data.vorbis_comment.num_comments; | ||
492 | break; | ||
493 | case FLAC__METADATA_TYPE_CUESHEET: | ||
494 | memcpy(&to->data.cue_sheet, &object->data.cue_sheet, sizeof(FLAC__StreamMetadata_CueSheet)); | ||
495 | if(object->data.cue_sheet.num_tracks == 0) { | ||
496 | FLAC__ASSERT(0 == object->data.cue_sheet.tracks); | ||
497 | } | ||
498 | else { | ||
499 | FLAC__ASSERT(0 != object->data.cue_sheet.tracks); | ||
500 | to->data.cue_sheet.tracks = cuesheet_track_array_copy_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks); | ||
501 | if(0 == to->data.cue_sheet.tracks) { | ||
502 | FLAC__metadata_object_delete(to); | ||
503 | return 0; | ||
504 | } | ||
505 | } | ||
506 | break; | ||
507 | default: | ||
508 | if(!copy_bytes_(&to->data.unknown.data, object->data.unknown.data, object->length)) { | ||
509 | FLAC__metadata_object_delete(to); | ||
510 | return 0; | ||
511 | } | ||
512 | break; | ||
513 | } | ||
514 | } | ||
515 | |||
516 | return to; | ||
517 | } | ||
518 | |||
519 | void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object) | ||
520 | { | ||
521 | FLAC__ASSERT(0 != object); | ||
522 | |||
523 | switch(object->type) { | ||
524 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
525 | case FLAC__METADATA_TYPE_PADDING: | ||
526 | break; | ||
527 | case FLAC__METADATA_TYPE_APPLICATION: | ||
528 | if(0 != object->data.application.data) { | ||
529 | free(object->data.application.data); | ||
530 | object->data.application.data = 0; | ||
531 | } | ||
532 | break; | ||
533 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
534 | if(0 != object->data.seek_table.points) { | ||
535 | free(object->data.seek_table.points); | ||
536 | object->data.seek_table.points = 0; | ||
537 | } | ||
538 | break; | ||
539 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
540 | if(0 != object->data.vorbis_comment.vendor_string.entry) { | ||
541 | free(object->data.vorbis_comment.vendor_string.entry); | ||
542 | object->data.vorbis_comment.vendor_string.entry = 0; | ||
543 | } | ||
544 | if(0 != object->data.vorbis_comment.comments) { | ||
545 | FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0); | ||
546 | vorbiscomment_entry_array_delete_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments); | ||
547 | } | ||
548 | break; | ||
549 | case FLAC__METADATA_TYPE_CUESHEET: | ||
550 | if(0 != object->data.cue_sheet.tracks) { | ||
551 | FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0); | ||
552 | cuesheet_track_array_delete_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks); | ||
553 | } | ||
554 | break; | ||
555 | default: | ||
556 | if(0 != object->data.unknown.data) { | ||
557 | free(object->data.unknown.data); | ||
558 | object->data.unknown.data = 0; | ||
559 | } | ||
560 | break; | ||
561 | } | ||
562 | } | ||
563 | |||
564 | FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object) | ||
565 | { | ||
566 | FLAC__metadata_object_delete_data(object); | ||
567 | free(object); | ||
568 | } | ||
569 | |||
570 | static FLAC__bool compare_block_data_streaminfo_(const FLAC__StreamMetadata_StreamInfo *block1, const FLAC__StreamMetadata_StreamInfo *block2) | ||
571 | { | ||
572 | if(block1->min_blocksize != block2->min_blocksize) | ||
573 | return false; | ||
574 | if(block1->max_blocksize != block2->max_blocksize) | ||
575 | return false; | ||
576 | if(block1->min_framesize != block2->min_framesize) | ||
577 | return false; | ||
578 | if(block1->max_framesize != block2->max_framesize) | ||
579 | return false; | ||
580 | if(block1->sample_rate != block2->sample_rate) | ||
581 | return false; | ||
582 | if(block1->channels != block2->channels) | ||
583 | return false; | ||
584 | if(block1->bits_per_sample != block2->bits_per_sample) | ||
585 | return false; | ||
586 | if(block1->total_samples != block2->total_samples) | ||
587 | return false; | ||
588 | if(0 != memcmp(block1->md5sum, block2->md5sum, 16)) | ||
589 | return false; | ||
590 | return true; | ||
591 | } | ||
592 | |||
593 | static FLAC__bool compare_block_data_application_(const FLAC__StreamMetadata_Application *block1, const FLAC__StreamMetadata_Application *block2, unsigned block_length) | ||
594 | { | ||
595 | FLAC__ASSERT(0 != block1); | ||
596 | FLAC__ASSERT(0 != block2); | ||
597 | FLAC__ASSERT(block_length >= sizeof(block1->id)); | ||
598 | |||
599 | if(0 != memcmp(block1->id, block2->id, sizeof(block1->id))) | ||
600 | return false; | ||
601 | if(0 != block1->data && 0 != block2->data) | ||
602 | return 0 == memcmp(block1->data, block2->data, block_length - sizeof(block1->id)); | ||
603 | else | ||
604 | return block1->data == block2->data; | ||
605 | } | ||
606 | |||
607 | static FLAC__bool compare_block_data_seektable_(const FLAC__StreamMetadata_SeekTable *block1, const FLAC__StreamMetadata_SeekTable *block2) | ||
608 | { | ||
609 | unsigned i; | ||
610 | |||
611 | FLAC__ASSERT(0 != block1); | ||
612 | FLAC__ASSERT(0 != block2); | ||
613 | |||
614 | if(block1->num_points != block2->num_points) | ||
615 | return false; | ||
616 | |||
617 | if(0 != block1->points && 0 != block2->points) { | ||
618 | for(i = 0; i < block1->num_points; i++) { | ||
619 | if(block1->points[i].sample_number != block2->points[i].sample_number) | ||
620 | return false; | ||
621 | if(block1->points[i].stream_offset != block2->points[i].stream_offset) | ||
622 | return false; | ||
623 | if(block1->points[i].frame_samples != block2->points[i].frame_samples) | ||
624 | return false; | ||
625 | } | ||
626 | return true; | ||
627 | } | ||
628 | else | ||
629 | return block1->points == block2->points; | ||
630 | } | ||
631 | |||
632 | static FLAC__bool compare_block_data_vorbiscomment_(const FLAC__StreamMetadata_VorbisComment *block1, const FLAC__StreamMetadata_VorbisComment *block2) | ||
633 | { | ||
634 | unsigned i; | ||
635 | |||
636 | if(block1->vendor_string.length != block2->vendor_string.length) | ||
637 | return false; | ||
638 | |||
639 | if(0 != block1->vendor_string.entry && 0 != block2->vendor_string.entry) { | ||
640 | if(0 != memcmp(block1->vendor_string.entry, block2->vendor_string.entry, block1->vendor_string.length)) | ||
641 | return false; | ||
642 | } | ||
643 | else if(block1->vendor_string.entry != block2->vendor_string.entry) | ||
644 | return false; | ||
645 | |||
646 | if(block1->num_comments != block2->num_comments) | ||
647 | return false; | ||
648 | |||
649 | for(i = 0; i < block1->num_comments; i++) { | ||
650 | if(0 != block1->comments[i].entry && 0 != block2->comments[i].entry) { | ||
651 | if(0 != memcmp(block1->comments[i].entry, block2->comments[i].entry, block1->comments[i].length)) | ||
652 | return false; | ||
653 | } | ||
654 | else if(block1->comments[i].entry != block2->comments[i].entry) | ||
655 | return false; | ||
656 | } | ||
657 | return true; | ||
658 | } | ||
659 | |||
660 | static FLAC__bool compare_block_data_cuesheet_(const FLAC__StreamMetadata_CueSheet *block1, const FLAC__StreamMetadata_CueSheet *block2) | ||
661 | { | ||
662 | unsigned i, j; | ||
663 | |||
664 | if(0 != strcmp(block1->media_catalog_number, block2->media_catalog_number)) | ||
665 | return false; | ||
666 | |||
667 | if(block1->lead_in != block2->lead_in) | ||
668 | return false; | ||
669 | |||
670 | if(block1->is_cd != block2->is_cd) | ||
671 | return false; | ||
672 | |||
673 | if(block1->num_tracks != block2->num_tracks) | ||
674 | return false; | ||
675 | |||
676 | if(0 != block1->tracks && 0 != block2->tracks) { | ||
677 | FLAC__ASSERT(block1->num_tracks > 0); | ||
678 | for(i = 0; i < block1->num_tracks; i++) { | ||
679 | if(block1->tracks[i].offset != block2->tracks[i].offset) | ||
680 | return false; | ||
681 | if(block1->tracks[i].number != block2->tracks[i].number) | ||
682 | return false; | ||
683 | if(0 != memcmp(block1->tracks[i].isrc, block2->tracks[i].isrc, sizeof(block1->tracks[i].isrc))) | ||
684 | return false; | ||
685 | if(block1->tracks[i].type != block2->tracks[i].type) | ||
686 | return false; | ||
687 | if(block1->tracks[i].pre_emphasis != block2->tracks[i].pre_emphasis) | ||
688 | return false; | ||
689 | if(block1->tracks[i].num_indices != block2->tracks[i].num_indices) | ||
690 | return false; | ||
691 | if(0 != block1->tracks[i].indices && 0 != block2->tracks[i].indices) { | ||
692 | FLAC__ASSERT(block1->tracks[i].num_indices > 0); | ||
693 | for(j = 0; j < block1->tracks[i].num_indices; j++) { | ||
694 | if(block1->tracks[i].indices[j].offset != block2->tracks[i].indices[j].offset) | ||
695 | return false; | ||
696 | if(block1->tracks[i].indices[j].number != block2->tracks[i].indices[j].number) | ||
697 | return false; | ||
698 | } | ||
699 | } | ||
700 | else if(block1->tracks[i].indices != block2->tracks[i].indices) | ||
701 | return false; | ||
702 | } | ||
703 | } | ||
704 | else if(block1->tracks != block2->tracks) | ||
705 | return false; | ||
706 | return true; | ||
707 | } | ||
708 | |||
709 | static FLAC__bool compare_block_data_unknown_(const FLAC__StreamMetadata_Unknown *block1, const FLAC__StreamMetadata_Unknown *block2, unsigned block_length) | ||
710 | { | ||
711 | FLAC__ASSERT(0 != block1); | ||
712 | FLAC__ASSERT(0 != block2); | ||
713 | |||
714 | if(0 != block1->data && 0 != block2->data) | ||
715 | return 0 == memcmp(block1->data, block2->data, block_length); | ||
716 | else | ||
717 | return block1->data == block2->data; | ||
718 | } | ||
719 | |||
720 | FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2) | ||
721 | { | ||
722 | FLAC__ASSERT(0 != block1); | ||
723 | FLAC__ASSERT(0 != block2); | ||
724 | |||
725 | if(block1->type != block2->type) { | ||
726 | return false; | ||
727 | } | ||
728 | if(block1->is_last != block2->is_last) { | ||
729 | return false; | ||
730 | } | ||
731 | if(block1->length != block2->length) { | ||
732 | return false; | ||
733 | } | ||
734 | switch(block1->type) { | ||
735 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
736 | return compare_block_data_streaminfo_(&block1->data.stream_info, &block2->data.stream_info); | ||
737 | case FLAC__METADATA_TYPE_PADDING: | ||
738 | return true; /* we don't compare the padding guts */ | ||
739 | case FLAC__METADATA_TYPE_APPLICATION: | ||
740 | return compare_block_data_application_(&block1->data.application, &block2->data.application, block1->length); | ||
741 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
742 | return compare_block_data_seektable_(&block1->data.seek_table, &block2->data.seek_table); | ||
743 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
744 | return compare_block_data_vorbiscomment_(&block1->data.vorbis_comment, &block2->data.vorbis_comment); | ||
745 | case FLAC__METADATA_TYPE_CUESHEET: | ||
746 | return compare_block_data_cuesheet_(&block1->data.cue_sheet, &block2->data.cue_sheet); | ||
747 | default: | ||
748 | return compare_block_data_unknown_(&block1->data.unknown, &block2->data.unknown, block1->length); | ||
749 | } | ||
750 | } | ||
751 | |||
752 | FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy) | ||
753 | { | ||
754 | FLAC__byte *save; | ||
755 | |||
756 | FLAC__ASSERT(0 != object); | ||
757 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_APPLICATION); | ||
758 | FLAC__ASSERT((0 != data && length > 0) || (0 == data && length == 0 && copy == false)); | ||
759 | |||
760 | save = object->data.application.data; | ||
761 | |||
762 | /* do the copy first so that if we fail we leave the object untouched */ | ||
763 | if(copy) { | ||
764 | if(!copy_bytes_(&object->data.application.data, data, length)) | ||
765 | return false; | ||
766 | } | ||
767 | else { | ||
768 | object->data.application.data = data; | ||
769 | } | ||
770 | |||
771 | if(0 != save) | ||
772 | free(save); | ||
773 | |||
774 | object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8 + length; | ||
775 | return true; | ||
776 | } | ||
777 | |||
778 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points) | ||
779 | { | ||
780 | FLAC__ASSERT(0 != object); | ||
781 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
782 | |||
783 | if(0 == object->data.seek_table.points) { | ||
784 | FLAC__ASSERT(object->data.seek_table.num_points == 0); | ||
785 | if(0 == new_num_points) | ||
786 | return true; | ||
787 | else if(0 == (object->data.seek_table.points = seekpoint_array_new_(new_num_points))) | ||
788 | return false; | ||
789 | } | ||
790 | else { | ||
791 | const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint); | ||
792 | const unsigned new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint); | ||
793 | |||
794 | FLAC__ASSERT(object->data.seek_table.num_points > 0); | ||
795 | |||
796 | if(new_size == 0) { | ||
797 | free(object->data.seek_table.points); | ||
798 | object->data.seek_table.points = 0; | ||
799 | } | ||
800 | else if(0 == (object->data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(object->data.seek_table.points, new_size))) | ||
801 | return false; | ||
802 | |||
803 | /* if growing, set new elements to placeholders */ | ||
804 | if(new_size > old_size) { | ||
805 | unsigned i; | ||
806 | for(i = object->data.seek_table.num_points; i < new_num_points; i++) { | ||
807 | object->data.seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | ||
808 | object->data.seek_table.points[i].stream_offset = 0; | ||
809 | object->data.seek_table.points[i].frame_samples = 0; | ||
810 | } | ||
811 | } | ||
812 | } | ||
813 | |||
814 | object->data.seek_table.num_points = new_num_points; | ||
815 | |||
816 | seektable_calculate_length_(object); | ||
817 | return true; | ||
818 | } | ||
819 | |||
820 | FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point) | ||
821 | { | ||
822 | FLAC__ASSERT(0 != object); | ||
823 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
824 | FLAC__ASSERT(point_num < object->data.seek_table.num_points); | ||
825 | |||
826 | object->data.seek_table.points[point_num] = point; | ||
827 | } | ||
828 | |||
829 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point) | ||
830 | { | ||
831 | int i; | ||
832 | |||
833 | FLAC__ASSERT(0 != object); | ||
834 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
835 | FLAC__ASSERT(point_num <= object->data.seek_table.num_points); | ||
836 | |||
837 | if(!FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points+1)) | ||
838 | return false; | ||
839 | |||
840 | /* move all points >= point_num forward one space */ | ||
841 | for(i = (int)object->data.seek_table.num_points-1; i > (int)point_num; i--) | ||
842 | object->data.seek_table.points[i] = object->data.seek_table.points[i-1]; | ||
843 | |||
844 | FLAC__metadata_object_seektable_set_point(object, point_num, point); | ||
845 | seektable_calculate_length_(object); | ||
846 | return true; | ||
847 | } | ||
848 | |||
849 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num) | ||
850 | { | ||
851 | unsigned i; | ||
852 | |||
853 | FLAC__ASSERT(0 != object); | ||
854 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
855 | FLAC__ASSERT(point_num < object->data.seek_table.num_points); | ||
856 | |||
857 | /* move all points > point_num backward one space */ | ||
858 | for(i = point_num; i < object->data.seek_table.num_points-1; i++) | ||
859 | object->data.seek_table.points[i] = object->data.seek_table.points[i+1]; | ||
860 | |||
861 | return FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points-1); | ||
862 | } | ||
863 | |||
864 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object) | ||
865 | { | ||
866 | FLAC__ASSERT(0 != object); | ||
867 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
868 | |||
869 | return FLAC__format_seektable_is_legal(&object->data.seek_table); | ||
870 | } | ||
871 | |||
872 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num) | ||
873 | { | ||
874 | FLAC__ASSERT(0 != object); | ||
875 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
876 | |||
877 | if(num > 0) | ||
878 | /* WATCHOUT: we rely on the fact that growing the array adds PLACEHOLDERS at the end */ | ||
879 | return FLAC__metadata_object_seektable_resize_points(object, object->data.seek_table.num_points + num); | ||
880 | else | ||
881 | return true; | ||
882 | } | ||
883 | |||
884 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number) | ||
885 | { | ||
886 | FLAC__StreamMetadata_SeekTable *seek_table; | ||
887 | |||
888 | FLAC__ASSERT(0 != object); | ||
889 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
890 | |||
891 | seek_table = &object->data.seek_table; | ||
892 | |||
893 | if(!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + 1)) | ||
894 | return false; | ||
895 | |||
896 | seek_table->points[seek_table->num_points - 1].sample_number = sample_number; | ||
897 | seek_table->points[seek_table->num_points - 1].stream_offset = 0; | ||
898 | seek_table->points[seek_table->num_points - 1].frame_samples = 0; | ||
899 | |||
900 | return true; | ||
901 | } | ||
902 | |||
903 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num) | ||
904 | { | ||
905 | FLAC__ASSERT(0 != object); | ||
906 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
907 | FLAC__ASSERT(0 != sample_numbers || num == 0); | ||
908 | |||
909 | if(num > 0) { | ||
910 | FLAC__StreamMetadata_SeekTable *seek_table = &object->data.seek_table; | ||
911 | unsigned i, j; | ||
912 | |||
913 | i = seek_table->num_points; | ||
914 | |||
915 | if(!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + num)) | ||
916 | return false; | ||
917 | |||
918 | for(j = 0; j < num; i++, j++) { | ||
919 | seek_table->points[i].sample_number = sample_numbers[j]; | ||
920 | seek_table->points[i].stream_offset = 0; | ||
921 | seek_table->points[i].frame_samples = 0; | ||
922 | } | ||
923 | } | ||
924 | |||
925 | return true; | ||
926 | } | ||
927 | |||
928 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples) | ||
929 | { | ||
930 | FLAC__ASSERT(0 != object); | ||
931 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
932 | FLAC__ASSERT(total_samples > 0); | ||
933 | |||
934 | if(num > 0) { | ||
935 | FLAC__StreamMetadata_SeekTable *seek_table = &object->data.seek_table; | ||
936 | unsigned i, j; | ||
937 | |||
938 | i = seek_table->num_points; | ||
939 | |||
940 | if(!FLAC__metadata_object_seektable_resize_points(object, seek_table->num_points + num)) | ||
941 | return false; | ||
942 | |||
943 | for(j = 0; j < num; i++, j++) { | ||
944 | seek_table->points[i].sample_number = total_samples * (FLAC__uint64)j / (FLAC__uint64)num; | ||
945 | seek_table->points[i].stream_offset = 0; | ||
946 | seek_table->points[i].frame_samples = 0; | ||
947 | } | ||
948 | } | ||
949 | |||
950 | return true; | ||
951 | } | ||
952 | |||
953 | FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact) | ||
954 | { | ||
955 | unsigned unique; | ||
956 | |||
957 | FLAC__ASSERT(0 != object); | ||
958 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_SEEKTABLE); | ||
959 | |||
960 | unique = FLAC__format_seektable_sort(&object->data.seek_table); | ||
961 | |||
962 | return !compact || FLAC__metadata_object_seektable_resize_points(object, unique); | ||
963 | } | ||
964 | |||
965 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) | ||
966 | { | ||
967 | if(!FLAC__format_vorbiscomment_entry_value_is_legal(entry.entry, entry.length)) | ||
968 | return false; | ||
969 | return vorbiscomment_set_entry_(object, &object->data.vorbis_comment.vendor_string, &entry, copy); | ||
970 | } | ||
971 | |||
972 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments) | ||
973 | { | ||
974 | FLAC__ASSERT(0 != object); | ||
975 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
976 | |||
977 | if(0 == object->data.vorbis_comment.comments) { | ||
978 | FLAC__ASSERT(object->data.vorbis_comment.num_comments == 0); | ||
979 | if(0 == new_num_comments) | ||
980 | return true; | ||
981 | else if(0 == (object->data.vorbis_comment.comments = vorbiscomment_entry_array_new_(new_num_comments))) | ||
982 | return false; | ||
983 | } | ||
984 | else { | ||
985 | const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); | ||
986 | const unsigned new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry); | ||
987 | |||
988 | FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0); | ||
989 | |||
990 | /* if shrinking, free the truncated entries */ | ||
991 | if(new_num_comments < object->data.vorbis_comment.num_comments) { | ||
992 | unsigned i; | ||
993 | for(i = new_num_comments; i < object->data.vorbis_comment.num_comments; i++) | ||
994 | if(0 != object->data.vorbis_comment.comments[i].entry) | ||
995 | free(object->data.vorbis_comment.comments[i].entry); | ||
996 | } | ||
997 | |||
998 | if(new_size == 0) { | ||
999 | free(object->data.vorbis_comment.comments); | ||
1000 | object->data.vorbis_comment.comments = 0; | ||
1001 | } | ||
1002 | else if(0 == (object->data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)realloc(object->data.vorbis_comment.comments, new_size))) | ||
1003 | return false; | ||
1004 | |||
1005 | /* if growing, zero all the length/pointers of new elements */ | ||
1006 | if(new_size > old_size) | ||
1007 | memset(object->data.vorbis_comment.comments + object->data.vorbis_comment.num_comments, 0, new_size - old_size); | ||
1008 | } | ||
1009 | |||
1010 | object->data.vorbis_comment.num_comments = new_num_comments; | ||
1011 | |||
1012 | vorbiscomment_calculate_length_(object); | ||
1013 | return true; | ||
1014 | } | ||
1015 | |||
1016 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) | ||
1017 | { | ||
1018 | FLAC__ASSERT(0 != object); | ||
1019 | FLAC__ASSERT(comment_num < object->data.vorbis_comment.num_comments); | ||
1020 | |||
1021 | if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) | ||
1022 | return false; | ||
1023 | return vorbiscomment_set_entry_(object, &object->data.vorbis_comment.comments[comment_num], &entry, copy); | ||
1024 | } | ||
1025 | |||
1026 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) | ||
1027 | { | ||
1028 | FLAC__StreamMetadata_VorbisComment *vc; | ||
1029 | |||
1030 | FLAC__ASSERT(0 != object); | ||
1031 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
1032 | FLAC__ASSERT(comment_num <= object->data.vorbis_comment.num_comments); | ||
1033 | |||
1034 | if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) | ||
1035 | return false; | ||
1036 | |||
1037 | vc = &object->data.vorbis_comment; | ||
1038 | |||
1039 | if(!FLAC__metadata_object_vorbiscomment_resize_comments(object, vc->num_comments+1)) | ||
1040 | return false; | ||
1041 | |||
1042 | /* move all comments >= comment_num forward one space */ | ||
1043 | memmove(&vc->comments[comment_num+1], &vc->comments[comment_num], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(vc->num_comments-1-comment_num)); | ||
1044 | vc->comments[comment_num].length = 0; | ||
1045 | vc->comments[comment_num].entry = 0; | ||
1046 | |||
1047 | return FLAC__metadata_object_vorbiscomment_set_comment(object, comment_num, entry, copy); | ||
1048 | } | ||
1049 | |||
1050 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy) | ||
1051 | { | ||
1052 | FLAC__ASSERT(0 != object); | ||
1053 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
1054 | return FLAC__metadata_object_vorbiscomment_insert_comment(object, object->data.vorbis_comment.num_comments, entry, copy); | ||
1055 | } | ||
1056 | |||
1057 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy) | ||
1058 | { | ||
1059 | FLAC__ASSERT(0 != entry.entry && entry.length > 0); | ||
1060 | |||
1061 | if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) | ||
1062 | return false; | ||
1063 | |||
1064 | { | ||
1065 | int i; | ||
1066 | unsigned field_name_length; | ||
1067 | const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); | ||
1068 | |||
1069 | FLAC__ASSERT(0 != eq); | ||
1070 | |||
1071 | if(0 == eq) | ||
1072 | return false; /* double protection */ | ||
1073 | |||
1074 | field_name_length = eq-entry.entry; | ||
1075 | |||
1076 | if((i = vorbiscomment_find_entry_from_(object, 0, entry.entry, field_name_length)) >= 0) { | ||
1077 | unsigned index = (unsigned)i; | ||
1078 | if(!FLAC__metadata_object_vorbiscomment_set_comment(object, index, entry, copy)) | ||
1079 | return false; | ||
1080 | if(all && (index+1 < object->data.vorbis_comment.num_comments)) { | ||
1081 | for(i = vorbiscomment_find_entry_from_(object, index+1, entry.entry, field_name_length); i >= 0; ) { | ||
1082 | if(!FLAC__metadata_object_vorbiscomment_delete_comment(object, (unsigned)i)) | ||
1083 | return false; | ||
1084 | if((unsigned)i < object->data.vorbis_comment.num_comments) | ||
1085 | i = vorbiscomment_find_entry_from_(object, (unsigned)i, entry.entry, field_name_length); | ||
1086 | else | ||
1087 | i = -1; | ||
1088 | } | ||
1089 | } | ||
1090 | return true; | ||
1091 | } | ||
1092 | else | ||
1093 | return FLAC__metadata_object_vorbiscomment_append_comment(object, entry, copy); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num) | ||
1098 | { | ||
1099 | FLAC__StreamMetadata_VorbisComment *vc; | ||
1100 | |||
1101 | FLAC__ASSERT(0 != object); | ||
1102 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
1103 | FLAC__ASSERT(comment_num < object->data.vorbis_comment.num_comments); | ||
1104 | |||
1105 | vc = &object->data.vorbis_comment; | ||
1106 | |||
1107 | /* free the comment at comment_num */ | ||
1108 | if(0 != vc->comments[comment_num].entry) | ||
1109 | free(vc->comments[comment_num].entry); | ||
1110 | |||
1111 | /* move all comments > comment_num backward one space */ | ||
1112 | memmove(&vc->comments[comment_num], &vc->comments[comment_num+1], sizeof(FLAC__StreamMetadata_VorbisComment_Entry)*(vc->num_comments-comment_num-1)); | ||
1113 | vc->comments[vc->num_comments-1].length = 0; | ||
1114 | vc->comments[vc->num_comments-1].entry = 0; | ||
1115 | |||
1116 | return FLAC__metadata_object_vorbiscomment_resize_comments(object, vc->num_comments-1); | ||
1117 | } | ||
1118 | |||
1119 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value) | ||
1120 | { | ||
1121 | FLAC__ASSERT(0 != entry); | ||
1122 | FLAC__ASSERT(0 != field_name); | ||
1123 | FLAC__ASSERT(0 != field_value); | ||
1124 | |||
1125 | if(!FLAC__format_vorbiscomment_entry_name_is_legal(field_name)) | ||
1126 | return false; | ||
1127 | if(!FLAC__format_vorbiscomment_entry_value_is_legal(field_value, (unsigned)(-1))) | ||
1128 | return false; | ||
1129 | |||
1130 | { | ||
1131 | const size_t nn = strlen(field_name); | ||
1132 | const size_t nv = strlen(field_value); | ||
1133 | entry->length = nn + 1 /*=*/ + nv; | ||
1134 | if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) | ||
1135 | return false; | ||
1136 | memcpy(entry->entry, field_name, nn); | ||
1137 | entry->entry[nn] = '='; | ||
1138 | memcpy(entry->entry+nn+1, field_value, nv); | ||
1139 | entry->entry[entry->length] = '\0'; | ||
1140 | } | ||
1141 | |||
1142 | return true; | ||
1143 | } | ||
1144 | |||
1145 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value) | ||
1146 | { | ||
1147 | FLAC__ASSERT(0 != entry.entry && entry.length > 0); | ||
1148 | FLAC__ASSERT(0 != field_name); | ||
1149 | FLAC__ASSERT(0 != field_value); | ||
1150 | |||
1151 | if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) | ||
1152 | return false; | ||
1153 | |||
1154 | { | ||
1155 | const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); | ||
1156 | const size_t nn = eq-entry.entry; | ||
1157 | const size_t nv = entry.length-nn-1; /* -1 for the '=' */ | ||
1158 | FLAC__ASSERT(0 != eq); | ||
1159 | if(0 == eq) | ||
1160 | return false; /* double protection */ | ||
1161 | if(0 == (*field_name = (char*)malloc(nn+1))) | ||
1162 | return false; | ||
1163 | if(0 == (*field_value = (char*)malloc(nv+1))) { | ||
1164 | free(*field_name); | ||
1165 | return false; | ||
1166 | } | ||
1167 | memcpy(*field_name, entry.entry, nn); | ||
1168 | memcpy(*field_value, entry.entry+nn+1, nv); | ||
1169 | (*field_name)[nn] = '\0'; | ||
1170 | (*field_value)[nv] = '\0'; | ||
1171 | } | ||
1172 | |||
1173 | return true; | ||
1174 | } | ||
1175 | |||
1176 | FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length) | ||
1177 | { | ||
1178 | FLAC__ASSERT(0 != entry.entry && entry.length > 0); | ||
1179 | { | ||
1180 | const FLAC__byte *eq = (FLAC__byte*)memchr(entry.entry, '=', entry.length); | ||
1181 | #if defined _MSC_VER || defined __MINGW32__ | ||
1182 | #define FLAC__STRNCASECMP strnicmp | ||
1183 | #else | ||
1184 | #define FLAC__STRNCASECMP strncasecmp | ||
1185 | #endif | ||
1186 | return (0 != eq && (unsigned)(eq-entry.entry) == field_name_length && 0 == FLAC__STRNCASECMP(field_name, (const char *)entry.entry, field_name_length)); | ||
1187 | #undef FLAC__STRNCASECMP | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name) | ||
1192 | { | ||
1193 | FLAC__ASSERT(0 != field_name); | ||
1194 | |||
1195 | return vorbiscomment_find_entry_from_(object, offset, field_name, strlen(field_name)); | ||
1196 | } | ||
1197 | |||
1198 | FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name) | ||
1199 | { | ||
1200 | const unsigned field_name_length = strlen(field_name); | ||
1201 | unsigned i; | ||
1202 | |||
1203 | FLAC__ASSERT(0 != object); | ||
1204 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
1205 | |||
1206 | for(i = 0; i < object->data.vorbis_comment.num_comments; i++) { | ||
1207 | if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) { | ||
1208 | if(!FLAC__metadata_object_vorbiscomment_delete_comment(object, i)) | ||
1209 | return -1; | ||
1210 | else | ||
1211 | return 1; | ||
1212 | } | ||
1213 | } | ||
1214 | |||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name) | ||
1219 | { | ||
1220 | FLAC__bool ok = true; | ||
1221 | unsigned matching = 0; | ||
1222 | const unsigned field_name_length = strlen(field_name); | ||
1223 | int i; | ||
1224 | |||
1225 | FLAC__ASSERT(0 != object); | ||
1226 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT); | ||
1227 | |||
1228 | /* must delete from end to start otherwise it will interfere with our iteration */ | ||
1229 | for(i = (int)object->data.vorbis_comment.num_comments - 1; ok && i >= 0; i--) { | ||
1230 | if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments[i], field_name, field_name_length)) { | ||
1231 | matching++; | ||
1232 | ok &= FLAC__metadata_object_vorbiscomment_delete_comment(object, (unsigned)i); | ||
1233 | } | ||
1234 | } | ||
1235 | |||
1236 | return ok? (int)matching : -1; | ||
1237 | } | ||
1238 | |||
1239 | FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new() | ||
1240 | { | ||
1241 | return (FLAC__StreamMetadata_CueSheet_Track*)calloc(1, sizeof(FLAC__StreamMetadata_CueSheet_Track)); | ||
1242 | } | ||
1243 | |||
1244 | FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object) | ||
1245 | { | ||
1246 | FLAC__StreamMetadata_CueSheet_Track *to; | ||
1247 | |||
1248 | FLAC__ASSERT(0 != object); | ||
1249 | |||
1250 | if(0 != (to = FLAC__metadata_object_cuesheet_track_new())) { | ||
1251 | if(!copy_track_(to, object)) { | ||
1252 | FLAC__metadata_object_cuesheet_track_delete(to); | ||
1253 | return 0; | ||
1254 | } | ||
1255 | } | ||
1256 | |||
1257 | return to; | ||
1258 | } | ||
1259 | |||
1260 | void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object) | ||
1261 | { | ||
1262 | FLAC__ASSERT(0 != object); | ||
1263 | |||
1264 | if(0 != object->indices) { | ||
1265 | FLAC__ASSERT(object->num_indices > 0); | ||
1266 | free(object->indices); | ||
1267 | } | ||
1268 | } | ||
1269 | |||
1270 | FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object) | ||
1271 | { | ||
1272 | FLAC__metadata_object_cuesheet_track_delete_data(object); | ||
1273 | free(object); | ||
1274 | } | ||
1275 | |||
1276 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices) | ||
1277 | { | ||
1278 | FLAC__StreamMetadata_CueSheet_Track *track; | ||
1279 | FLAC__ASSERT(0 != object); | ||
1280 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1281 | FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); | ||
1282 | |||
1283 | track = &object->data.cue_sheet.tracks[track_num]; | ||
1284 | |||
1285 | if(0 == track->indices) { | ||
1286 | FLAC__ASSERT(track->num_indices == 0); | ||
1287 | if(0 == new_num_indices) | ||
1288 | return true; | ||
1289 | else if(0 == (track->indices = cuesheet_track_index_array_new_(new_num_indices))) | ||
1290 | return false; | ||
1291 | } | ||
1292 | else { | ||
1293 | const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); | ||
1294 | const unsigned new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index); | ||
1295 | |||
1296 | FLAC__ASSERT(track->num_indices > 0); | ||
1297 | |||
1298 | if(new_size == 0) { | ||
1299 | free(track->indices); | ||
1300 | track->indices = 0; | ||
1301 | } | ||
1302 | else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)realloc(track->indices, new_size))) | ||
1303 | return false; | ||
1304 | |||
1305 | /* if growing, zero all the lengths/pointers of new elements */ | ||
1306 | if(new_size > old_size) | ||
1307 | memset(track->indices + track->num_indices, 0, new_size - old_size); | ||
1308 | } | ||
1309 | |||
1310 | track->num_indices = new_num_indices; | ||
1311 | |||
1312 | cuesheet_calculate_length_(object); | ||
1313 | return true; | ||
1314 | } | ||
1315 | |||
1316 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index) | ||
1317 | { | ||
1318 | FLAC__StreamMetadata_CueSheet_Track *track; | ||
1319 | |||
1320 | FLAC__ASSERT(0 != object); | ||
1321 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1322 | FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); | ||
1323 | FLAC__ASSERT(index_num <= object->data.cue_sheet.tracks[track_num].num_indices); | ||
1324 | |||
1325 | track = &object->data.cue_sheet.tracks[track_num]; | ||
1326 | |||
1327 | if(!FLAC__metadata_object_cuesheet_track_resize_indices(object, track_num, track->num_indices+1)) | ||
1328 | return false; | ||
1329 | |||
1330 | /* move all indices >= index_num forward one space */ | ||
1331 | memmove(&track->indices[index_num+1], &track->indices[index_num], sizeof(FLAC__StreamMetadata_CueSheet_Index)*(track->num_indices-1-index_num)); | ||
1332 | |||
1333 | track->indices[index_num] = index; | ||
1334 | cuesheet_calculate_length_(object); | ||
1335 | return true; | ||
1336 | } | ||
1337 | |||
1338 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num) | ||
1339 | { | ||
1340 | FLAC__StreamMetadata_CueSheet_Index index; | ||
1341 | memset(&index, 0, sizeof(index)); | ||
1342 | return FLAC__metadata_object_cuesheet_track_insert_index(object, track_num, index_num, index); | ||
1343 | } | ||
1344 | |||
1345 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num) | ||
1346 | { | ||
1347 | FLAC__StreamMetadata_CueSheet_Track *track; | ||
1348 | |||
1349 | FLAC__ASSERT(0 != object); | ||
1350 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1351 | FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); | ||
1352 | FLAC__ASSERT(index_num < object->data.cue_sheet.tracks[track_num].num_indices); | ||
1353 | |||
1354 | track = &object->data.cue_sheet.tracks[track_num]; | ||
1355 | |||
1356 | /* move all indices > index_num backward one space */ | ||
1357 | memmove(&track->indices[index_num], &track->indices[index_num+1], sizeof(FLAC__StreamMetadata_CueSheet_Index)*(track->num_indices-index_num-1)); | ||
1358 | |||
1359 | FLAC__metadata_object_cuesheet_track_resize_indices(object, track_num, track->num_indices-1); | ||
1360 | cuesheet_calculate_length_(object); | ||
1361 | return true; | ||
1362 | } | ||
1363 | |||
1364 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks) | ||
1365 | { | ||
1366 | FLAC__ASSERT(0 != object); | ||
1367 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1368 | |||
1369 | if(0 == object->data.cue_sheet.tracks) { | ||
1370 | FLAC__ASSERT(object->data.cue_sheet.num_tracks == 0); | ||
1371 | if(0 == new_num_tracks) | ||
1372 | return true; | ||
1373 | else if(0 == (object->data.cue_sheet.tracks = cuesheet_track_array_new_(new_num_tracks))) | ||
1374 | return false; | ||
1375 | } | ||
1376 | else { | ||
1377 | const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); | ||
1378 | const unsigned new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track); | ||
1379 | |||
1380 | FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0); | ||
1381 | |||
1382 | /* if shrinking, free the truncated entries */ | ||
1383 | if(new_num_tracks < object->data.cue_sheet.num_tracks) { | ||
1384 | unsigned i; | ||
1385 | for(i = new_num_tracks; i < object->data.cue_sheet.num_tracks; i++) | ||
1386 | if(0 != object->data.cue_sheet.tracks[i].indices) | ||
1387 | free(object->data.cue_sheet.tracks[i].indices); | ||
1388 | } | ||
1389 | |||
1390 | if(new_size == 0) { | ||
1391 | free(object->data.cue_sheet.tracks); | ||
1392 | object->data.cue_sheet.tracks = 0; | ||
1393 | } | ||
1394 | else if(0 == (object->data.cue_sheet.tracks = (FLAC__StreamMetadata_CueSheet_Track*)realloc(object->data.cue_sheet.tracks, new_size))) | ||
1395 | return false; | ||
1396 | |||
1397 | /* if growing, zero all the lengths/pointers of new elements */ | ||
1398 | if(new_size > old_size) | ||
1399 | memset(object->data.cue_sheet.tracks + object->data.cue_sheet.num_tracks, 0, new_size - old_size); | ||
1400 | } | ||
1401 | |||
1402 | object->data.cue_sheet.num_tracks = new_num_tracks; | ||
1403 | |||
1404 | cuesheet_calculate_length_(object); | ||
1405 | return true; | ||
1406 | } | ||
1407 | |||
1408 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy) | ||
1409 | { | ||
1410 | FLAC__ASSERT(0 != object); | ||
1411 | FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); | ||
1412 | |||
1413 | return cuesheet_set_track_(object, object->data.cue_sheet.tracks + track_num, track, copy); | ||
1414 | } | ||
1415 | |||
1416 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy) | ||
1417 | { | ||
1418 | FLAC__StreamMetadata_CueSheet *cs; | ||
1419 | |||
1420 | FLAC__ASSERT(0 != object); | ||
1421 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1422 | FLAC__ASSERT(track_num <= object->data.cue_sheet.num_tracks); | ||
1423 | |||
1424 | cs = &object->data.cue_sheet; | ||
1425 | |||
1426 | if(!FLAC__metadata_object_cuesheet_resize_tracks(object, cs->num_tracks+1)) | ||
1427 | return false; | ||
1428 | |||
1429 | /* move all tracks >= track_num forward one space */ | ||
1430 | memmove(&cs->tracks[track_num+1], &cs->tracks[track_num], sizeof(FLAC__StreamMetadata_CueSheet_Track)*(cs->num_tracks-1-track_num)); | ||
1431 | cs->tracks[track_num].num_indices = 0; | ||
1432 | cs->tracks[track_num].indices = 0; | ||
1433 | |||
1434 | return FLAC__metadata_object_cuesheet_set_track(object, track_num, track, copy); | ||
1435 | } | ||
1436 | |||
1437 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num) | ||
1438 | { | ||
1439 | FLAC__StreamMetadata_CueSheet_Track track; | ||
1440 | memset(&track, 0, sizeof(track)); | ||
1441 | return FLAC__metadata_object_cuesheet_insert_track(object, track_num, &track, /*copy=*/false); | ||
1442 | } | ||
1443 | |||
1444 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num) | ||
1445 | { | ||
1446 | FLAC__StreamMetadata_CueSheet *cs; | ||
1447 | |||
1448 | FLAC__ASSERT(0 != object); | ||
1449 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1450 | FLAC__ASSERT(track_num < object->data.cue_sheet.num_tracks); | ||
1451 | |||
1452 | cs = &object->data.cue_sheet; | ||
1453 | |||
1454 | /* free the track at track_num */ | ||
1455 | if(0 != cs->tracks[track_num].indices) | ||
1456 | free(cs->tracks[track_num].indices); | ||
1457 | |||
1458 | /* move all tracks > track_num backward one space */ | ||
1459 | memmove(&cs->tracks[track_num], &cs->tracks[track_num+1], sizeof(FLAC__StreamMetadata_CueSheet_Track)*(cs->num_tracks-track_num-1)); | ||
1460 | cs->tracks[cs->num_tracks-1].num_indices = 0; | ||
1461 | cs->tracks[cs->num_tracks-1].indices = 0; | ||
1462 | |||
1463 | return FLAC__metadata_object_cuesheet_resize_tracks(object, cs->num_tracks-1); | ||
1464 | } | ||
1465 | |||
1466 | FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation) | ||
1467 | { | ||
1468 | FLAC__ASSERT(0 != object); | ||
1469 | FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_CUESHEET); | ||
1470 | |||
1471 | return FLAC__format_cuesheet_is_legal(&object->data.cue_sheet, check_cd_da_subset, violation); | ||
1472 | } | ||
diff --git a/apps/codecs/libFLAC/seekable_stream_decoder.c b/apps/codecs/libFLAC/seekable_stream_decoder.c new file mode 100644 index 0000000000..2c899f20b3 --- /dev/null +++ b/apps/codecs/libFLAC/seekable_stream_decoder.c | |||
@@ -0,0 +1,1111 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for calloc() */ | ||
34 | #include <string.h> /* for memcpy()/memcmp() */ | ||
35 | #include "FLAC/assert.h" | ||
36 | #include "protected/seekable_stream_decoder.h" | ||
37 | #include "protected/stream_decoder.h" | ||
38 | #include "private/float.h" /* for FLAC__double */ | ||
39 | #include "private/md5.h" | ||
40 | |||
41 | /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | ||
42 | #ifdef _MSC_VER | ||
43 | #define FLAC__U64L(x) x | ||
44 | #else | ||
45 | #define FLAC__U64L(x) x##LLU | ||
46 | #endif | ||
47 | |||
48 | /*********************************************************************** | ||
49 | * | ||
50 | * Private class method prototypes | ||
51 | * | ||
52 | ***********************************************************************/ | ||
53 | |||
54 | static void set_defaults_(FLAC__SeekableStreamDecoder *decoder); | ||
55 | static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
56 | static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); | ||
57 | static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
58 | static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); | ||
59 | static FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample); | ||
60 | |||
61 | /*********************************************************************** | ||
62 | * | ||
63 | * Private class data | ||
64 | * | ||
65 | ***********************************************************************/ | ||
66 | |||
67 | typedef struct FLAC__SeekableStreamDecoderPrivate { | ||
68 | FLAC__SeekableStreamDecoderReadCallback read_callback; | ||
69 | FLAC__SeekableStreamDecoderSeekCallback seek_callback; | ||
70 | FLAC__SeekableStreamDecoderTellCallback tell_callback; | ||
71 | FLAC__SeekableStreamDecoderLengthCallback length_callback; | ||
72 | FLAC__SeekableStreamDecoderEofCallback eof_callback; | ||
73 | FLAC__SeekableStreamDecoderWriteCallback write_callback; | ||
74 | FLAC__SeekableStreamDecoderMetadataCallback metadata_callback; | ||
75 | FLAC__SeekableStreamDecoderErrorCallback error_callback; | ||
76 | void *client_data; | ||
77 | FLAC__StreamDecoder *stream_decoder; | ||
78 | FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek */ | ||
79 | struct FLAC__MD5Context md5context; | ||
80 | FLAC__byte stored_md5sum[16]; /* this is what is stored in the metadata */ | ||
81 | FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ | ||
82 | /* the rest of these are only used for seeking: */ | ||
83 | FLAC__StreamMetadata_StreamInfo stream_info; /* we keep this around so we can figure out how to seek quickly */ | ||
84 | const FLAC__StreamMetadata_SeekTable *seek_table; /* we hold a pointer to the stream decoder's seek table for the same reason */ | ||
85 | /* Since we always want to see the STREAMINFO and SEEK_TABLE blocks at this level, we need some extra flags to keep track of whether they should be passed on up through the metadata_callback */ | ||
86 | FLAC__bool ignore_stream_info_block; | ||
87 | FLAC__bool ignore_seek_table_block; | ||
88 | FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ | ||
89 | FLAC__uint64 target_sample; | ||
90 | } FLAC__SeekableStreamDecoderPrivate; | ||
91 | |||
92 | /*********************************************************************** | ||
93 | * | ||
94 | * Public static class data | ||
95 | * | ||
96 | ***********************************************************************/ | ||
97 | |||
98 | FLAC_API const char * const FLAC__SeekableStreamDecoderStateString[] = { | ||
99 | "FLAC__SEEKABLE_STREAM_DECODER_OK", | ||
100 | "FLAC__SEEKABLE_STREAM_DECODER_SEEKING", | ||
101 | "FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM", | ||
102 | "FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR", | ||
103 | "FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR", | ||
104 | "FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR", | ||
105 | "FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR", | ||
106 | "FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED", | ||
107 | "FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK", | ||
108 | "FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED" | ||
109 | }; | ||
110 | |||
111 | FLAC_API const char * const FLAC__SeekableStreamDecoderReadStatusString[] = { | ||
112 | "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK", | ||
113 | "FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR" | ||
114 | }; | ||
115 | |||
116 | FLAC_API const char * const FLAC__SeekableStreamDecoderSeekStatusString[] = { | ||
117 | "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK", | ||
118 | "FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR" | ||
119 | }; | ||
120 | |||
121 | FLAC_API const char * const FLAC__SeekableStreamDecoderTellStatusString[] = { | ||
122 | "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK", | ||
123 | "FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR" | ||
124 | }; | ||
125 | |||
126 | FLAC_API const char * const FLAC__SeekableStreamDecoderLengthStatusString[] = { | ||
127 | "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK", | ||
128 | "FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR" | ||
129 | }; | ||
130 | |||
131 | |||
132 | /*********************************************************************** | ||
133 | * | ||
134 | * Class constructor/destructor | ||
135 | * | ||
136 | ***********************************************************************/ | ||
137 | |||
138 | FLAC_API FLAC__SeekableStreamDecoder *FLAC__seekable_stream_decoder_new() | ||
139 | { | ||
140 | FLAC__SeekableStreamDecoder *decoder; | ||
141 | |||
142 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
143 | |||
144 | decoder = (FLAC__SeekableStreamDecoder*)calloc(1, sizeof(FLAC__SeekableStreamDecoder)); | ||
145 | if(decoder == 0) { | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | decoder->protected_ = (FLAC__SeekableStreamDecoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamDecoderProtected)); | ||
150 | if(decoder->protected_ == 0) { | ||
151 | free(decoder); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | decoder->private_ = (FLAC__SeekableStreamDecoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamDecoderPrivate)); | ||
156 | if(decoder->private_ == 0) { | ||
157 | free(decoder->protected_); | ||
158 | free(decoder); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | decoder->private_->stream_decoder = FLAC__stream_decoder_new(); | ||
163 | if(0 == decoder->private_->stream_decoder) { | ||
164 | free(decoder->private_); | ||
165 | free(decoder->protected_); | ||
166 | free(decoder); | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | set_defaults_(decoder); | ||
171 | |||
172 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED; | ||
173 | |||
174 | return decoder; | ||
175 | } | ||
176 | |||
177 | FLAC_API void FLAC__seekable_stream_decoder_delete(FLAC__SeekableStreamDecoder *decoder) | ||
178 | { | ||
179 | FLAC__ASSERT(0 != decoder); | ||
180 | FLAC__ASSERT(0 != decoder->protected_); | ||
181 | FLAC__ASSERT(0 != decoder->private_); | ||
182 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
183 | |||
184 | (void)FLAC__seekable_stream_decoder_finish(decoder); | ||
185 | |||
186 | FLAC__stream_decoder_delete(decoder->private_->stream_decoder); | ||
187 | |||
188 | free(decoder->private_); | ||
189 | free(decoder->protected_); | ||
190 | free(decoder); | ||
191 | } | ||
192 | |||
193 | /*********************************************************************** | ||
194 | * | ||
195 | * Public class methods | ||
196 | * | ||
197 | ***********************************************************************/ | ||
198 | |||
199 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_init(FLAC__SeekableStreamDecoder *decoder) | ||
200 | { | ||
201 | FLAC__ASSERT(0 != decoder); | ||
202 | |||
203 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
204 | return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED; | ||
205 | |||
206 | if(0 == decoder->private_->read_callback || 0 == decoder->private_->seek_callback || 0 == decoder->private_->tell_callback || 0 == decoder->private_->length_callback || 0 == decoder->private_->eof_callback) | ||
207 | return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK; | ||
208 | |||
209 | if(0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) | ||
210 | return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK; | ||
211 | |||
212 | decoder->private_->seek_table = 0; | ||
213 | |||
214 | decoder->private_->do_md5_checking = decoder->protected_->md5_checking; | ||
215 | |||
216 | /* We initialize the FLAC__MD5Context even though we may never use it. This | ||
217 | * is because md5 checking may be turned on to start and then turned off if | ||
218 | * a seek occurs. So we always init the context here and finalize it in | ||
219 | * FLAC__seekable_stream_decoder_finish() to make sure things are always | ||
220 | * cleaned up properly. | ||
221 | */ | ||
222 | FLAC__MD5Init(&decoder->private_->md5context); | ||
223 | |||
224 | FLAC__stream_decoder_set_read_callback(decoder->private_->stream_decoder, read_callback_); | ||
225 | FLAC__stream_decoder_set_write_callback(decoder->private_->stream_decoder, write_callback_); | ||
226 | FLAC__stream_decoder_set_metadata_callback(decoder->private_->stream_decoder, metadata_callback_); | ||
227 | FLAC__stream_decoder_set_error_callback(decoder->private_->stream_decoder, error_callback_); | ||
228 | FLAC__stream_decoder_set_client_data(decoder->private_->stream_decoder, decoder); | ||
229 | |||
230 | /* We always want to see these blocks. Whether or not we pass them up | ||
231 | * through the metadata callback will be determined by flags set in our | ||
232 | * implementation of ..._set_metadata_respond/ignore...() | ||
233 | */ | ||
234 | FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO); | ||
235 | FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE); | ||
236 | |||
237 | if(FLAC__stream_decoder_init(decoder->private_->stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) | ||
238 | return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
239 | |||
240 | return decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK; | ||
241 | } | ||
242 | |||
243 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_finish(FLAC__SeekableStreamDecoder *decoder) | ||
244 | { | ||
245 | FLAC__bool md5_failed = false; | ||
246 | |||
247 | FLAC__ASSERT(0 != decoder); | ||
248 | FLAC__ASSERT(0 != decoder->private_); | ||
249 | FLAC__ASSERT(0 != decoder->protected_); | ||
250 | |||
251 | if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
252 | return true; | ||
253 | |||
254 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
255 | |||
256 | /* see the comment in FLAC__seekable_stream_decoder_init() as to why we | ||
257 | * always call FLAC__MD5Final() | ||
258 | */ | ||
259 | FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); | ||
260 | |||
261 | FLAC__stream_decoder_finish(decoder->private_->stream_decoder); | ||
262 | |||
263 | if(decoder->private_->do_md5_checking) { | ||
264 | if(memcmp(decoder->private_->stored_md5sum, decoder->private_->computed_md5sum, 16)) | ||
265 | md5_failed = true; | ||
266 | } | ||
267 | |||
268 | set_defaults_(decoder); | ||
269 | |||
270 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED; | ||
271 | |||
272 | return !md5_failed; | ||
273 | } | ||
274 | |||
275 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_md5_checking(FLAC__SeekableStreamDecoder *decoder, FLAC__bool value) | ||
276 | { | ||
277 | FLAC__ASSERT(0 != decoder); | ||
278 | FLAC__ASSERT(0 != decoder->protected_); | ||
279 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
280 | return false; | ||
281 | decoder->protected_->md5_checking = value; | ||
282 | return true; | ||
283 | } | ||
284 | |||
285 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_read_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderReadCallback value) | ||
286 | { | ||
287 | FLAC__ASSERT(0 != decoder); | ||
288 | FLAC__ASSERT(0 != decoder->private_); | ||
289 | FLAC__ASSERT(0 != decoder->protected_); | ||
290 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
291 | return false; | ||
292 | decoder->private_->read_callback = value; | ||
293 | return true; | ||
294 | } | ||
295 | |||
296 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_seek_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderSeekCallback value) | ||
297 | { | ||
298 | FLAC__ASSERT(0 != decoder); | ||
299 | FLAC__ASSERT(0 != decoder->private_); | ||
300 | FLAC__ASSERT(0 != decoder->protected_); | ||
301 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
302 | return false; | ||
303 | decoder->private_->seek_callback = value; | ||
304 | return true; | ||
305 | } | ||
306 | |||
307 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_tell_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderTellCallback value) | ||
308 | { | ||
309 | FLAC__ASSERT(0 != decoder); | ||
310 | FLAC__ASSERT(0 != decoder->private_); | ||
311 | FLAC__ASSERT(0 != decoder->protected_); | ||
312 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
313 | return false; | ||
314 | decoder->private_->tell_callback = value; | ||
315 | return true; | ||
316 | } | ||
317 | |||
318 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_length_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderLengthCallback value) | ||
319 | { | ||
320 | FLAC__ASSERT(0 != decoder); | ||
321 | FLAC__ASSERT(0 != decoder->private_); | ||
322 | FLAC__ASSERT(0 != decoder->protected_); | ||
323 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
324 | return false; | ||
325 | decoder->private_->length_callback = value; | ||
326 | return true; | ||
327 | } | ||
328 | |||
329 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_eof_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderEofCallback value) | ||
330 | { | ||
331 | FLAC__ASSERT(0 != decoder); | ||
332 | FLAC__ASSERT(0 != decoder->private_); | ||
333 | FLAC__ASSERT(0 != decoder->protected_); | ||
334 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
335 | return false; | ||
336 | decoder->private_->eof_callback = value; | ||
337 | return true; | ||
338 | } | ||
339 | |||
340 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_write_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderWriteCallback value) | ||
341 | { | ||
342 | FLAC__ASSERT(0 != decoder); | ||
343 | FLAC__ASSERT(0 != decoder->private_); | ||
344 | FLAC__ASSERT(0 != decoder->protected_); | ||
345 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
346 | return false; | ||
347 | decoder->private_->write_callback = value; | ||
348 | return true; | ||
349 | } | ||
350 | |||
351 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderMetadataCallback value) | ||
352 | { | ||
353 | FLAC__ASSERT(0 != decoder); | ||
354 | FLAC__ASSERT(0 != decoder->private_); | ||
355 | FLAC__ASSERT(0 != decoder->protected_); | ||
356 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
357 | return false; | ||
358 | decoder->private_->metadata_callback = value; | ||
359 | return true; | ||
360 | } | ||
361 | |||
362 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_error_callback(FLAC__SeekableStreamDecoder *decoder, FLAC__SeekableStreamDecoderErrorCallback value) | ||
363 | { | ||
364 | FLAC__ASSERT(0 != decoder); | ||
365 | FLAC__ASSERT(0 != decoder->private_); | ||
366 | FLAC__ASSERT(0 != decoder->protected_); | ||
367 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
368 | return false; | ||
369 | decoder->private_->error_callback = value; | ||
370 | return true; | ||
371 | } | ||
372 | |||
373 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_client_data(FLAC__SeekableStreamDecoder *decoder, void *value) | ||
374 | { | ||
375 | FLAC__ASSERT(0 != decoder); | ||
376 | FLAC__ASSERT(0 != decoder->private_); | ||
377 | FLAC__ASSERT(0 != decoder->protected_); | ||
378 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
379 | return false; | ||
380 | decoder->private_->client_data = value; | ||
381 | return true; | ||
382 | } | ||
383 | |||
384 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type) | ||
385 | { | ||
386 | FLAC__ASSERT(0 != decoder); | ||
387 | FLAC__ASSERT(0 != decoder->private_); | ||
388 | FLAC__ASSERT(0 != decoder->protected_); | ||
389 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
390 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
391 | return false; | ||
392 | if(type == FLAC__METADATA_TYPE_STREAMINFO) | ||
393 | decoder->private_->ignore_stream_info_block = false; | ||
394 | else if(type == FLAC__METADATA_TYPE_SEEKTABLE) | ||
395 | decoder->private_->ignore_seek_table_block = false; | ||
396 | return FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, type); | ||
397 | } | ||
398 | |||
399 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4]) | ||
400 | { | ||
401 | FLAC__ASSERT(0 != decoder); | ||
402 | FLAC__ASSERT(0 != decoder->private_); | ||
403 | FLAC__ASSERT(0 != decoder->protected_); | ||
404 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
405 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
406 | return false; | ||
407 | return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->stream_decoder, id); | ||
408 | } | ||
409 | |||
410 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_respond_all(FLAC__SeekableStreamDecoder *decoder) | ||
411 | { | ||
412 | FLAC__ASSERT(0 != decoder); | ||
413 | FLAC__ASSERT(0 != decoder->private_); | ||
414 | FLAC__ASSERT(0 != decoder->protected_); | ||
415 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
416 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
417 | return false; | ||
418 | decoder->private_->ignore_stream_info_block = false; | ||
419 | decoder->private_->ignore_seek_table_block = false; | ||
420 | return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->stream_decoder); | ||
421 | } | ||
422 | |||
423 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore(FLAC__SeekableStreamDecoder *decoder, FLAC__MetadataType type) | ||
424 | { | ||
425 | FLAC__ASSERT(0 != decoder); | ||
426 | FLAC__ASSERT(0 != decoder->private_); | ||
427 | FLAC__ASSERT(0 != decoder->protected_); | ||
428 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
429 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
430 | return false; | ||
431 | if(type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
432 | decoder->private_->ignore_stream_info_block = true; | ||
433 | return true; | ||
434 | } | ||
435 | else if(type == FLAC__METADATA_TYPE_SEEKTABLE) { | ||
436 | decoder->private_->ignore_seek_table_block = true; | ||
437 | return true; | ||
438 | } | ||
439 | else | ||
440 | return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->stream_decoder, type); | ||
441 | } | ||
442 | |||
443 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_application(FLAC__SeekableStreamDecoder *decoder, const FLAC__byte id[4]) | ||
444 | { | ||
445 | FLAC__ASSERT(0 != decoder); | ||
446 | FLAC__ASSERT(0 != decoder->private_); | ||
447 | FLAC__ASSERT(0 != decoder->protected_); | ||
448 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
449 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
450 | return false; | ||
451 | return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->stream_decoder, id); | ||
452 | } | ||
453 | |||
454 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_set_metadata_ignore_all(FLAC__SeekableStreamDecoder *decoder) | ||
455 | { | ||
456 | FLAC__ASSERT(0 != decoder); | ||
457 | FLAC__ASSERT(0 != decoder->private_); | ||
458 | FLAC__ASSERT(0 != decoder->protected_); | ||
459 | FLAC__ASSERT(0 != decoder->private_->stream_decoder); | ||
460 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED) | ||
461 | return false; | ||
462 | decoder->private_->ignore_stream_info_block = true; | ||
463 | decoder->private_->ignore_seek_table_block = true; | ||
464 | return | ||
465 | FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->stream_decoder) && | ||
466 | FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_STREAMINFO) && | ||
467 | FLAC__stream_decoder_set_metadata_respond(decoder->private_->stream_decoder, FLAC__METADATA_TYPE_SEEKTABLE); | ||
468 | } | ||
469 | |||
470 | FLAC_API FLAC__SeekableStreamDecoderState FLAC__seekable_stream_decoder_get_state(const FLAC__SeekableStreamDecoder *decoder) | ||
471 | { | ||
472 | FLAC__ASSERT(0 != decoder); | ||
473 | FLAC__ASSERT(0 != decoder->protected_); | ||
474 | return decoder->protected_->state; | ||
475 | } | ||
476 | |||
477 | FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_decoder_get_stream_decoder_state(const FLAC__SeekableStreamDecoder *decoder) | ||
478 | { | ||
479 | FLAC__ASSERT(0 != decoder); | ||
480 | FLAC__ASSERT(0 != decoder->private_); | ||
481 | return FLAC__stream_decoder_get_state(decoder->private_->stream_decoder); | ||
482 | } | ||
483 | |||
484 | FLAC_API const char *FLAC__seekable_stream_decoder_get_resolved_state_string(const FLAC__SeekableStreamDecoder *decoder) | ||
485 | { | ||
486 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR) | ||
487 | return FLAC__SeekableStreamDecoderStateString[decoder->protected_->state]; | ||
488 | else | ||
489 | return FLAC__stream_decoder_get_resolved_state_string(decoder->private_->stream_decoder); | ||
490 | } | ||
491 | |||
492 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_md5_checking(const FLAC__SeekableStreamDecoder *decoder) | ||
493 | { | ||
494 | FLAC__ASSERT(0 != decoder); | ||
495 | FLAC__ASSERT(0 != decoder->protected_); | ||
496 | return decoder->protected_->md5_checking; | ||
497 | } | ||
498 | |||
499 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_channels(const FLAC__SeekableStreamDecoder *decoder) | ||
500 | { | ||
501 | FLAC__ASSERT(0 != decoder); | ||
502 | FLAC__ASSERT(0 != decoder->private_); | ||
503 | return FLAC__stream_decoder_get_channels(decoder->private_->stream_decoder); | ||
504 | } | ||
505 | |||
506 | FLAC_API FLAC__ChannelAssignment FLAC__seekable_stream_decoder_get_channel_assignment(const FLAC__SeekableStreamDecoder *decoder) | ||
507 | { | ||
508 | FLAC__ASSERT(0 != decoder); | ||
509 | FLAC__ASSERT(0 != decoder->private_); | ||
510 | return FLAC__stream_decoder_get_channel_assignment(decoder->private_->stream_decoder); | ||
511 | } | ||
512 | |||
513 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_bits_per_sample(const FLAC__SeekableStreamDecoder *decoder) | ||
514 | { | ||
515 | FLAC__ASSERT(0 != decoder); | ||
516 | FLAC__ASSERT(0 != decoder->private_); | ||
517 | return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->stream_decoder); | ||
518 | } | ||
519 | |||
520 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_sample_rate(const FLAC__SeekableStreamDecoder *decoder) | ||
521 | { | ||
522 | FLAC__ASSERT(0 != decoder); | ||
523 | FLAC__ASSERT(0 != decoder->private_); | ||
524 | return FLAC__stream_decoder_get_sample_rate(decoder->private_->stream_decoder); | ||
525 | } | ||
526 | |||
527 | FLAC_API unsigned FLAC__seekable_stream_decoder_get_blocksize(const FLAC__SeekableStreamDecoder *decoder) | ||
528 | { | ||
529 | FLAC__ASSERT(0 != decoder); | ||
530 | FLAC__ASSERT(0 != decoder->private_); | ||
531 | return FLAC__stream_decoder_get_blocksize(decoder->private_->stream_decoder); | ||
532 | } | ||
533 | |||
534 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_get_decode_position(const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position) | ||
535 | { | ||
536 | FLAC__ASSERT(0 != decoder); | ||
537 | FLAC__ASSERT(0 != decoder->private_); | ||
538 | FLAC__ASSERT(0 != position); | ||
539 | |||
540 | if(decoder->private_->tell_callback(decoder, position, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) | ||
541 | return false; | ||
542 | FLAC__ASSERT(*position >= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder)); | ||
543 | *position -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder); | ||
544 | return true; | ||
545 | } | ||
546 | |||
547 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_flush(FLAC__SeekableStreamDecoder *decoder) | ||
548 | { | ||
549 | FLAC__ASSERT(0 != decoder); | ||
550 | FLAC__ASSERT(0 != decoder->private_); | ||
551 | FLAC__ASSERT(0 != decoder->protected_); | ||
552 | |||
553 | decoder->private_->do_md5_checking = false; | ||
554 | |||
555 | if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) { | ||
556 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
557 | return false; | ||
558 | } | ||
559 | |||
560 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK; | ||
561 | |||
562 | return true; | ||
563 | } | ||
564 | |||
565 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_reset(FLAC__SeekableStreamDecoder *decoder) | ||
566 | { | ||
567 | FLAC__ASSERT(0 != decoder); | ||
568 | FLAC__ASSERT(0 != decoder->private_); | ||
569 | FLAC__ASSERT(0 != decoder->protected_); | ||
570 | |||
571 | if(!FLAC__seekable_stream_decoder_flush(decoder)) { | ||
572 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
573 | return false; | ||
574 | } | ||
575 | |||
576 | if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) { | ||
577 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
578 | return false; | ||
579 | } | ||
580 | |||
581 | decoder->private_->seek_table = 0; | ||
582 | |||
583 | decoder->private_->do_md5_checking = decoder->protected_->md5_checking; | ||
584 | |||
585 | /* We initialize the FLAC__MD5Context even though we may never use it. This | ||
586 | * is because md5 checking may be turned on to start and then turned off if | ||
587 | * a seek occurs. So we always init the context here and finalize it in | ||
588 | * FLAC__seekable_stream_decoder_finish() to make sure things are always | ||
589 | * cleaned up properly. | ||
590 | */ | ||
591 | FLAC__MD5Init(&decoder->private_->md5context); | ||
592 | |||
593 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK; | ||
594 | |||
595 | return true; | ||
596 | } | ||
597 | |||
598 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_single(FLAC__SeekableStreamDecoder *decoder) | ||
599 | { | ||
600 | FLAC__bool ret; | ||
601 | FLAC__ASSERT(0 != decoder); | ||
602 | |||
603 | if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) | ||
604 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
605 | |||
606 | if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
607 | return true; | ||
608 | |||
609 | FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK); | ||
610 | |||
611 | ret = FLAC__stream_decoder_process_single(decoder->private_->stream_decoder); | ||
612 | if(!ret) | ||
613 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
614 | |||
615 | return ret; | ||
616 | } | ||
617 | |||
618 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder) | ||
619 | { | ||
620 | FLAC__bool ret; | ||
621 | FLAC__ASSERT(0 != decoder); | ||
622 | |||
623 | if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) | ||
624 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
625 | |||
626 | if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
627 | return true; | ||
628 | |||
629 | FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK); | ||
630 | |||
631 | ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder); | ||
632 | if(!ret) | ||
633 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
634 | |||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_stream(FLAC__SeekableStreamDecoder *decoder) | ||
639 | { | ||
640 | FLAC__bool ret; | ||
641 | FLAC__ASSERT(0 != decoder); | ||
642 | |||
643 | if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) | ||
644 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
645 | |||
646 | if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
647 | return true; | ||
648 | |||
649 | FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK); | ||
650 | |||
651 | ret = FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->stream_decoder); | ||
652 | if(!ret) | ||
653 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
654 | |||
655 | return ret; | ||
656 | } | ||
657 | |||
658 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_skip_single_frame(FLAC__SeekableStreamDecoder *decoder) | ||
659 | { | ||
660 | FLAC__bool ret; | ||
661 | FLAC__ASSERT(0 != decoder); | ||
662 | |||
663 | if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) | ||
664 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
665 | |||
666 | if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) | ||
667 | return true; | ||
668 | |||
669 | FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK); | ||
670 | |||
671 | ret = FLAC__stream_decoder_skip_single_frame(decoder->private_->stream_decoder); | ||
672 | if(!ret) | ||
673 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
674 | |||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample) | ||
679 | { | ||
680 | FLAC__uint64 length; | ||
681 | |||
682 | FLAC__ASSERT(0 != decoder); | ||
683 | FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM); | ||
684 | |||
685 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEKING; | ||
686 | |||
687 | /* turn off md5 checking if a seek is attempted */ | ||
688 | decoder->private_->do_md5_checking = false; | ||
689 | |||
690 | if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) { | ||
691 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
692 | return false; | ||
693 | } | ||
694 | /* get the file length */ | ||
695 | if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) { | ||
696 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
697 | return false; | ||
698 | } | ||
699 | /* rewind */ | ||
700 | if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) { | ||
701 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
702 | return false; | ||
703 | } | ||
704 | if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) { | ||
705 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
706 | return false; | ||
707 | } | ||
708 | if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) { | ||
709 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
710 | return false; | ||
711 | } | ||
712 | |||
713 | return seek_to_absolute_sample_(decoder, length, sample); | ||
714 | } | ||
715 | |||
716 | /*********************************************************************** | ||
717 | * | ||
718 | * Private class methods | ||
719 | * | ||
720 | ***********************************************************************/ | ||
721 | |||
722 | void set_defaults_(FLAC__SeekableStreamDecoder *decoder) | ||
723 | { | ||
724 | decoder->private_->read_callback = 0; | ||
725 | decoder->private_->seek_callback = 0; | ||
726 | decoder->private_->tell_callback = 0; | ||
727 | decoder->private_->length_callback = 0; | ||
728 | decoder->private_->eof_callback = 0; | ||
729 | decoder->private_->write_callback = 0; | ||
730 | decoder->private_->metadata_callback = 0; | ||
731 | decoder->private_->error_callback = 0; | ||
732 | decoder->private_->client_data = 0; | ||
733 | /* WATCHOUT: these should match the default behavior of FLAC__StreamDecoder */ | ||
734 | decoder->private_->ignore_stream_info_block = false; | ||
735 | decoder->private_->ignore_seek_table_block = true; | ||
736 | |||
737 | decoder->protected_->md5_checking = false; | ||
738 | } | ||
739 | |||
740 | FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) | ||
741 | { | ||
742 | FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data; | ||
743 | (void)decoder; | ||
744 | if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) { | ||
745 | *bytes = 0; | ||
746 | #if 0 | ||
747 | /*@@@@@@ verify that this is not needed */ | ||
748 | seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
749 | #endif | ||
750 | return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; | ||
751 | } | ||
752 | else if(*bytes > 0) { | ||
753 | if(seekable_stream_decoder->private_->read_callback(seekable_stream_decoder, buffer, bytes, seekable_stream_decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK) { | ||
754 | seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR; | ||
755 | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; | ||
756 | } | ||
757 | if(*bytes == 0) { | ||
758 | if(seekable_stream_decoder->private_->eof_callback(seekable_stream_decoder, seekable_stream_decoder->private_->client_data)) { | ||
759 | #if 0 | ||
760 | /*@@@@@@ verify that this is not needed */ | ||
761 | seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; | ||
762 | #endif | ||
763 | return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; | ||
764 | } | ||
765 | else | ||
766 | return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; | ||
767 | } | ||
768 | else { | ||
769 | return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; | ||
770 | } | ||
771 | } | ||
772 | else | ||
773 | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ | ||
774 | } | ||
775 | |||
776 | FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) | ||
777 | { | ||
778 | FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data; | ||
779 | (void)decoder; | ||
780 | |||
781 | if(seekable_stream_decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_SEEKING) { | ||
782 | FLAC__uint64 this_frame_sample = frame->header.number.sample_number; | ||
783 | FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize; | ||
784 | FLAC__uint64 target_sample = seekable_stream_decoder->private_->target_sample; | ||
785 | |||
786 | FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); | ||
787 | |||
788 | seekable_stream_decoder->private_->last_frame = *frame; /* save the frame */ | ||
789 | if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */ | ||
790 | unsigned delta = (unsigned)(target_sample - this_frame_sample); | ||
791 | /* kick out of seek mode */ | ||
792 | seekable_stream_decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_OK; | ||
793 | /* shift out the samples before target_sample */ | ||
794 | if(delta > 0) { | ||
795 | unsigned channel; | ||
796 | const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS]; | ||
797 | for(channel = 0; channel < frame->header.channels; channel++) | ||
798 | newbuffer[channel] = buffer[channel] + delta; | ||
799 | seekable_stream_decoder->private_->last_frame.header.blocksize -= delta; | ||
800 | seekable_stream_decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta; | ||
801 | /* write the relevant samples */ | ||
802 | return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, &seekable_stream_decoder->private_->last_frame, newbuffer, seekable_stream_decoder->private_->client_data); | ||
803 | } | ||
804 | else { | ||
805 | /* write the relevant samples */ | ||
806 | return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data); | ||
807 | } | ||
808 | } | ||
809 | else { | ||
810 | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | ||
811 | } | ||
812 | } | ||
813 | else { | ||
814 | if(seekable_stream_decoder->private_->do_md5_checking) { | ||
815 | if(!FLAC__MD5Accumulate(&seekable_stream_decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) | ||
816 | return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; | ||
817 | } | ||
818 | return seekable_stream_decoder->private_->write_callback(seekable_stream_decoder, frame, buffer, seekable_stream_decoder->private_->client_data); | ||
819 | } | ||
820 | } | ||
821 | |||
822 | void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) | ||
823 | { | ||
824 | FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data; | ||
825 | (void)decoder; | ||
826 | |||
827 | if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
828 | seekable_stream_decoder->private_->stream_info = metadata->data.stream_info; | ||
829 | /* save the MD5 signature for comparison later */ | ||
830 | memcpy(seekable_stream_decoder->private_->stored_md5sum, metadata->data.stream_info.md5sum, 16); | ||
831 | if(0 == memcmp(seekable_stream_decoder->private_->stored_md5sum, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)) | ||
832 | seekable_stream_decoder->private_->do_md5_checking = false; | ||
833 | } | ||
834 | else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE) { | ||
835 | seekable_stream_decoder->private_->seek_table = &metadata->data.seek_table; | ||
836 | } | ||
837 | |||
838 | if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) { | ||
839 | FLAC__bool ignore_block = false; | ||
840 | if(metadata->type == FLAC__METADATA_TYPE_STREAMINFO && seekable_stream_decoder->private_->ignore_stream_info_block) | ||
841 | ignore_block = true; | ||
842 | else if(metadata->type == FLAC__METADATA_TYPE_SEEKTABLE && seekable_stream_decoder->private_->ignore_seek_table_block) | ||
843 | ignore_block = true; | ||
844 | if(!ignore_block) | ||
845 | seekable_stream_decoder->private_->metadata_callback(seekable_stream_decoder, metadata, seekable_stream_decoder->private_->client_data); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) | ||
850 | { | ||
851 | FLAC__SeekableStreamDecoder *seekable_stream_decoder = (FLAC__SeekableStreamDecoder *)client_data; | ||
852 | (void)decoder; | ||
853 | |||
854 | if(seekable_stream_decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING) | ||
855 | seekable_stream_decoder->private_->error_callback(seekable_stream_decoder, status, seekable_stream_decoder->private_->client_data); | ||
856 | } | ||
857 | |||
858 | FLAC__bool seek_to_absolute_sample_(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 stream_length, FLAC__uint64 target_sample) | ||
859 | { | ||
860 | FLAC__uint64 first_frame_offset, lower_bound, upper_bound; | ||
861 | FLAC__int64 pos = -1, last_pos = -1; | ||
862 | int i, lower_seek_point = -1, upper_seek_point = -1; | ||
863 | unsigned approx_bytes_per_frame; | ||
864 | FLAC__uint64 last_frame_sample = FLAC__U64L(0xffffffffffffffff); | ||
865 | FLAC__bool needs_seek; | ||
866 | const FLAC__uint64 total_samples = decoder->private_->stream_info.total_samples; | ||
867 | const unsigned min_blocksize = decoder->private_->stream_info.min_blocksize; | ||
868 | const unsigned max_blocksize = decoder->private_->stream_info.max_blocksize; | ||
869 | const unsigned max_framesize = decoder->private_->stream_info.max_framesize; | ||
870 | const unsigned channels = FLAC__seekable_stream_decoder_get_channels(decoder); | ||
871 | const unsigned bps = FLAC__seekable_stream_decoder_get_bits_per_sample(decoder); | ||
872 | |||
873 | /* we are just guessing here, but we want to guess high, not low */ | ||
874 | if(max_framesize > 0) { | ||
875 | approx_bytes_per_frame = max_framesize; | ||
876 | } | ||
877 | /* | ||
878 | * Check if it's a known fixed-blocksize stream. Note that though | ||
879 | * the spec doesn't allow zeroes in the STREAMINFO block, we may | ||
880 | * never get a STREAMINFO block when decoding so the value of | ||
881 | * min_blocksize might be zero. | ||
882 | */ | ||
883 | else if(min_blocksize == max_blocksize && min_blocksize > 0) { | ||
884 | /* note there are no () around 'bps/8' to keep precision up since it's an integer calulation */ | ||
885 | approx_bytes_per_frame = min_blocksize * channels * bps/8 + 64; | ||
886 | } | ||
887 | else | ||
888 | approx_bytes_per_frame = 4608 * channels * bps/8 + 64; | ||
889 | |||
890 | /* | ||
891 | * The decode position is currently at the first frame since we | ||
892 | * rewound and processed metadata. | ||
893 | */ | ||
894 | if(!FLAC__seekable_stream_decoder_get_decode_position(decoder, &first_frame_offset)) { | ||
895 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
896 | return false; | ||
897 | } | ||
898 | |||
899 | /* | ||
900 | * First, we set an upper and lower bound on where in the | ||
901 | * stream we will search. For now we assume the worst case | ||
902 | * scenario, which is our best guess at the beginning of | ||
903 | * the first and last frames. | ||
904 | */ | ||
905 | lower_bound = first_frame_offset; | ||
906 | |||
907 | /* calc the upper_bound, beyond which we never want to seek */ | ||
908 | if(max_framesize > 0) | ||
909 | upper_bound = stream_length - (max_framesize + 128 + 2); /* 128 for a possible ID3V1 tag, 2 for indexing differences */ | ||
910 | else | ||
911 | upper_bound = stream_length - ((channels * bps * FLAC__MAX_BLOCK_SIZE) / 8 + 128 + 2); | ||
912 | |||
913 | /* | ||
914 | * Now we refine the bounds if we have a seektable with | ||
915 | * suitable points. Note that according to the spec they | ||
916 | * must be ordered by ascending sample number. | ||
917 | */ | ||
918 | if(0 != decoder->private_->seek_table) { | ||
919 | /* find the closest seek point <= target_sample, if it exists */ | ||
920 | for(i = (int)decoder->private_->seek_table->num_points - 1; i >= 0; i--) { | ||
921 | if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number <= target_sample) | ||
922 | break; | ||
923 | } | ||
924 | if(i >= 0) { /* i.e. we found a suitable seek point... */ | ||
925 | lower_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset; | ||
926 | lower_seek_point = i; | ||
927 | } | ||
928 | |||
929 | /* find the closest seek point > target_sample, if it exists */ | ||
930 | for(i = 0; i < (int)decoder->private_->seek_table->num_points; i++) { | ||
931 | if(decoder->private_->seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && decoder->private_->seek_table->points[i].sample_number > target_sample) | ||
932 | break; | ||
933 | } | ||
934 | if(i < (int)decoder->private_->seek_table->num_points) { /* i.e. we found a suitable seek point... */ | ||
935 | upper_bound = first_frame_offset + decoder->private_->seek_table->points[i].stream_offset; | ||
936 | upper_seek_point = i; | ||
937 | } | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * Now guess at where within those bounds our target | ||
942 | * sample will be. | ||
943 | */ | ||
944 | if(lower_seek_point >= 0) { | ||
945 | /* first see if our sample is within a few frames of the lower seekpoint */ | ||
946 | if(decoder->private_->seek_table->points[lower_seek_point].sample_number <= target_sample && target_sample < decoder->private_->seek_table->points[lower_seek_point].sample_number + (decoder->private_->seek_table->points[lower_seek_point].frame_samples * 4)) { | ||
947 | pos = (FLAC__int64)lower_bound; | ||
948 | } | ||
949 | else if(upper_seek_point >= 0) { | ||
950 | const FLAC__uint64 target_offset = target_sample - decoder->private_->seek_table->points[lower_seek_point].sample_number; | ||
951 | const FLAC__uint64 range_samples = decoder->private_->seek_table->points[upper_seek_point].sample_number - decoder->private_->seek_table->points[lower_seek_point].sample_number; | ||
952 | const FLAC__uint64 range_bytes = (upper_bound>lower_bound? upper_bound - lower_bound - 1 : 0); | ||
953 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
954 | #if defined _MSC_VER || defined __MINGW32__ | ||
955 | /* with MSVC you have to spoon feed it the casting */ | ||
956 | pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_offset / (FLAC__double)(FLAC__int64)range_samples) * (FLAC__double)(FLAC__int64)(range_bytes-1)) - approx_bytes_per_frame; | ||
957 | #else | ||
958 | pos = (FLAC__int64)lower_bound + (FLAC__int64)(((FLAC__double)target_offset / (FLAC__double)range_samples) * (FLAC__double)range_bytes) - approx_bytes_per_frame; | ||
959 | #endif | ||
960 | #else | ||
961 | /* a little less accurate: */ | ||
962 | if (range_bytes <= 0xffffffff) | ||
963 | pos = (FLAC__int64)lower_bound + (FLAC__int64)((target_offset * range_bytes) / range_samples) - approx_bytes_per_frame; | ||
964 | else /* @@@ WATCHOUT, ~2TB limit */ | ||
965 | pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_offset>>8) * (range_bytes>>8)) / (range_samples>>16)) - approx_bytes_per_frame; | ||
966 | #endif | ||
967 | } | ||
968 | } | ||
969 | |||
970 | /* | ||
971 | * If there's no seek table, we need to use the metadata (if we | ||
972 | * have it) and the filelength to estimate the position of the | ||
973 | * frame with the correct sample. | ||
974 | */ | ||
975 | if(pos < 0 && total_samples > 0) { | ||
976 | /* | ||
977 | * For max accuracy we should be using | ||
978 | * (stream_length-first_frame_offset-1) in the divisor, but the | ||
979 | * difference is trivial and (stream_length-first_frame_offset) | ||
980 | * has no chance of underflow. | ||
981 | */ | ||
982 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
983 | #if defined _MSC_VER || defined __MINGW32__ | ||
984 | /* with VC++ you have to spoon feed it the casting */ | ||
985 | pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)(FLAC__int64)target_sample / (FLAC__double)(FLAC__int64)total_samples) * (FLAC__double)(FLAC__int64)(stream_length-first_frame_offset)) - approx_bytes_per_frame; | ||
986 | #else | ||
987 | pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((FLAC__double)target_sample / (FLAC__double)total_samples) * (FLAC__double)(stream_length-first_frame_offset)) - approx_bytes_per_frame; | ||
988 | #endif | ||
989 | #else | ||
990 | /* a little less accurate: */ | ||
991 | if (stream_length < 0xffffffff) | ||
992 | pos = (FLAC__int64)first_frame_offset + (FLAC__int64)((target_sample * (stream_length-first_frame_offset)) / total_samples) - approx_bytes_per_frame; | ||
993 | else /* @@@ WATCHOUT, ~2TB limit */ | ||
994 | pos = (FLAC__int64)first_frame_offset + (FLAC__int64)(((target_sample>>8) * ((stream_length-first_frame_offset)>>8)) / (total_samples>>16)) - approx_bytes_per_frame; | ||
995 | #endif | ||
996 | } | ||
997 | |||
998 | /* | ||
999 | * If there's no seek table and total_samples is unknown, we | ||
1000 | * don't even bother trying to figure out a target, we just use | ||
1001 | * our current position. | ||
1002 | */ | ||
1003 | if(pos < 0) { | ||
1004 | FLAC__uint64 upos; | ||
1005 | if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) { | ||
1006 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
1007 | return false; | ||
1008 | } | ||
1009 | pos = (FLAC__int64)upos; | ||
1010 | needs_seek = false; | ||
1011 | } | ||
1012 | else | ||
1013 | needs_seek = true; | ||
1014 | |||
1015 | /* clip the position to the bounds, lower bound takes precedence */ | ||
1016 | if(pos >= (FLAC__int64)upper_bound) { | ||
1017 | pos = (FLAC__int64)upper_bound-1; | ||
1018 | needs_seek = true; | ||
1019 | } | ||
1020 | if(pos < (FLAC__int64)lower_bound) { | ||
1021 | pos = (FLAC__int64)lower_bound; | ||
1022 | needs_seek = true; | ||
1023 | } | ||
1024 | |||
1025 | decoder->private_->target_sample = target_sample; | ||
1026 | while(1) { | ||
1027 | if(needs_seek) { | ||
1028 | if(decoder->private_->seek_callback(decoder, (FLAC__uint64)pos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) { | ||
1029 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
1030 | return false; | ||
1031 | } | ||
1032 | if(!FLAC__stream_decoder_flush(decoder->private_->stream_decoder)) { | ||
1033 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; | ||
1034 | return false; | ||
1035 | } | ||
1036 | } | ||
1037 | /* Now we need to get a frame. It is possible for our seek | ||
1038 | * to land in the middle of audio data that looks exactly like | ||
1039 | * a frame header from a future version of an encoder. When | ||
1040 | * that happens, FLAC__stream_decoder_process_single() will | ||
1041 | * return false and the state will be | ||
1042 | * FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. But there is a | ||
1043 | * remote possibility that it is properly synced at such a | ||
1044 | * "future-codec frame", so to make sure, we wait to see | ||
1045 | * several "unparseable" errors in a row before bailing out. | ||
1046 | */ | ||
1047 | { | ||
1048 | unsigned unparseable_count; | ||
1049 | FLAC__bool got_a_frame = false; | ||
1050 | for (unparseable_count = 0; !got_a_frame && unparseable_count < 10; unparseable_count++) { | ||
1051 | if(FLAC__stream_decoder_process_single(decoder->private_->stream_decoder)) | ||
1052 | got_a_frame = true; | ||
1053 | else if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_UNPARSEABLE_STREAM) | ||
1054 | /* try again. we don't want to flush the decoder since that clears the bitbuffer */ | ||
1055 | decoder->private_->stream_decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1056 | else /* it's a real error */ | ||
1057 | break; | ||
1058 | } | ||
1059 | if (!got_a_frame) { | ||
1060 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
1061 | return false; | ||
1062 | } | ||
1063 | } | ||
1064 | /* our write callback will change the state when it gets to the target frame */ | ||
1065 | /* actually, we could have got_a_frame if our decoder is at FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM so we need to check for that also */ | ||
1066 | if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) { | ||
1067 | break; | ||
1068 | } | ||
1069 | else { /* we need to narrow the search */ | ||
1070 | const FLAC__uint64 this_frame_sample = decoder->private_->last_frame.header.number.sample_number; | ||
1071 | FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); | ||
1072 | if(this_frame_sample == last_frame_sample && pos < last_pos) { | ||
1073 | /* our last move backwards wasn't big enough, double it */ | ||
1074 | pos -= (last_pos - pos); | ||
1075 | needs_seek = true; | ||
1076 | } | ||
1077 | else { | ||
1078 | if(target_sample < this_frame_sample) { | ||
1079 | last_pos = pos; | ||
1080 | approx_bytes_per_frame = decoder->private_->last_frame.header.blocksize * channels * bps/8 + 64; | ||
1081 | pos -= approx_bytes_per_frame; | ||
1082 | needs_seek = true; | ||
1083 | } | ||
1084 | else { /* target_sample >= this_frame_sample + this frame's blocksize */ | ||
1085 | FLAC__uint64 upos; | ||
1086 | if(decoder->private_->tell_callback(decoder, &upos, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK) { | ||
1087 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
1088 | return false; | ||
1089 | } | ||
1090 | last_pos = pos; | ||
1091 | pos = (FLAC__int64)upos; | ||
1092 | pos -= FLAC__stream_decoder_get_input_bytes_unconsumed(decoder->private_->stream_decoder); | ||
1093 | needs_seek = false; | ||
1094 | /* | ||
1095 | * if we haven't hit the target frame yet and our position hasn't changed, | ||
1096 | * it means we're at the end of the stream and the seek target does not exist. | ||
1097 | */ | ||
1098 | if(last_pos == pos) { | ||
1099 | decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; | ||
1100 | return false; | ||
1101 | } | ||
1102 | } | ||
1103 | } | ||
1104 | if(pos < (FLAC__int64)lower_bound) | ||
1105 | pos = (FLAC__int64)lower_bound; | ||
1106 | last_frame_sample = this_frame_sample; | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | return true; | ||
1111 | } | ||
diff --git a/apps/codecs/libFLAC/seekable_stream_encoder.c b/apps/codecs/libFLAC/seekable_stream_encoder.c new file mode 100644 index 0000000000..18291a8052 --- /dev/null +++ b/apps/codecs/libFLAC/seekable_stream_encoder.c | |||
@@ -0,0 +1,943 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for calloc() */ | ||
34 | #include <string.h> /* for memcpy() */ | ||
35 | #include "FLAC/assert.h" | ||
36 | #include "protected/seekable_stream_encoder.h" | ||
37 | |||
38 | #ifdef max | ||
39 | #undef max | ||
40 | #endif | ||
41 | #define max(a,b) ((a)>(b)?(a):(b)) | ||
42 | |||
43 | /*********************************************************************** | ||
44 | * | ||
45 | * Private class method prototypes | ||
46 | * | ||
47 | ***********************************************************************/ | ||
48 | |||
49 | /* unpublished debug routines */ | ||
50 | extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
51 | extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
52 | extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); | ||
53 | |||
54 | static void set_defaults_(FLAC__SeekableStreamEncoder *encoder); | ||
55 | static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); | ||
56 | static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); | ||
57 | |||
58 | /*********************************************************************** | ||
59 | * | ||
60 | * Private class data | ||
61 | * | ||
62 | ***********************************************************************/ | ||
63 | |||
64 | typedef struct FLAC__SeekableStreamEncoderPrivate { | ||
65 | FLAC__SeekableStreamEncoderSeekCallback seek_callback; | ||
66 | FLAC__SeekableStreamEncoderTellCallback tell_callback; | ||
67 | FLAC__SeekableStreamEncoderWriteCallback write_callback; | ||
68 | void *client_data; | ||
69 | FLAC__StreamEncoder *stream_encoder; | ||
70 | FLAC__StreamMetadata_SeekTable *seek_table; | ||
71 | /* internal vars (all the above are class settings) */ | ||
72 | unsigned first_seekpoint_to_check; | ||
73 | FLAC__uint64 samples_written; | ||
74 | } FLAC__SeekableStreamEncoderPrivate; | ||
75 | |||
76 | /*********************************************************************** | ||
77 | * | ||
78 | * Public static class data | ||
79 | * | ||
80 | ***********************************************************************/ | ||
81 | |||
82 | FLAC_API const char * const FLAC__SeekableStreamEncoderStateString[] = { | ||
83 | "FLAC__SEEKABLE_STREAM_ENCODER_OK", | ||
84 | "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR", | ||
85 | "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR", | ||
86 | "FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR", | ||
87 | "FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR", | ||
88 | "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR", | ||
89 | "FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR", | ||
90 | "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED", | ||
91 | "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK", | ||
92 | "FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE", | ||
93 | "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED" | ||
94 | }; | ||
95 | |||
96 | FLAC_API const char * const FLAC__SeekableStreamEncoderSeekStatusString[] = { | ||
97 | "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK", | ||
98 | "FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR" | ||
99 | }; | ||
100 | |||
101 | FLAC_API const char * const FLAC__SeekableStreamEncoderTellStatusString[] = { | ||
102 | "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK", | ||
103 | "FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR" | ||
104 | }; | ||
105 | |||
106 | |||
107 | /*********************************************************************** | ||
108 | * | ||
109 | * Class constructor/destructor | ||
110 | * | ||
111 | ***********************************************************************/ | ||
112 | |||
113 | FLAC_API FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new() | ||
114 | { | ||
115 | FLAC__SeekableStreamEncoder *encoder; | ||
116 | |||
117 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
118 | |||
119 | encoder = (FLAC__SeekableStreamEncoder*)calloc(1, sizeof(FLAC__SeekableStreamEncoder)); | ||
120 | if(encoder == 0) { | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(FLAC__SeekableStreamEncoderProtected)); | ||
125 | if(encoder->protected_ == 0) { | ||
126 | free(encoder); | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(FLAC__SeekableStreamEncoderPrivate)); | ||
131 | if(encoder->private_ == 0) { | ||
132 | free(encoder->protected_); | ||
133 | free(encoder); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | encoder->private_->stream_encoder = FLAC__stream_encoder_new(); | ||
138 | if(0 == encoder->private_->stream_encoder) { | ||
139 | free(encoder->private_); | ||
140 | free(encoder->protected_); | ||
141 | free(encoder); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | set_defaults_(encoder); | ||
146 | |||
147 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED; | ||
148 | |||
149 | return encoder; | ||
150 | } | ||
151 | |||
152 | FLAC_API void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder) | ||
153 | { | ||
154 | FLAC__ASSERT(0 != encoder); | ||
155 | FLAC__ASSERT(0 != encoder->protected_); | ||
156 | FLAC__ASSERT(0 != encoder->private_); | ||
157 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
158 | |||
159 | (void)FLAC__seekable_stream_encoder_finish(encoder); | ||
160 | |||
161 | FLAC__stream_encoder_delete(encoder->private_->stream_encoder); | ||
162 | |||
163 | free(encoder->private_); | ||
164 | free(encoder->protected_); | ||
165 | free(encoder); | ||
166 | } | ||
167 | |||
168 | |||
169 | /*********************************************************************** | ||
170 | * | ||
171 | * Public class methods | ||
172 | * | ||
173 | ***********************************************************************/ | ||
174 | |||
175 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder) | ||
176 | { | ||
177 | FLAC__ASSERT(0 != encoder); | ||
178 | |||
179 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
180 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED; | ||
181 | |||
182 | if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback) | ||
183 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK; | ||
184 | |||
185 | if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table)) | ||
186 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE; | ||
187 | |||
188 | /* | ||
189 | * These must be done before we init the stream encoder because that | ||
190 | * calls the write_callback, which uses these values. | ||
191 | */ | ||
192 | encoder->private_->first_seekpoint_to_check = 0; | ||
193 | encoder->private_->samples_written = 0; | ||
194 | encoder->protected_->streaminfo_offset = 0; | ||
195 | encoder->protected_->seektable_offset = 0; | ||
196 | encoder->protected_->audio_offset = 0; | ||
197 | |||
198 | FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_); | ||
199 | FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_); | ||
200 | FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder); | ||
201 | |||
202 | if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK) | ||
203 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR; | ||
204 | |||
205 | /* | ||
206 | * Initializing the stream encoder writes all the metadata, so we | ||
207 | * save the stream offset now. | ||
208 | */ | ||
209 | if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK) | ||
210 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR; | ||
211 | |||
212 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK; | ||
213 | } | ||
214 | |||
215 | FLAC_API void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder) | ||
216 | { | ||
217 | FLAC__ASSERT(0 != encoder); | ||
218 | FLAC__ASSERT(0 != encoder->private_); | ||
219 | FLAC__ASSERT(0 != encoder->protected_); | ||
220 | |||
221 | if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
222 | return; | ||
223 | |||
224 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
225 | |||
226 | FLAC__stream_encoder_finish(encoder->private_->stream_encoder); | ||
227 | |||
228 | set_defaults_(encoder); | ||
229 | |||
230 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED; | ||
231 | } | ||
232 | |||
233 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_verify(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
234 | { | ||
235 | FLAC__ASSERT(0 != encoder); | ||
236 | FLAC__ASSERT(0 != encoder->private_); | ||
237 | FLAC__ASSERT(0 != encoder->protected_); | ||
238 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
239 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
240 | return false; | ||
241 | return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value); | ||
242 | } | ||
243 | |||
244 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
245 | { | ||
246 | FLAC__ASSERT(0 != encoder); | ||
247 | FLAC__ASSERT(0 != encoder->private_); | ||
248 | FLAC__ASSERT(0 != encoder->protected_); | ||
249 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
250 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
251 | return false; | ||
252 | return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value); | ||
253 | } | ||
254 | |||
255 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
256 | { | ||
257 | FLAC__ASSERT(0 != encoder); | ||
258 | FLAC__ASSERT(0 != encoder->private_); | ||
259 | FLAC__ASSERT(0 != encoder->protected_); | ||
260 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
261 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
262 | return false; | ||
263 | return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value); | ||
264 | } | ||
265 | |||
266 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
267 | { | ||
268 | FLAC__ASSERT(0 != encoder); | ||
269 | FLAC__ASSERT(0 != encoder->private_); | ||
270 | FLAC__ASSERT(0 != encoder->protected_); | ||
271 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
272 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
273 | return false; | ||
274 | return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value); | ||
275 | } | ||
276 | |||
277 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
278 | { | ||
279 | FLAC__ASSERT(0 != encoder); | ||
280 | FLAC__ASSERT(0 != encoder->private_); | ||
281 | FLAC__ASSERT(0 != encoder->protected_); | ||
282 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
283 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
284 | return false; | ||
285 | return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value); | ||
286 | } | ||
287 | |||
288 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
289 | { | ||
290 | FLAC__ASSERT(0 != encoder); | ||
291 | FLAC__ASSERT(0 != encoder->private_); | ||
292 | FLAC__ASSERT(0 != encoder->protected_); | ||
293 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
294 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
295 | return false; | ||
296 | return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value); | ||
297 | } | ||
298 | |||
299 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
300 | { | ||
301 | FLAC__ASSERT(0 != encoder); | ||
302 | FLAC__ASSERT(0 != encoder->private_); | ||
303 | FLAC__ASSERT(0 != encoder->protected_); | ||
304 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
305 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
306 | return false; | ||
307 | return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value); | ||
308 | } | ||
309 | |||
310 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
311 | { | ||
312 | FLAC__ASSERT(0 != encoder); | ||
313 | FLAC__ASSERT(0 != encoder->private_); | ||
314 | FLAC__ASSERT(0 != encoder->protected_); | ||
315 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
316 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
317 | return false; | ||
318 | return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value); | ||
319 | } | ||
320 | |||
321 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
322 | { | ||
323 | FLAC__ASSERT(0 != encoder); | ||
324 | FLAC__ASSERT(0 != encoder->private_); | ||
325 | FLAC__ASSERT(0 != encoder->protected_); | ||
326 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
327 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
328 | return false; | ||
329 | return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value); | ||
330 | } | ||
331 | |||
332 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
333 | { | ||
334 | FLAC__ASSERT(0 != encoder); | ||
335 | FLAC__ASSERT(0 != encoder->private_); | ||
336 | FLAC__ASSERT(0 != encoder->protected_); | ||
337 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
338 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
339 | return false; | ||
340 | return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value); | ||
341 | } | ||
342 | |||
343 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
344 | { | ||
345 | FLAC__ASSERT(0 != encoder); | ||
346 | FLAC__ASSERT(0 != encoder->private_); | ||
347 | FLAC__ASSERT(0 != encoder->protected_); | ||
348 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
349 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
350 | return false; | ||
351 | return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value); | ||
352 | } | ||
353 | |||
354 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
355 | { | ||
356 | FLAC__ASSERT(0 != encoder); | ||
357 | FLAC__ASSERT(0 != encoder->private_); | ||
358 | FLAC__ASSERT(0 != encoder->protected_); | ||
359 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
360 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
361 | return false; | ||
362 | return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value); | ||
363 | } | ||
364 | |||
365 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
366 | { | ||
367 | FLAC__ASSERT(0 != encoder); | ||
368 | FLAC__ASSERT(0 != encoder->private_); | ||
369 | FLAC__ASSERT(0 != encoder->protected_); | ||
370 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
371 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
372 | return false; | ||
373 | return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value); | ||
374 | } | ||
375 | |||
376 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
377 | { | ||
378 | FLAC__ASSERT(0 != encoder); | ||
379 | FLAC__ASSERT(0 != encoder->private_); | ||
380 | FLAC__ASSERT(0 != encoder->protected_); | ||
381 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
382 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
383 | return false; | ||
384 | return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value); | ||
385 | } | ||
386 | |||
387 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
388 | { | ||
389 | FLAC__ASSERT(0 != encoder); | ||
390 | FLAC__ASSERT(0 != encoder->private_); | ||
391 | FLAC__ASSERT(0 != encoder->protected_); | ||
392 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
393 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
394 | return false; | ||
395 | return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value); | ||
396 | } | ||
397 | |||
398 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value) | ||
399 | { | ||
400 | FLAC__ASSERT(0 != encoder); | ||
401 | FLAC__ASSERT(0 != encoder->private_); | ||
402 | FLAC__ASSERT(0 != encoder->protected_); | ||
403 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
404 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
405 | return false; | ||
406 | return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value); | ||
407 | } | ||
408 | |||
409 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value) | ||
410 | { | ||
411 | FLAC__ASSERT(0 != encoder); | ||
412 | FLAC__ASSERT(0 != encoder->private_); | ||
413 | FLAC__ASSERT(0 != encoder->protected_); | ||
414 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
415 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
416 | return false; | ||
417 | return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value); | ||
418 | } | ||
419 | |||
420 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) | ||
421 | { | ||
422 | FLAC__ASSERT(0 != encoder); | ||
423 | FLAC__ASSERT(0 != encoder->private_); | ||
424 | FLAC__ASSERT(0 != encoder->protected_); | ||
425 | FLAC__ASSERT(0 != encoder->private_->stream_encoder); | ||
426 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
427 | return false; | ||
428 | if(0 != metadata && num_blocks > 0) { | ||
429 | unsigned i; | ||
430 | for(i = 0; i < num_blocks; i++) { | ||
431 | if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) { | ||
432 | encoder->private_->seek_table = &metadata[i]->data.seek_table; | ||
433 | break; /* take only the first one */ | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, metadata, num_blocks); | ||
438 | } | ||
439 | |||
440 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekCallback value) | ||
441 | { | ||
442 | FLAC__ASSERT(0 != encoder); | ||
443 | FLAC__ASSERT(0 != encoder->private_); | ||
444 | FLAC__ASSERT(0 != encoder->protected_); | ||
445 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
446 | return false; | ||
447 | encoder->private_->seek_callback = value; | ||
448 | return true; | ||
449 | } | ||
450 | |||
451 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_tell_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderTellCallback value) | ||
452 | { | ||
453 | FLAC__ASSERT(0 != encoder); | ||
454 | FLAC__ASSERT(0 != encoder->private_); | ||
455 | FLAC__ASSERT(0 != encoder->protected_); | ||
456 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
457 | return false; | ||
458 | encoder->private_->tell_callback = value; | ||
459 | return true; | ||
460 | } | ||
461 | |||
462 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_write_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderWriteCallback value) | ||
463 | { | ||
464 | FLAC__ASSERT(0 != encoder); | ||
465 | FLAC__ASSERT(0 != encoder->private_); | ||
466 | FLAC__ASSERT(0 != encoder->protected_); | ||
467 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
468 | return false; | ||
469 | encoder->private_->write_callback = value; | ||
470 | return true; | ||
471 | } | ||
472 | |||
473 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_client_data(FLAC__SeekableStreamEncoder *encoder, void *value) | ||
474 | { | ||
475 | FLAC__ASSERT(0 != encoder); | ||
476 | FLAC__ASSERT(0 != encoder->private_); | ||
477 | FLAC__ASSERT(0 != encoder->protected_); | ||
478 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
479 | return false; | ||
480 | encoder->private_->client_data = value; | ||
481 | return true; | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * These three functions are not static, but not publically exposed in | ||
486 | * include/FLAC/ either. They are used by the test suite. | ||
487 | */ | ||
488 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
489 | { | ||
490 | FLAC__ASSERT(0 != encoder); | ||
491 | FLAC__ASSERT(0 != encoder->private_); | ||
492 | FLAC__ASSERT(0 != encoder->protected_); | ||
493 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
494 | return false; | ||
495 | return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->stream_encoder, value); | ||
496 | } | ||
497 | |||
498 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
499 | { | ||
500 | FLAC__ASSERT(0 != encoder); | ||
501 | FLAC__ASSERT(0 != encoder->private_); | ||
502 | FLAC__ASSERT(0 != encoder->protected_); | ||
503 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
504 | return false; | ||
505 | return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->stream_encoder, value); | ||
506 | } | ||
507 | |||
508 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) | ||
509 | { | ||
510 | FLAC__ASSERT(0 != encoder); | ||
511 | FLAC__ASSERT(0 != encoder->private_); | ||
512 | FLAC__ASSERT(0 != encoder->protected_); | ||
513 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) | ||
514 | return false; | ||
515 | return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->stream_encoder, value); | ||
516 | } | ||
517 | |||
518 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder) | ||
519 | { | ||
520 | FLAC__ASSERT(0 != encoder); | ||
521 | FLAC__ASSERT(0 != encoder->protected_); | ||
522 | return encoder->protected_->state; | ||
523 | } | ||
524 | |||
525 | FLAC_API FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder) | ||
526 | { | ||
527 | FLAC__ASSERT(0 != encoder); | ||
528 | FLAC__ASSERT(0 != encoder->private_); | ||
529 | return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder); | ||
530 | } | ||
531 | |||
532 | FLAC_API FLAC__StreamDecoderState FLAC__seekable_stream_encoder_get_verify_decoder_state(const FLAC__SeekableStreamEncoder *encoder) | ||
533 | { | ||
534 | FLAC__ASSERT(0 != encoder); | ||
535 | FLAC__ASSERT(0 != encoder->private_); | ||
536 | return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->stream_encoder); | ||
537 | } | ||
538 | |||
539 | FLAC_API const char *FLAC__seekable_stream_encoder_get_resolved_state_string(const FLAC__SeekableStreamEncoder *encoder) | ||
540 | { | ||
541 | if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR) | ||
542 | return FLAC__SeekableStreamEncoderStateString[encoder->protected_->state]; | ||
543 | else | ||
544 | return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->stream_encoder); | ||
545 | } | ||
546 | |||
547 | FLAC_API void FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got) | ||
548 | { | ||
549 | FLAC__ASSERT(0 != encoder); | ||
550 | FLAC__ASSERT(0 != encoder->private_); | ||
551 | FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->stream_encoder, absolute_sample, frame_number, channel, sample, expected, got); | ||
552 | } | ||
553 | |||
554 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_verify(const FLAC__SeekableStreamEncoder *encoder) | ||
555 | { | ||
556 | FLAC__ASSERT(0 != encoder); | ||
557 | FLAC__ASSERT(0 != encoder->private_); | ||
558 | return FLAC__stream_encoder_get_verify(encoder->private_->stream_encoder); | ||
559 | } | ||
560 | |||
561 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder) | ||
562 | { | ||
563 | FLAC__ASSERT(0 != encoder); | ||
564 | FLAC__ASSERT(0 != encoder->private_); | ||
565 | return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder); | ||
566 | } | ||
567 | |||
568 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder) | ||
569 | { | ||
570 | FLAC__ASSERT(0 != encoder); | ||
571 | FLAC__ASSERT(0 != encoder->private_); | ||
572 | return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder); | ||
573 | } | ||
574 | |||
575 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder) | ||
576 | { | ||
577 | FLAC__ASSERT(0 != encoder); | ||
578 | FLAC__ASSERT(0 != encoder->private_); | ||
579 | return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder); | ||
580 | } | ||
581 | |||
582 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder) | ||
583 | { | ||
584 | FLAC__ASSERT(0 != encoder); | ||
585 | FLAC__ASSERT(0 != encoder->private_); | ||
586 | return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder); | ||
587 | } | ||
588 | |||
589 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder) | ||
590 | { | ||
591 | FLAC__ASSERT(0 != encoder); | ||
592 | FLAC__ASSERT(0 != encoder->private_); | ||
593 | return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder); | ||
594 | } | ||
595 | |||
596 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder) | ||
597 | { | ||
598 | FLAC__ASSERT(0 != encoder); | ||
599 | FLAC__ASSERT(0 != encoder->private_); | ||
600 | return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder); | ||
601 | } | ||
602 | |||
603 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder) | ||
604 | { | ||
605 | FLAC__ASSERT(0 != encoder); | ||
606 | FLAC__ASSERT(0 != encoder->private_); | ||
607 | return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder); | ||
608 | } | ||
609 | |||
610 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder) | ||
611 | { | ||
612 | FLAC__ASSERT(0 != encoder); | ||
613 | FLAC__ASSERT(0 != encoder->private_); | ||
614 | return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder); | ||
615 | } | ||
616 | |||
617 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder) | ||
618 | { | ||
619 | FLAC__ASSERT(0 != encoder); | ||
620 | FLAC__ASSERT(0 != encoder->private_); | ||
621 | return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder); | ||
622 | } | ||
623 | |||
624 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder) | ||
625 | { | ||
626 | FLAC__ASSERT(0 != encoder); | ||
627 | FLAC__ASSERT(0 != encoder->private_); | ||
628 | return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder); | ||
629 | } | ||
630 | |||
631 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder) | ||
632 | { | ||
633 | FLAC__ASSERT(0 != encoder); | ||
634 | FLAC__ASSERT(0 != encoder->private_); | ||
635 | return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder); | ||
636 | } | ||
637 | |||
638 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder) | ||
639 | { | ||
640 | FLAC__ASSERT(0 != encoder); | ||
641 | FLAC__ASSERT(0 != encoder->private_); | ||
642 | return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder); | ||
643 | } | ||
644 | |||
645 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder) | ||
646 | { | ||
647 | FLAC__ASSERT(0 != encoder); | ||
648 | FLAC__ASSERT(0 != encoder->private_); | ||
649 | return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder); | ||
650 | } | ||
651 | |||
652 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder) | ||
653 | { | ||
654 | FLAC__ASSERT(0 != encoder); | ||
655 | FLAC__ASSERT(0 != encoder->private_); | ||
656 | return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder); | ||
657 | } | ||
658 | |||
659 | FLAC_API unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder) | ||
660 | { | ||
661 | FLAC__ASSERT(0 != encoder); | ||
662 | FLAC__ASSERT(0 != encoder->private_); | ||
663 | return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder); | ||
664 | } | ||
665 | |||
666 | FLAC_API FLAC__uint64 FLAC__seekable_stream_encoder_get_total_samples_estimate(const FLAC__SeekableStreamEncoder *encoder) | ||
667 | { | ||
668 | FLAC__ASSERT(0 != encoder); | ||
669 | FLAC__ASSERT(0 != encoder->private_); | ||
670 | return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->stream_encoder); | ||
671 | } | ||
672 | |||
673 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) | ||
674 | { | ||
675 | FLAC__ASSERT(0 != encoder); | ||
676 | FLAC__ASSERT(0 != encoder->private_); | ||
677 | if(!FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples)) { | ||
678 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR; | ||
679 | return false; | ||
680 | } | ||
681 | else | ||
682 | return true; | ||
683 | } | ||
684 | |||
685 | /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ | ||
686 | FLAC_API FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) | ||
687 | { | ||
688 | FLAC__ASSERT(0 != encoder); | ||
689 | FLAC__ASSERT(0 != encoder->private_); | ||
690 | if(!FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples)) { | ||
691 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR; | ||
692 | return false; | ||
693 | } | ||
694 | else | ||
695 | return true; | ||
696 | } | ||
697 | |||
698 | /*********************************************************************** | ||
699 | * | ||
700 | * Private class methods | ||
701 | * | ||
702 | ***********************************************************************/ | ||
703 | |||
704 | void set_defaults_(FLAC__SeekableStreamEncoder *encoder) | ||
705 | { | ||
706 | FLAC__ASSERT(0 != encoder); | ||
707 | FLAC__ASSERT(0 != encoder->private_); | ||
708 | FLAC__ASSERT(0 != encoder->protected_); | ||
709 | |||
710 | encoder->private_->seek_callback = 0; | ||
711 | encoder->private_->tell_callback = 0; | ||
712 | encoder->private_->write_callback = 0; | ||
713 | encoder->private_->client_data = 0; | ||
714 | |||
715 | encoder->private_->seek_table = 0; | ||
716 | } | ||
717 | |||
718 | FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) | ||
719 | { | ||
720 | FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data; | ||
721 | FLAC__StreamEncoderWriteStatus status; | ||
722 | FLAC__uint64 output_position; | ||
723 | |||
724 | (void)unused; /* silence compiler warning about unused parameter */ | ||
725 | FLAC__ASSERT(encoder->private_->stream_encoder == unused); | ||
726 | |||
727 | if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK) | ||
728 | return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR; | ||
729 | |||
730 | /* | ||
731 | * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets. | ||
732 | */ | ||
733 | if(samples == 0) { | ||
734 | FLAC__MetadataType type = (buffer[0] & 0x7f); | ||
735 | if(type == FLAC__METADATA_TYPE_STREAMINFO) | ||
736 | encoder->protected_->streaminfo_offset = output_position; | ||
737 | else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0) | ||
738 | encoder->protected_->seektable_offset = output_position; | ||
739 | } | ||
740 | |||
741 | /* | ||
742 | * Mark the current seek point if hit (if audio_offset == 0 that | ||
743 | * means we're still writing metadata and haven't hit the first | ||
744 | * frame yet) | ||
745 | */ | ||
746 | if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) { | ||
747 | const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder); | ||
748 | const FLAC__uint64 frame_first_sample = encoder->private_->samples_written; | ||
749 | const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1; | ||
750 | FLAC__uint64 test_sample; | ||
751 | unsigned i; | ||
752 | for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) { | ||
753 | test_sample = encoder->private_->seek_table->points[i].sample_number; | ||
754 | if(test_sample > frame_last_sample) { | ||
755 | break; | ||
756 | } | ||
757 | else if(test_sample >= frame_first_sample) { | ||
758 | encoder->private_->seek_table->points[i].sample_number = frame_first_sample; | ||
759 | encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset; | ||
760 | encoder->private_->seek_table->points[i].frame_samples = blocksize; | ||
761 | encoder->private_->first_seekpoint_to_check++; | ||
762 | /* DO NOT: "break;" and here's why: | ||
763 | * The seektable template may contain more than one target | ||
764 | * sample for any given frame; we will keep looping, generating | ||
765 | * duplicate seekpoints for them, and we'll clean it up later, | ||
766 | * just before writing the seektable back to the metadata. | ||
767 | */ | ||
768 | } | ||
769 | else { | ||
770 | encoder->private_->first_seekpoint_to_check++; | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | status = encoder->private_->write_callback(encoder, buffer, bytes, samples, current_frame, encoder->private_->client_data); | ||
776 | |||
777 | if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
778 | encoder->private_->samples_written += samples; | ||
779 | } | ||
780 | else | ||
781 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR; | ||
782 | |||
783 | return status; | ||
784 | } | ||
785 | |||
786 | void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data) | ||
787 | { | ||
788 | FLAC__SeekableStreamEncoder *encoder = (FLAC__SeekableStreamEncoder*)client_data; | ||
789 | FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; | ||
790 | const FLAC__uint64 samples = metadata->data.stream_info.total_samples; | ||
791 | const unsigned min_framesize = metadata->data.stream_info.min_framesize; | ||
792 | const unsigned max_framesize = metadata->data.stream_info.max_framesize; | ||
793 | const unsigned bps = metadata->data.stream_info.bits_per_sample; | ||
794 | |||
795 | FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); | ||
796 | |||
797 | /* We get called by the stream encoder when the encoding process | ||
798 | * has finished so that we can update the STREAMINFO and SEEKTABLE | ||
799 | * blocks. | ||
800 | */ | ||
801 | |||
802 | (void)unused; /* silence compiler warning about unused parameter */ | ||
803 | FLAC__ASSERT(encoder->private_->stream_encoder == unused); | ||
804 | |||
805 | /*@@@ reopen callback here? The docs currently require user to open files in update mode from the start */ | ||
806 | |||
807 | /* All this is based on intimate knowledge of the stream header | ||
808 | * layout, but a change to the header format that would break this | ||
809 | * would also break all streams encoded in the previous format. | ||
810 | */ | ||
811 | |||
812 | /* | ||
813 | * Write MD5 signature | ||
814 | */ | ||
815 | { | ||
816 | const unsigned md5_offset = | ||
817 | FLAC__STREAM_METADATA_HEADER_LENGTH + | ||
818 | ( | ||
819 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + | ||
820 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + | ||
821 | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + | ||
822 | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + | ||
823 | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + | ||
824 | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + | ||
825 | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN + | ||
826 | FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN | ||
827 | ) / 8; | ||
828 | |||
829 | if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + md5_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) { | ||
830 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR; | ||
831 | return; | ||
832 | } | ||
833 | if(encoder->private_->write_callback(encoder, metadata->data.stream_info.md5sum, 16, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
834 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR; | ||
835 | return; | ||
836 | } | ||
837 | } | ||
838 | |||
839 | /* | ||
840 | * Write total samples | ||
841 | */ | ||
842 | { | ||
843 | const unsigned total_samples_byte_offset = | ||
844 | FLAC__STREAM_METADATA_HEADER_LENGTH + | ||
845 | ( | ||
846 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + | ||
847 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN + | ||
848 | FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN + | ||
849 | FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN + | ||
850 | FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN + | ||
851 | FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN + | ||
852 | FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN | ||
853 | - 4 | ||
854 | ) / 8; | ||
855 | |||
856 | b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F); | ||
857 | b[1] = (FLAC__byte)((samples >> 24) & 0xFF); | ||
858 | b[2] = (FLAC__byte)((samples >> 16) & 0xFF); | ||
859 | b[3] = (FLAC__byte)((samples >> 8) & 0xFF); | ||
860 | b[4] = (FLAC__byte)(samples & 0xFF); | ||
861 | if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + total_samples_byte_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) { | ||
862 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR; | ||
863 | return; | ||
864 | } | ||
865 | if(encoder->private_->write_callback(encoder, b, 5, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
866 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR; | ||
867 | return; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /* | ||
872 | * Write min/max framesize | ||
873 | */ | ||
874 | { | ||
875 | const unsigned min_framesize_offset = | ||
876 | FLAC__STREAM_METADATA_HEADER_LENGTH + | ||
877 | ( | ||
878 | FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN + | ||
879 | FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN | ||
880 | ) / 8; | ||
881 | |||
882 | b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF); | ||
883 | b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF); | ||
884 | b[2] = (FLAC__byte)(min_framesize & 0xFF); | ||
885 | b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF); | ||
886 | b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF); | ||
887 | b[5] = (FLAC__byte)(max_framesize & 0xFF); | ||
888 | if(encoder->private_->seek_callback(encoder, encoder->protected_->streaminfo_offset + min_framesize_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) { | ||
889 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR; | ||
890 | return; | ||
891 | } | ||
892 | if(encoder->private_->write_callback(encoder, b, 6, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
893 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR; | ||
894 | return; | ||
895 | } | ||
896 | } | ||
897 | |||
898 | /* | ||
899 | * Write seektable | ||
900 | */ | ||
901 | if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) { | ||
902 | unsigned i; | ||
903 | |||
904 | FLAC__format_seektable_sort(encoder->private_->seek_table); | ||
905 | |||
906 | FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table)); | ||
907 | |||
908 | if(encoder->private_->seek_callback(encoder, encoder->protected_->seektable_offset + FLAC__STREAM_METADATA_HEADER_LENGTH, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK) { | ||
909 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR; | ||
910 | return; | ||
911 | } | ||
912 | |||
913 | for(i = 0; i < encoder->private_->seek_table->num_points; i++) { | ||
914 | FLAC__uint64 xx; | ||
915 | unsigned x; | ||
916 | xx = encoder->private_->seek_table->points[i].sample_number; | ||
917 | b[7] = (FLAC__byte)xx; xx >>= 8; | ||
918 | b[6] = (FLAC__byte)xx; xx >>= 8; | ||
919 | b[5] = (FLAC__byte)xx; xx >>= 8; | ||
920 | b[4] = (FLAC__byte)xx; xx >>= 8; | ||
921 | b[3] = (FLAC__byte)xx; xx >>= 8; | ||
922 | b[2] = (FLAC__byte)xx; xx >>= 8; | ||
923 | b[1] = (FLAC__byte)xx; xx >>= 8; | ||
924 | b[0] = (FLAC__byte)xx; xx >>= 8; | ||
925 | xx = encoder->private_->seek_table->points[i].stream_offset; | ||
926 | b[15] = (FLAC__byte)xx; xx >>= 8; | ||
927 | b[14] = (FLAC__byte)xx; xx >>= 8; | ||
928 | b[13] = (FLAC__byte)xx; xx >>= 8; | ||
929 | b[12] = (FLAC__byte)xx; xx >>= 8; | ||
930 | b[11] = (FLAC__byte)xx; xx >>= 8; | ||
931 | b[10] = (FLAC__byte)xx; xx >>= 8; | ||
932 | b[9] = (FLAC__byte)xx; xx >>= 8; | ||
933 | b[8] = (FLAC__byte)xx; xx >>= 8; | ||
934 | x = encoder->private_->seek_table->points[i].frame_samples; | ||
935 | b[17] = (FLAC__byte)x; x >>= 8; | ||
936 | b[16] = (FLAC__byte)x; x >>= 8; | ||
937 | if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
938 | encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR; | ||
939 | return; | ||
940 | } | ||
941 | } | ||
942 | } | ||
943 | } | ||
diff --git a/apps/codecs/libFLAC/stream_decoder.c b/apps/codecs/libFLAC/stream_decoder.c new file mode 100644 index 0000000000..845ff90131 --- /dev/null +++ b/apps/codecs/libFLAC/stream_decoder.c | |||
@@ -0,0 +1,2157 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> /* for malloc() */ | ||
34 | #include <string.h> /* for memset/memcpy() */ | ||
35 | #include "FLAC/assert.h" | ||
36 | #include "protected/stream_decoder.h" | ||
37 | #include "private/bitbuffer.h" | ||
38 | #include "private/bitmath.h" | ||
39 | #include "private/cpu.h" | ||
40 | #include "private/crc.h" | ||
41 | #include "private/fixed.h" | ||
42 | #include "private/format.h" | ||
43 | #include "private/lpc.h" | ||
44 | #include "private/memory.h" | ||
45 | |||
46 | #ifdef HAVE_CONFIG_H | ||
47 | #include <config.h> | ||
48 | #endif | ||
49 | |||
50 | #ifdef max | ||
51 | #undef max | ||
52 | #endif | ||
53 | #define max(a,b) ((a)>(b)?(a):(b)) | ||
54 | |||
55 | /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ | ||
56 | #ifdef _MSC_VER | ||
57 | #define FLAC__U64L(x) x | ||
58 | #else | ||
59 | #define FLAC__U64L(x) x##LLU | ||
60 | #endif | ||
61 | |||
62 | /*********************************************************************** | ||
63 | * | ||
64 | * Private static data | ||
65 | * | ||
66 | ***********************************************************************/ | ||
67 | |||
68 | static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; | ||
69 | |||
70 | /*********************************************************************** | ||
71 | * | ||
72 | * Private class method prototypes | ||
73 | * | ||
74 | ***********************************************************************/ | ||
75 | |||
76 | static void set_defaults_(FLAC__StreamDecoder *decoder); | ||
77 | static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels); | ||
78 | static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); | ||
79 | static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); | ||
80 | static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); | ||
81 | static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); | ||
82 | static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); | ||
83 | static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj); | ||
84 | static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj); | ||
85 | static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); | ||
86 | static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder); | ||
87 | static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode); | ||
88 | static FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder); | ||
89 | static FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); | ||
90 | static FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); | ||
91 | static FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode); | ||
92 | static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode); | ||
93 | static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode); | ||
94 | static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual); | ||
95 | static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder); | ||
96 | static FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data); | ||
97 | |||
98 | /*********************************************************************** | ||
99 | * | ||
100 | * Private class data | ||
101 | * | ||
102 | ***********************************************************************/ | ||
103 | |||
104 | typedef struct FLAC__StreamDecoderPrivate { | ||
105 | FLAC__StreamDecoderReadCallback read_callback; | ||
106 | FLAC__StreamDecoderWriteCallback write_callback; | ||
107 | FLAC__StreamDecoderMetadataCallback metadata_callback; | ||
108 | FLAC__StreamDecoderErrorCallback error_callback; | ||
109 | /* generic 32-bit datapath: */ | ||
110 | void (*local_lpc_restore_signal)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
111 | /* generic 64-bit datapath: */ | ||
112 | void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
113 | /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ | ||
114 | void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
115 | /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ | ||
116 | void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | ||
117 | void *client_data; | ||
118 | FLAC__BitBuffer *input; | ||
119 | FLAC__int32 *output[FLAC__MAX_CHANNELS]; | ||
120 | FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ | ||
121 | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; | ||
122 | unsigned output_capacity, output_channels; | ||
123 | FLAC__uint32 last_frame_number; | ||
124 | FLAC__uint32 last_block_size; | ||
125 | FLAC__uint64 samples_decoded; | ||
126 | FLAC__bool has_stream_info, has_seek_table; | ||
127 | FLAC__StreamMetadata stream_info; | ||
128 | FLAC__StreamMetadata seek_table; | ||
129 | FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */ | ||
130 | FLAC__byte *metadata_filter_ids; | ||
131 | unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ | ||
132 | FLAC__Frame frame; | ||
133 | FLAC__bool cached; /* true if there is a byte in lookahead */ | ||
134 | FLAC__CPUInfo cpuinfo; | ||
135 | FLAC__byte header_warmup[2]; /* contains the sync code and reserved bits */ | ||
136 | FLAC__byte lookahead; /* temp storage when we need to look ahead one byte in the stream */ | ||
137 | /* unaligned (original) pointers to allocated data */ | ||
138 | FLAC__int32 *residual_unaligned[FLAC__MAX_CHANNELS]; | ||
139 | } FLAC__StreamDecoderPrivate; | ||
140 | |||
141 | /*********************************************************************** | ||
142 | * | ||
143 | * Public static class data | ||
144 | * | ||
145 | ***********************************************************************/ | ||
146 | |||
147 | FLAC_API const char * const FLAC__StreamDecoderStateString[] = { | ||
148 | "FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", | ||
149 | "FLAC__STREAM_DECODER_READ_METADATA", | ||
150 | "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", | ||
151 | "FLAC__STREAM_DECODER_READ_FRAME", | ||
152 | "FLAC__STREAM_DECODER_END_OF_STREAM", | ||
153 | "FLAC__STREAM_DECODER_ABORTED", | ||
154 | "FLAC__STREAM_DECODER_UNPARSEABLE_STREAM", | ||
155 | "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", | ||
156 | "FLAC__STREAM_DECODER_ALREADY_INITIALIZED", | ||
157 | "FLAC__STREAM_DECODER_INVALID_CALLBACK", | ||
158 | "FLAC__STREAM_DECODER_UNINITIALIZED" | ||
159 | }; | ||
160 | |||
161 | FLAC_API const char * const FLAC__StreamDecoderReadStatusString[] = { | ||
162 | "FLAC__STREAM_DECODER_READ_STATUS_CONTINUE", | ||
163 | "FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM", | ||
164 | "FLAC__STREAM_DECODER_READ_STATUS_ABORT" | ||
165 | }; | ||
166 | |||
167 | FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[] = { | ||
168 | "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", | ||
169 | "FLAC__STREAM_DECODER_WRITE_STATUS_ABORT" | ||
170 | }; | ||
171 | |||
172 | FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = { | ||
173 | "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", | ||
174 | "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", | ||
175 | "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH" | ||
176 | }; | ||
177 | |||
178 | /*********************************************************************** | ||
179 | * | ||
180 | * Class constructor/destructor | ||
181 | * | ||
182 | ***********************************************************************/ | ||
183 | FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new() | ||
184 | { | ||
185 | FLAC__StreamDecoder *decoder; | ||
186 | unsigned i; | ||
187 | |||
188 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
189 | |||
190 | decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder)); | ||
191 | if(decoder == 0) { | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected)); | ||
196 | if(decoder->protected_ == 0) { | ||
197 | free(decoder); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate)); | ||
202 | if(decoder->private_ == 0) { | ||
203 | free(decoder->protected_); | ||
204 | free(decoder); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | decoder->private_->input = FLAC__bitbuffer_new(); | ||
209 | if(decoder->private_->input == 0) { | ||
210 | free(decoder->private_); | ||
211 | free(decoder->protected_); | ||
212 | free(decoder); | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | decoder->private_->metadata_filter_ids_capacity = 16; | ||
217 | if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { | ||
218 | FLAC__bitbuffer_delete(decoder->private_->input); | ||
219 | free(decoder->private_); | ||
220 | free(decoder->protected_); | ||
221 | free(decoder); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
226 | decoder->private_->output[i] = 0; | ||
227 | decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; | ||
228 | } | ||
229 | |||
230 | decoder->private_->output_capacity = 0; | ||
231 | decoder->private_->output_channels = 0; | ||
232 | decoder->private_->has_seek_table = false; | ||
233 | |||
234 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) | ||
235 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&decoder->private_->partitioned_rice_contents[i]); | ||
236 | |||
237 | set_defaults_(decoder); | ||
238 | |||
239 | decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | ||
240 | |||
241 | return decoder; | ||
242 | } | ||
243 | |||
244 | FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) | ||
245 | { | ||
246 | unsigned i; | ||
247 | |||
248 | FLAC__ASSERT(0 != decoder); | ||
249 | FLAC__ASSERT(0 != decoder->protected_); | ||
250 | FLAC__ASSERT(0 != decoder->private_); | ||
251 | FLAC__ASSERT(0 != decoder->private_->input); | ||
252 | |||
253 | FLAC__stream_decoder_finish(decoder); | ||
254 | |||
255 | if(0 != decoder->private_->metadata_filter_ids) | ||
256 | free(decoder->private_->metadata_filter_ids); | ||
257 | |||
258 | FLAC__bitbuffer_delete(decoder->private_->input); | ||
259 | |||
260 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) | ||
261 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&decoder->private_->partitioned_rice_contents[i]); | ||
262 | |||
263 | free(decoder->private_); | ||
264 | free(decoder->protected_); | ||
265 | free(decoder); | ||
266 | } | ||
267 | |||
268 | /*********************************************************************** | ||
269 | * | ||
270 | * Public class methods | ||
271 | * | ||
272 | ***********************************************************************/ | ||
273 | |||
274 | FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_init(FLAC__StreamDecoder *decoder) | ||
275 | { | ||
276 | FLAC__ASSERT(0 != decoder); | ||
277 | |||
278 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
279 | return decoder->protected_->state = FLAC__STREAM_DECODER_ALREADY_INITIALIZED; | ||
280 | |||
281 | if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback) | ||
282 | return decoder->protected_->state = FLAC__STREAM_DECODER_INVALID_CALLBACK; | ||
283 | |||
284 | if(!FLAC__bitbuffer_init(decoder->private_->input)) | ||
285 | return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
286 | |||
287 | decoder->private_->last_frame_number = 0; | ||
288 | decoder->private_->last_block_size = 0; | ||
289 | decoder->private_->samples_decoded = 0; | ||
290 | decoder->private_->has_stream_info = false; | ||
291 | decoder->private_->cached = false; | ||
292 | |||
293 | /* | ||
294 | * get the CPU info and set the function pointers | ||
295 | */ | ||
296 | FLAC__cpu_info(&decoder->private_->cpuinfo); | ||
297 | /* first default to the non-asm routines */ | ||
298 | decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; | ||
299 | decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; | ||
300 | decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; | ||
301 | decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal; | ||
302 | /* now override with asm where appropriate */ | ||
303 | #ifndef FLAC__NO_ASM | ||
304 | if(decoder->private_->cpuinfo.use_asm) { | ||
305 | #ifdef FLAC__CPU_IA32 | ||
306 | FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); | ||
307 | #ifdef FLAC__HAS_NASM | ||
308 | if(decoder->private_->cpuinfo.data.ia32.mmx) { | ||
309 | decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; | ||
310 | decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; | ||
311 | decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx; | ||
312 | } | ||
313 | else { | ||
314 | decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; | ||
315 | decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; | ||
316 | decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32; | ||
317 | } | ||
318 | #endif | ||
319 | #elif defined FLAC__CPU_PPC | ||
320 | FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); | ||
321 | if(decoder->private_->cpuinfo.data.ppc.altivec) { | ||
322 | decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; | ||
323 | decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8; | ||
324 | } | ||
325 | #endif | ||
326 | } | ||
327 | #endif | ||
328 | |||
329 | if(!FLAC__stream_decoder_reset(decoder)) | ||
330 | return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
331 | |||
332 | return decoder->protected_->state; | ||
333 | } | ||
334 | |||
335 | FLAC_API void FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) | ||
336 | { | ||
337 | unsigned i; | ||
338 | FLAC__ASSERT(0 != decoder); | ||
339 | if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) | ||
340 | return; | ||
341 | if(0 != decoder->private_->seek_table.data.seek_table.points) { | ||
342 | free(decoder->private_->seek_table.data.seek_table.points); | ||
343 | decoder->private_->seek_table.data.seek_table.points = 0; | ||
344 | decoder->private_->has_seek_table = false; | ||
345 | } | ||
346 | FLAC__bitbuffer_free(decoder->private_->input); | ||
347 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
348 | /* WATCHOUT: | ||
349 | * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the | ||
350 | * output arrays have a buffer of up to 3 zeroes in front | ||
351 | * (at negative indices) for alignment purposes; we use 4 | ||
352 | * to keep the data well-aligned. | ||
353 | */ | ||
354 | if(0 != decoder->private_->output[i]) { | ||
355 | free(decoder->private_->output[i]-4); | ||
356 | decoder->private_->output[i] = 0; | ||
357 | } | ||
358 | if(0 != decoder->private_->residual_unaligned[i]) { | ||
359 | free(decoder->private_->residual_unaligned[i]); | ||
360 | decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; | ||
361 | } | ||
362 | } | ||
363 | decoder->private_->output_capacity = 0; | ||
364 | decoder->private_->output_channels = 0; | ||
365 | |||
366 | set_defaults_(decoder); | ||
367 | |||
368 | decoder->protected_->state = FLAC__STREAM_DECODER_UNINITIALIZED; | ||
369 | } | ||
370 | |||
371 | FLAC_API FLAC__bool FLAC__stream_decoder_set_read_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderReadCallback value) | ||
372 | { | ||
373 | FLAC__ASSERT(0 != decoder); | ||
374 | FLAC__ASSERT(0 != decoder->private_); | ||
375 | FLAC__ASSERT(0 != decoder->protected_); | ||
376 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
377 | return false; | ||
378 | decoder->private_->read_callback = value; | ||
379 | return true; | ||
380 | } | ||
381 | |||
382 | FLAC_API FLAC__bool FLAC__stream_decoder_set_write_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderWriteCallback value) | ||
383 | { | ||
384 | FLAC__ASSERT(0 != decoder); | ||
385 | FLAC__ASSERT(0 != decoder->private_); | ||
386 | FLAC__ASSERT(0 != decoder->protected_); | ||
387 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
388 | return false; | ||
389 | decoder->private_->write_callback = value; | ||
390 | return true; | ||
391 | } | ||
392 | |||
393 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderMetadataCallback value) | ||
394 | { | ||
395 | FLAC__ASSERT(0 != decoder); | ||
396 | FLAC__ASSERT(0 != decoder->private_); | ||
397 | FLAC__ASSERT(0 != decoder->protected_); | ||
398 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
399 | return false; | ||
400 | decoder->private_->metadata_callback = value; | ||
401 | return true; | ||
402 | } | ||
403 | |||
404 | FLAC_API FLAC__bool FLAC__stream_decoder_set_error_callback(FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorCallback value) | ||
405 | { | ||
406 | FLAC__ASSERT(0 != decoder); | ||
407 | FLAC__ASSERT(0 != decoder->private_); | ||
408 | FLAC__ASSERT(0 != decoder->protected_); | ||
409 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
410 | return false; | ||
411 | decoder->private_->error_callback = value; | ||
412 | return true; | ||
413 | } | ||
414 | |||
415 | FLAC_API FLAC__bool FLAC__stream_decoder_set_client_data(FLAC__StreamDecoder *decoder, void *value) | ||
416 | { | ||
417 | FLAC__ASSERT(0 != decoder); | ||
418 | FLAC__ASSERT(0 != decoder->private_); | ||
419 | FLAC__ASSERT(0 != decoder->protected_); | ||
420 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
421 | return false; | ||
422 | decoder->private_->client_data = value; | ||
423 | return true; | ||
424 | } | ||
425 | |||
426 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) | ||
427 | { | ||
428 | FLAC__ASSERT(0 != decoder); | ||
429 | FLAC__ASSERT(0 != decoder->private_); | ||
430 | FLAC__ASSERT(0 != decoder->protected_); | ||
431 | FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE); | ||
432 | /* double protection */ | ||
433 | if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE) | ||
434 | return false; | ||
435 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
436 | return false; | ||
437 | decoder->private_->metadata_filter[type] = true; | ||
438 | if(type == FLAC__METADATA_TYPE_APPLICATION) | ||
439 | decoder->private_->metadata_filter_ids_count = 0; | ||
440 | return true; | ||
441 | } | ||
442 | |||
443 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) | ||
444 | { | ||
445 | FLAC__ASSERT(0 != decoder); | ||
446 | FLAC__ASSERT(0 != decoder->private_); | ||
447 | FLAC__ASSERT(0 != decoder->protected_); | ||
448 | FLAC__ASSERT(0 != id); | ||
449 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
450 | return false; | ||
451 | |||
452 | if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) | ||
453 | return true; | ||
454 | |||
455 | FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | ||
456 | |||
457 | if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | ||
458 | if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) | ||
459 | return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
460 | decoder->private_->metadata_filter_ids_capacity *= 2; | ||
461 | } | ||
462 | |||
463 | memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); | ||
464 | decoder->private_->metadata_filter_ids_count++; | ||
465 | |||
466 | return true; | ||
467 | } | ||
468 | |||
469 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder) | ||
470 | { | ||
471 | unsigned i; | ||
472 | FLAC__ASSERT(0 != decoder); | ||
473 | FLAC__ASSERT(0 != decoder->private_); | ||
474 | FLAC__ASSERT(0 != decoder->protected_); | ||
475 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
476 | return false; | ||
477 | for(i = 0; i < sizeof(decoder->private_->metadata_filter) / sizeof(decoder->private_->metadata_filter[0]); i++) | ||
478 | decoder->private_->metadata_filter[i] = true; | ||
479 | decoder->private_->metadata_filter_ids_count = 0; | ||
480 | return true; | ||
481 | } | ||
482 | |||
483 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type) | ||
484 | { | ||
485 | FLAC__ASSERT(0 != decoder); | ||
486 | FLAC__ASSERT(0 != decoder->private_); | ||
487 | FLAC__ASSERT(0 != decoder->protected_); | ||
488 | FLAC__ASSERT((unsigned)type <= FLAC__MAX_METADATA_TYPE_CODE); | ||
489 | /* double protection */ | ||
490 | if((unsigned)type > FLAC__MAX_METADATA_TYPE_CODE) | ||
491 | return false; | ||
492 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
493 | return false; | ||
494 | decoder->private_->metadata_filter[type] = false; | ||
495 | if(type == FLAC__METADATA_TYPE_APPLICATION) | ||
496 | decoder->private_->metadata_filter_ids_count = 0; | ||
497 | return true; | ||
498 | } | ||
499 | |||
500 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]) | ||
501 | { | ||
502 | FLAC__ASSERT(0 != decoder); | ||
503 | FLAC__ASSERT(0 != decoder->private_); | ||
504 | FLAC__ASSERT(0 != decoder->protected_); | ||
505 | FLAC__ASSERT(0 != id); | ||
506 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
507 | return false; | ||
508 | |||
509 | if(!decoder->private_->metadata_filter[FLAC__METADATA_TYPE_APPLICATION]) | ||
510 | return true; | ||
511 | |||
512 | FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); | ||
513 | |||
514 | if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { | ||
515 | if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) | ||
516 | return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
517 | decoder->private_->metadata_filter_ids_capacity *= 2; | ||
518 | } | ||
519 | |||
520 | memcpy(decoder->private_->metadata_filter_ids + decoder->private_->metadata_filter_ids_count * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)); | ||
521 | decoder->private_->metadata_filter_ids_count++; | ||
522 | |||
523 | return true; | ||
524 | } | ||
525 | |||
526 | FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder) | ||
527 | { | ||
528 | FLAC__ASSERT(0 != decoder); | ||
529 | FLAC__ASSERT(0 != decoder->private_); | ||
530 | FLAC__ASSERT(0 != decoder->protected_); | ||
531 | if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) | ||
532 | return false; | ||
533 | memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); | ||
534 | decoder->private_->metadata_filter_ids_count = 0; | ||
535 | return true; | ||
536 | } | ||
537 | |||
538 | FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder) | ||
539 | { | ||
540 | FLAC__ASSERT(0 != decoder); | ||
541 | FLAC__ASSERT(0 != decoder->protected_); | ||
542 | return decoder->protected_->state; | ||
543 | } | ||
544 | |||
545 | FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder) | ||
546 | { | ||
547 | return FLAC__StreamDecoderStateString[decoder->protected_->state]; | ||
548 | } | ||
549 | |||
550 | FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder) | ||
551 | { | ||
552 | FLAC__ASSERT(0 != decoder); | ||
553 | FLAC__ASSERT(0 != decoder->protected_); | ||
554 | return decoder->protected_->channels; | ||
555 | } | ||
556 | |||
557 | FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder) | ||
558 | { | ||
559 | FLAC__ASSERT(0 != decoder); | ||
560 | FLAC__ASSERT(0 != decoder->protected_); | ||
561 | return decoder->protected_->channel_assignment; | ||
562 | } | ||
563 | |||
564 | FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder) | ||
565 | { | ||
566 | FLAC__ASSERT(0 != decoder); | ||
567 | FLAC__ASSERT(0 != decoder->protected_); | ||
568 | return decoder->protected_->bits_per_sample; | ||
569 | } | ||
570 | |||
571 | FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder) | ||
572 | { | ||
573 | FLAC__ASSERT(0 != decoder); | ||
574 | FLAC__ASSERT(0 != decoder->protected_); | ||
575 | return decoder->protected_->sample_rate; | ||
576 | } | ||
577 | |||
578 | FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder) | ||
579 | { | ||
580 | FLAC__ASSERT(0 != decoder); | ||
581 | FLAC__ASSERT(0 != decoder->protected_); | ||
582 | return decoder->protected_->blocksize; | ||
583 | } | ||
584 | |||
585 | FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) | ||
586 | { | ||
587 | FLAC__ASSERT(0 != decoder); | ||
588 | FLAC__ASSERT(0 != decoder->private_); | ||
589 | FLAC__ASSERT(0 != decoder->protected_); | ||
590 | |||
591 | if(!FLAC__bitbuffer_clear(decoder->private_->input)) { | ||
592 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
593 | return false; | ||
594 | } | ||
595 | decoder->private_->last_frame_number = 0; | ||
596 | decoder->private_->last_block_size = 0; | ||
597 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
598 | |||
599 | return true; | ||
600 | } | ||
601 | |||
602 | FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) | ||
603 | { | ||
604 | FLAC__ASSERT(0 != decoder); | ||
605 | FLAC__ASSERT(0 != decoder->private_); | ||
606 | FLAC__ASSERT(0 != decoder->protected_); | ||
607 | |||
608 | if(!FLAC__stream_decoder_flush(decoder)) { | ||
609 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
610 | return false; | ||
611 | } | ||
612 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; | ||
613 | |||
614 | decoder->private_->samples_decoded = 0; | ||
615 | |||
616 | return true; | ||
617 | } | ||
618 | |||
619 | FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder) | ||
620 | { | ||
621 | FLAC__bool got_a_frame; | ||
622 | FLAC__ASSERT(0 != decoder); | ||
623 | FLAC__ASSERT(0 != decoder->protected_); | ||
624 | |||
625 | while(1) { | ||
626 | switch(decoder->protected_->state) { | ||
627 | case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: | ||
628 | if(!find_metadata_(decoder)) | ||
629 | return false; /* above function sets the status for us */ | ||
630 | break; | ||
631 | case FLAC__STREAM_DECODER_READ_METADATA: | ||
632 | if(!read_metadata_(decoder)) | ||
633 | return false; /* above function sets the status for us */ | ||
634 | else | ||
635 | return true; | ||
636 | case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: | ||
637 | if(!frame_sync_(decoder)) | ||
638 | return true; /* above function sets the status for us */ | ||
639 | break; | ||
640 | case FLAC__STREAM_DECODER_READ_FRAME: | ||
641 | if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/true)) | ||
642 | return false; /* above function sets the status for us */ | ||
643 | if(got_a_frame) | ||
644 | return true; /* above function sets the status for us */ | ||
645 | break; | ||
646 | case FLAC__STREAM_DECODER_END_OF_STREAM: | ||
647 | case FLAC__STREAM_DECODER_ABORTED: | ||
648 | return true; | ||
649 | default: | ||
650 | FLAC__ASSERT(0); | ||
651 | return false; | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | |||
656 | FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder) | ||
657 | { | ||
658 | FLAC__ASSERT(0 != decoder); | ||
659 | FLAC__ASSERT(0 != decoder->protected_); | ||
660 | |||
661 | while(1) { | ||
662 | switch(decoder->protected_->state) { | ||
663 | case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: | ||
664 | if(!find_metadata_(decoder)) | ||
665 | return false; /* above function sets the status for us */ | ||
666 | break; | ||
667 | case FLAC__STREAM_DECODER_READ_METADATA: | ||
668 | if(!read_metadata_(decoder)) | ||
669 | return false; /* above function sets the status for us */ | ||
670 | break; | ||
671 | case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: | ||
672 | case FLAC__STREAM_DECODER_READ_FRAME: | ||
673 | case FLAC__STREAM_DECODER_END_OF_STREAM: | ||
674 | case FLAC__STREAM_DECODER_ABORTED: | ||
675 | return true; | ||
676 | default: | ||
677 | FLAC__ASSERT(0); | ||
678 | return false; | ||
679 | } | ||
680 | } | ||
681 | } | ||
682 | |||
683 | FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder) | ||
684 | { | ||
685 | FLAC__bool dummy; | ||
686 | FLAC__ASSERT(0 != decoder); | ||
687 | FLAC__ASSERT(0 != decoder->protected_); | ||
688 | |||
689 | while(1) { | ||
690 | switch(decoder->protected_->state) { | ||
691 | case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: | ||
692 | if(!find_metadata_(decoder)) | ||
693 | return false; /* above function sets the status for us */ | ||
694 | break; | ||
695 | case FLAC__STREAM_DECODER_READ_METADATA: | ||
696 | if(!read_metadata_(decoder)) | ||
697 | return false; /* above function sets the status for us */ | ||
698 | break; | ||
699 | case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: | ||
700 | if(!frame_sync_(decoder)) | ||
701 | return true; /* above function sets the status for us */ | ||
702 | break; | ||
703 | case FLAC__STREAM_DECODER_READ_FRAME: | ||
704 | if(!read_frame_(decoder, &dummy, /*do_full_decode=*/true)) | ||
705 | return false; /* above function sets the status for us */ | ||
706 | break; | ||
707 | case FLAC__STREAM_DECODER_END_OF_STREAM: | ||
708 | case FLAC__STREAM_DECODER_ABORTED: | ||
709 | return true; | ||
710 | default: | ||
711 | FLAC__ASSERT(0); | ||
712 | return false; | ||
713 | } | ||
714 | } | ||
715 | } | ||
716 | |||
717 | FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder) | ||
718 | { | ||
719 | FLAC__bool got_a_frame; | ||
720 | FLAC__ASSERT(0 != decoder); | ||
721 | FLAC__ASSERT(0 != decoder->protected_); | ||
722 | |||
723 | while(1) { | ||
724 | switch(decoder->protected_->state) { | ||
725 | case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: | ||
726 | case FLAC__STREAM_DECODER_READ_METADATA: | ||
727 | return false; /* above function sets the status for us */ | ||
728 | case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: | ||
729 | if(!frame_sync_(decoder)) | ||
730 | return true; /* above function sets the status for us */ | ||
731 | break; | ||
732 | case FLAC__STREAM_DECODER_READ_FRAME: | ||
733 | if(!read_frame_(decoder, &got_a_frame, /*do_full_decode=*/false)) | ||
734 | return false; /* above function sets the status for us */ | ||
735 | if(got_a_frame) | ||
736 | return true; /* above function sets the status for us */ | ||
737 | break; | ||
738 | case FLAC__STREAM_DECODER_END_OF_STREAM: | ||
739 | case FLAC__STREAM_DECODER_ABORTED: | ||
740 | return true; | ||
741 | default: | ||
742 | FLAC__ASSERT(0); | ||
743 | return false; | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | |||
748 | /*********************************************************************** | ||
749 | * | ||
750 | * Protected class methods | ||
751 | * | ||
752 | ***********************************************************************/ | ||
753 | |||
754 | unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder) | ||
755 | { | ||
756 | FLAC__ASSERT(0 != decoder); | ||
757 | return FLAC__bitbuffer_get_input_bytes_unconsumed(decoder->private_->input); | ||
758 | } | ||
759 | |||
760 | /*********************************************************************** | ||
761 | * | ||
762 | * Private class methods | ||
763 | * | ||
764 | ***********************************************************************/ | ||
765 | |||
766 | void set_defaults_(FLAC__StreamDecoder *decoder) | ||
767 | { | ||
768 | decoder->private_->read_callback = 0; | ||
769 | decoder->private_->write_callback = 0; | ||
770 | decoder->private_->metadata_callback = 0; | ||
771 | decoder->private_->error_callback = 0; | ||
772 | decoder->private_->client_data = 0; | ||
773 | |||
774 | memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter)); | ||
775 | decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true; | ||
776 | decoder->private_->metadata_filter_ids_count = 0; | ||
777 | } | ||
778 | |||
779 | FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigned channels) | ||
780 | { | ||
781 | unsigned i; | ||
782 | FLAC__int32 *tmp; | ||
783 | |||
784 | if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) | ||
785 | return true; | ||
786 | |||
787 | /* simply using realloc() is not practical because the number of channels may change mid-stream */ | ||
788 | |||
789 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
790 | if(0 != decoder->private_->output[i]) { | ||
791 | free(decoder->private_->output[i]-4); | ||
792 | decoder->private_->output[i] = 0; | ||
793 | } | ||
794 | if(0 != decoder->private_->residual_unaligned[i]) { | ||
795 | free(decoder->private_->residual_unaligned[i]); | ||
796 | decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; | ||
797 | } | ||
798 | } | ||
799 | |||
800 | for(i = 0; i < channels; i++) { | ||
801 | /* WATCHOUT: | ||
802 | * FLAC__lpc_restore_signal_asm_ia32_mmx() requires that the | ||
803 | * output arrays have a buffer of up to 3 zeroes in front | ||
804 | * (at negative indices) for alignment purposes; we use 4 | ||
805 | * to keep the data well-aligned. | ||
806 | */ | ||
807 | tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4)); | ||
808 | if(tmp == 0) { | ||
809 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
810 | return false; | ||
811 | } | ||
812 | memset(tmp, 0, sizeof(FLAC__int32)*4); | ||
813 | decoder->private_->output[i] = tmp + 4; | ||
814 | |||
815 | /* WATCHOUT: | ||
816 | * minimum of quadword alignment for PPC vector optimizations is REQUIRED: | ||
817 | */ | ||
818 | if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { | ||
819 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
820 | return false; | ||
821 | } | ||
822 | } | ||
823 | |||
824 | decoder->private_->output_capacity = size; | ||
825 | decoder->private_->output_channels = channels; | ||
826 | |||
827 | return true; | ||
828 | } | ||
829 | |||
830 | FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) | ||
831 | { | ||
832 | unsigned i; | ||
833 | |||
834 | FLAC__ASSERT(0 != decoder); | ||
835 | FLAC__ASSERT(0 != decoder->private_); | ||
836 | |||
837 | for(i = 0; i < decoder->private_->metadata_filter_ids_count; i++) | ||
838 | if(0 == memcmp(decoder->private_->metadata_filter_ids + i * (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), id, (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))) | ||
839 | return true; | ||
840 | |||
841 | return false; | ||
842 | } | ||
843 | |||
844 | FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) | ||
845 | { | ||
846 | FLAC__uint32 x; | ||
847 | unsigned i, id; | ||
848 | FLAC__bool first = true; | ||
849 | |||
850 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
851 | |||
852 | for(i = id = 0; i < 4; ) { | ||
853 | if(decoder->private_->cached) { | ||
854 | x = (FLAC__uint32)decoder->private_->lookahead; | ||
855 | decoder->private_->cached = false; | ||
856 | } | ||
857 | else { | ||
858 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
859 | return false; /* the read_callback_ sets the state for us */ | ||
860 | } | ||
861 | if(x == FLAC__STREAM_SYNC_STRING[i]) { | ||
862 | first = true; | ||
863 | i++; | ||
864 | id = 0; | ||
865 | continue; | ||
866 | } | ||
867 | if(x == ID3V2_TAG_[id]) { | ||
868 | id++; | ||
869 | i = 0; | ||
870 | if(id == 3) { | ||
871 | if(!skip_id3v2_tag_(decoder)) | ||
872 | return false; /* the read_callback_ sets the state for us */ | ||
873 | } | ||
874 | continue; | ||
875 | } | ||
876 | if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ | ||
877 | decoder->private_->header_warmup[0] = (FLAC__byte)x; | ||
878 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
879 | return false; /* the read_callback_ sets the state for us */ | ||
880 | |||
881 | /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ | ||
882 | /* else we have to check if the second byte is the end of a sync code */ | ||
883 | if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ | ||
884 | decoder->private_->lookahead = (FLAC__byte)x; | ||
885 | decoder->private_->cached = true; | ||
886 | } | ||
887 | else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ | ||
888 | decoder->private_->header_warmup[1] = (FLAC__byte)x; | ||
889 | decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | ||
890 | return true; | ||
891 | } | ||
892 | } | ||
893 | i = 0; | ||
894 | if(first) { | ||
895 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
896 | first = false; | ||
897 | } | ||
898 | } | ||
899 | |||
900 | decoder->protected_->state = FLAC__STREAM_DECODER_READ_METADATA; | ||
901 | return true; | ||
902 | } | ||
903 | |||
904 | FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) | ||
905 | { | ||
906 | FLAC__bool is_last; | ||
907 | FLAC__uint32 i, x, type, length; | ||
908 | |||
909 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
910 | |||
911 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_IS_LAST_LEN, read_callback_, decoder)) | ||
912 | return false; /* the read_callback_ sets the state for us */ | ||
913 | is_last = x? true : false; | ||
914 | |||
915 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &type, FLAC__STREAM_METADATA_TYPE_LEN, read_callback_, decoder)) | ||
916 | return false; /* the read_callback_ sets the state for us */ | ||
917 | |||
918 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &length, FLAC__STREAM_METADATA_LENGTH_LEN, read_callback_, decoder)) | ||
919 | return false; /* the read_callback_ sets the state for us */ | ||
920 | |||
921 | if(type == FLAC__METADATA_TYPE_STREAMINFO) { | ||
922 | if(!read_metadata_streaminfo_(decoder, is_last, length)) | ||
923 | return false; | ||
924 | |||
925 | decoder->private_->has_stream_info = true; | ||
926 | if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO]) | ||
927 | decoder->private_->metadata_callback(decoder, &decoder->private_->stream_info, decoder->private_->client_data); | ||
928 | } | ||
929 | else if(type == FLAC__METADATA_TYPE_SEEKTABLE) { | ||
930 | if(!read_metadata_seektable_(decoder, is_last, length)) | ||
931 | return false; | ||
932 | |||
933 | decoder->private_->has_seek_table = true; | ||
934 | if(decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE]) | ||
935 | decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); | ||
936 | } | ||
937 | else { | ||
938 | FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; | ||
939 | unsigned real_length = length; | ||
940 | FLAC__StreamMetadata block; | ||
941 | |||
942 | block.is_last = is_last; | ||
943 | block.type = (FLAC__MetadataType)type; | ||
944 | block.length = length; | ||
945 | |||
946 | if(type == FLAC__METADATA_TYPE_APPLICATION) { | ||
947 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8, read_callback_, decoder)) | ||
948 | return false; /* the read_callback_ sets the state for us */ | ||
949 | |||
950 | real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; | ||
951 | |||
952 | if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) | ||
953 | skip_it = !skip_it; | ||
954 | } | ||
955 | |||
956 | if(skip_it) { | ||
957 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, real_length, read_callback_, decoder)) | ||
958 | return false; /* the read_callback_ sets the state for us */ | ||
959 | } | ||
960 | else { | ||
961 | switch(type) { | ||
962 | case FLAC__METADATA_TYPE_PADDING: | ||
963 | /* skip the padding bytes */ | ||
964 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, real_length, read_callback_, decoder)) | ||
965 | return false; /* the read_callback_ sets the state for us */ | ||
966 | break; | ||
967 | case FLAC__METADATA_TYPE_APPLICATION: | ||
968 | /* remember, we read the ID already */ | ||
969 | if(real_length > 0) { | ||
970 | if(0 == (block.data.application.data = (FLAC__byte*)malloc(real_length))) { | ||
971 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
972 | return false; | ||
973 | } | ||
974 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length, read_callback_, decoder)) | ||
975 | return false; /* the read_callback_ sets the state for us */ | ||
976 | } | ||
977 | else | ||
978 | block.data.application.data = 0; | ||
979 | break; | ||
980 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
981 | if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) | ||
982 | return false; | ||
983 | break; | ||
984 | case FLAC__METADATA_TYPE_CUESHEET: | ||
985 | if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) | ||
986 | return false; | ||
987 | break; | ||
988 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
989 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
990 | FLAC__ASSERT(0); | ||
991 | break; | ||
992 | default: | ||
993 | if(real_length > 0) { | ||
994 | if(0 == (block.data.unknown.data = (FLAC__byte*)malloc(real_length))) { | ||
995 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
996 | return false; | ||
997 | } | ||
998 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length, read_callback_, decoder)) | ||
999 | return false; /* the read_callback_ sets the state for us */ | ||
1000 | } | ||
1001 | else | ||
1002 | block.data.unknown.data = 0; | ||
1003 | break; | ||
1004 | } | ||
1005 | decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); | ||
1006 | |||
1007 | /* now we have to free any malloc'ed data in the block */ | ||
1008 | switch(type) { | ||
1009 | case FLAC__METADATA_TYPE_PADDING: | ||
1010 | break; | ||
1011 | case FLAC__METADATA_TYPE_APPLICATION: | ||
1012 | if(0 != block.data.application.data) | ||
1013 | free(block.data.application.data); | ||
1014 | break; | ||
1015 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
1016 | if(0 != block.data.vorbis_comment.vendor_string.entry) | ||
1017 | free(block.data.vorbis_comment.vendor_string.entry); | ||
1018 | if(block.data.vorbis_comment.num_comments > 0) | ||
1019 | for(i = 0; i < block.data.vorbis_comment.num_comments; i++) | ||
1020 | if(0 != block.data.vorbis_comment.comments[i].entry) | ||
1021 | free(block.data.vorbis_comment.comments[i].entry); | ||
1022 | if(0 != block.data.vorbis_comment.comments) | ||
1023 | free(block.data.vorbis_comment.comments); | ||
1024 | break; | ||
1025 | case FLAC__METADATA_TYPE_CUESHEET: | ||
1026 | if(block.data.cue_sheet.num_tracks > 0) | ||
1027 | for(i = 0; i < block.data.cue_sheet.num_tracks; i++) | ||
1028 | if(0 != block.data.cue_sheet.tracks[i].indices) | ||
1029 | free(block.data.cue_sheet.tracks[i].indices); | ||
1030 | if(0 != block.data.cue_sheet.tracks) | ||
1031 | free(block.data.cue_sheet.tracks); | ||
1032 | break; | ||
1033 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
1034 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
1035 | FLAC__ASSERT(0); | ||
1036 | default: | ||
1037 | if(0 != block.data.unknown.data) | ||
1038 | free(block.data.unknown.data); | ||
1039 | break; | ||
1040 | } | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | if(is_last) | ||
1045 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1046 | |||
1047 | return true; | ||
1048 | } | ||
1049 | |||
1050 | FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length) | ||
1051 | { | ||
1052 | FLAC__uint32 x; | ||
1053 | unsigned bits, used_bits = 0; | ||
1054 | |||
1055 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
1056 | |||
1057 | decoder->private_->stream_info.type = FLAC__METADATA_TYPE_STREAMINFO; | ||
1058 | decoder->private_->stream_info.is_last = is_last; | ||
1059 | decoder->private_->stream_info.length = length; | ||
1060 | |||
1061 | bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; | ||
1062 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, bits, read_callback_, decoder)) | ||
1063 | return false; /* the read_callback_ sets the state for us */ | ||
1064 | decoder->private_->stream_info.data.stream_info.min_blocksize = x; | ||
1065 | used_bits += bits; | ||
1066 | |||
1067 | bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; | ||
1068 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN, read_callback_, decoder)) | ||
1069 | return false; /* the read_callback_ sets the state for us */ | ||
1070 | decoder->private_->stream_info.data.stream_info.max_blocksize = x; | ||
1071 | used_bits += bits; | ||
1072 | |||
1073 | bits = FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; | ||
1074 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN, read_callback_, decoder)) | ||
1075 | return false; /* the read_callback_ sets the state for us */ | ||
1076 | decoder->private_->stream_info.data.stream_info.min_framesize = x; | ||
1077 | used_bits += bits; | ||
1078 | |||
1079 | bits = FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; | ||
1080 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN, read_callback_, decoder)) | ||
1081 | return false; /* the read_callback_ sets the state for us */ | ||
1082 | decoder->private_->stream_info.data.stream_info.max_framesize = x; | ||
1083 | used_bits += bits; | ||
1084 | |||
1085 | bits = FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; | ||
1086 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN, read_callback_, decoder)) | ||
1087 | return false; /* the read_callback_ sets the state for us */ | ||
1088 | decoder->private_->stream_info.data.stream_info.sample_rate = x; | ||
1089 | used_bits += bits; | ||
1090 | |||
1091 | bits = FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; | ||
1092 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN, read_callback_, decoder)) | ||
1093 | return false; /* the read_callback_ sets the state for us */ | ||
1094 | decoder->private_->stream_info.data.stream_info.channels = x+1; | ||
1095 | used_bits += bits; | ||
1096 | |||
1097 | bits = FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; | ||
1098 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN, read_callback_, decoder)) | ||
1099 | return false; /* the read_callback_ sets the state for us */ | ||
1100 | decoder->private_->stream_info.data.stream_info.bits_per_sample = x+1; | ||
1101 | used_bits += bits; | ||
1102 | |||
1103 | bits = FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; | ||
1104 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &decoder->private_->stream_info.data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN, read_callback_, decoder)) | ||
1105 | return false; /* the read_callback_ sets the state for us */ | ||
1106 | used_bits += bits; | ||
1107 | |||
1108 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, decoder->private_->stream_info.data.stream_info.md5sum, 16, read_callback_, decoder)) | ||
1109 | return false; /* the read_callback_ sets the state for us */ | ||
1110 | used_bits += 16*8; | ||
1111 | |||
1112 | /* skip the rest of the block */ | ||
1113 | FLAC__ASSERT(used_bits % 8 == 0); | ||
1114 | length -= (used_bits / 8); | ||
1115 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, length, read_callback_, decoder)) | ||
1116 | return false; /* the read_callback_ sets the state for us */ | ||
1117 | |||
1118 | return true; | ||
1119 | } | ||
1120 | |||
1121 | FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length) | ||
1122 | { | ||
1123 | FLAC__uint32 i, x; | ||
1124 | FLAC__uint64 xx; | ||
1125 | |||
1126 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
1127 | |||
1128 | decoder->private_->seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE; | ||
1129 | decoder->private_->seek_table.is_last = is_last; | ||
1130 | decoder->private_->seek_table.length = length; | ||
1131 | |||
1132 | decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; | ||
1133 | |||
1134 | /* use realloc since we may pass through here several times (e.g. after seeking) */ | ||
1135 | if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) { | ||
1136 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1137 | return false; | ||
1138 | } | ||
1139 | for(i = 0; i < decoder->private_->seek_table.data.seek_table.num_points; i++) { | ||
1140 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN, read_callback_, decoder)) | ||
1141 | return false; /* the read_callback_ sets the state for us */ | ||
1142 | decoder->private_->seek_table.data.seek_table.points[i].sample_number = xx; | ||
1143 | |||
1144 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &xx, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN, read_callback_, decoder)) | ||
1145 | return false; /* the read_callback_ sets the state for us */ | ||
1146 | decoder->private_->seek_table.data.seek_table.points[i].stream_offset = xx; | ||
1147 | |||
1148 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN, read_callback_, decoder)) | ||
1149 | return false; /* the read_callback_ sets the state for us */ | ||
1150 | decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x; | ||
1151 | } | ||
1152 | length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH); | ||
1153 | /* if there is a partial point left, skip over it */ | ||
1154 | if(length > 0) { | ||
1155 | /*@@@ do an error_callback() here? there's an argument for either way */ | ||
1156 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, length, read_callback_, decoder)) | ||
1157 | return false; /* the read_callback_ sets the state for us */ | ||
1158 | } | ||
1159 | |||
1160 | return true; | ||
1161 | } | ||
1162 | |||
1163 | FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj) | ||
1164 | { | ||
1165 | FLAC__uint32 i; | ||
1166 | |||
1167 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
1168 | |||
1169 | /* read vendor string */ | ||
1170 | FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); | ||
1171 | if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length, read_callback_, decoder)) | ||
1172 | return false; /* the read_callback_ sets the state for us */ | ||
1173 | if(obj->vendor_string.length > 0) { | ||
1174 | if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) { | ||
1175 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1176 | return false; | ||
1177 | } | ||
1178 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length, read_callback_, decoder)) | ||
1179 | return false; /* the read_callback_ sets the state for us */ | ||
1180 | obj->vendor_string.entry[obj->vendor_string.length] = '\0'; | ||
1181 | } | ||
1182 | else | ||
1183 | obj->vendor_string.entry = 0; | ||
1184 | |||
1185 | /* read num comments */ | ||
1186 | FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); | ||
1187 | if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->num_comments, read_callback_, decoder)) | ||
1188 | return false; /* the read_callback_ sets the state for us */ | ||
1189 | |||
1190 | /* read comments */ | ||
1191 | if(obj->num_comments > 0) { | ||
1192 | if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { | ||
1193 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1194 | return false; | ||
1195 | } | ||
1196 | for(i = 0; i < obj->num_comments; i++) { | ||
1197 | FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); | ||
1198 | if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->comments[i].length, read_callback_, decoder)) | ||
1199 | return false; /* the read_callback_ sets the state for us */ | ||
1200 | if(obj->comments[i].length > 0) { | ||
1201 | if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) { | ||
1202 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1203 | return false; | ||
1204 | } | ||
1205 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length, read_callback_, decoder)) | ||
1206 | return false; /* the read_callback_ sets the state for us */ | ||
1207 | obj->comments[i].entry[obj->comments[i].length] = '\0'; | ||
1208 | } | ||
1209 | else | ||
1210 | obj->comments[i].entry = 0; | ||
1211 | } | ||
1212 | } | ||
1213 | else { | ||
1214 | obj->comments = 0; | ||
1215 | } | ||
1216 | |||
1217 | return true; | ||
1218 | } | ||
1219 | |||
1220 | FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj) | ||
1221 | { | ||
1222 | FLAC__uint32 i, j, x; | ||
1223 | |||
1224 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
1225 | |||
1226 | memset(obj, 0, sizeof(FLAC__StreamMetadata_CueSheet)); | ||
1227 | |||
1228 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | ||
1229 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8, read_callback_, decoder)) | ||
1230 | return false; /* the read_callback_ sets the state for us */ | ||
1231 | |||
1232 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &obj->lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN, read_callback_, decoder)) | ||
1233 | return false; /* the read_callback_ sets the state for us */ | ||
1234 | |||
1235 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN, read_callback_, decoder)) | ||
1236 | return false; /* the read_callback_ sets the state for us */ | ||
1237 | obj->is_cd = x? true : false; | ||
1238 | |||
1239 | if(!FLAC__bitbuffer_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN, read_callback_, decoder)) | ||
1240 | return false; /* the read_callback_ sets the state for us */ | ||
1241 | |||
1242 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN, read_callback_, decoder)) | ||
1243 | return false; /* the read_callback_ sets the state for us */ | ||
1244 | obj->num_tracks = x; | ||
1245 | |||
1246 | if(obj->num_tracks > 0) { | ||
1247 | if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { | ||
1248 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1249 | return false; | ||
1250 | } | ||
1251 | for(i = 0; i < obj->num_tracks; i++) { | ||
1252 | FLAC__StreamMetadata_CueSheet_Track *track = &obj->tracks[i]; | ||
1253 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN, read_callback_, decoder)) | ||
1254 | return false; /* the read_callback_ sets the state for us */ | ||
1255 | |||
1256 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN, read_callback_, decoder)) | ||
1257 | return false; /* the read_callback_ sets the state for us */ | ||
1258 | track->number = (FLAC__byte)x; | ||
1259 | |||
1260 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | ||
1261 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8, read_callback_, decoder)) | ||
1262 | return false; /* the read_callback_ sets the state for us */ | ||
1263 | |||
1264 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN, read_callback_, decoder)) | ||
1265 | return false; /* the read_callback_ sets the state for us */ | ||
1266 | track->type = x; | ||
1267 | |||
1268 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN, read_callback_, decoder)) | ||
1269 | return false; /* the read_callback_ sets the state for us */ | ||
1270 | track->pre_emphasis = x; | ||
1271 | |||
1272 | if(!FLAC__bitbuffer_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN, read_callback_, decoder)) | ||
1273 | return false; /* the read_callback_ sets the state for us */ | ||
1274 | |||
1275 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN, read_callback_, decoder)) | ||
1276 | return false; /* the read_callback_ sets the state for us */ | ||
1277 | track->num_indices = (FLAC__byte)x; | ||
1278 | |||
1279 | if(track->num_indices > 0) { | ||
1280 | if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { | ||
1281 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
1282 | return false; | ||
1283 | } | ||
1284 | for(j = 0; j < track->num_indices; j++) { | ||
1285 | FLAC__StreamMetadata_CueSheet_Index *index = &track->indices[j]; | ||
1286 | if(!FLAC__bitbuffer_read_raw_uint64(decoder->private_->input, &index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN, read_callback_, decoder)) | ||
1287 | return false; /* the read_callback_ sets the state for us */ | ||
1288 | |||
1289 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN, read_callback_, decoder)) | ||
1290 | return false; /* the read_callback_ sets the state for us */ | ||
1291 | index->number = (FLAC__byte)x; | ||
1292 | |||
1293 | if(!FLAC__bitbuffer_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN, read_callback_, decoder)) | ||
1294 | return false; /* the read_callback_ sets the state for us */ | ||
1295 | } | ||
1296 | } | ||
1297 | } | ||
1298 | } | ||
1299 | |||
1300 | return true; | ||
1301 | } | ||
1302 | |||
1303 | FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder) | ||
1304 | { | ||
1305 | FLAC__uint32 x; | ||
1306 | unsigned i, skip; | ||
1307 | |||
1308 | /* skip the version and flags bytes */ | ||
1309 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 24, read_callback_, decoder)) | ||
1310 | return false; /* the read_callback_ sets the state for us */ | ||
1311 | /* get the size (in bytes) to skip */ | ||
1312 | skip = 0; | ||
1313 | for(i = 0; i < 4; i++) { | ||
1314 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1315 | return false; /* the read_callback_ sets the state for us */ | ||
1316 | skip <<= 7; | ||
1317 | skip |= (x & 0x7f); | ||
1318 | } | ||
1319 | /* skip the rest of the tag */ | ||
1320 | if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, 0, skip, read_callback_, decoder)) | ||
1321 | return false; /* the read_callback_ sets the state for us */ | ||
1322 | return true; | ||
1323 | } | ||
1324 | |||
1325 | FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) | ||
1326 | { | ||
1327 | FLAC__uint32 x; | ||
1328 | FLAC__bool first = true; | ||
1329 | |||
1330 | /* If we know the total number of samples in the stream, stop if we've read that many. */ | ||
1331 | /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */ | ||
1332 | if(decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.total_samples) { | ||
1333 | if(decoder->private_->samples_decoded >= decoder->private_->stream_info.data.stream_info.total_samples) { | ||
1334 | decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; | ||
1335 | return true; | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1339 | /* make sure we're byte aligned */ | ||
1340 | if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) { | ||
1341 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder)) | ||
1342 | return false; /* the read_callback_ sets the state for us */ | ||
1343 | } | ||
1344 | |||
1345 | while(1) { | ||
1346 | if(decoder->private_->cached) { | ||
1347 | x = (FLAC__uint32)decoder->private_->lookahead; | ||
1348 | decoder->private_->cached = false; | ||
1349 | } | ||
1350 | else { | ||
1351 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1352 | return false; /* the read_callback_ sets the state for us */ | ||
1353 | } | ||
1354 | if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ | ||
1355 | decoder->private_->header_warmup[0] = (FLAC__byte)x; | ||
1356 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1357 | return false; /* the read_callback_ sets the state for us */ | ||
1358 | |||
1359 | /* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */ | ||
1360 | /* else we have to check if the second byte is the end of a sync code */ | ||
1361 | if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ | ||
1362 | decoder->private_->lookahead = (FLAC__byte)x; | ||
1363 | decoder->private_->cached = true; | ||
1364 | } | ||
1365 | else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ | ||
1366 | decoder->private_->header_warmup[1] = (FLAC__byte)x; | ||
1367 | decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; | ||
1368 | return true; | ||
1369 | } | ||
1370 | } | ||
1371 | if(first) { | ||
1372 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
1373 | first = false; | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1377 | return true; | ||
1378 | } | ||
1379 | |||
1380 | FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode) | ||
1381 | { | ||
1382 | unsigned channel; | ||
1383 | unsigned i; | ||
1384 | FLAC__int32 mid, side, left, right; | ||
1385 | FLAC__uint16 frame_crc; /* the one we calculate from the input stream */ | ||
1386 | FLAC__uint32 x; | ||
1387 | |||
1388 | *got_a_frame = false; | ||
1389 | |||
1390 | /* init the CRC */ | ||
1391 | frame_crc = 0; | ||
1392 | FLAC__CRC16_UPDATE(decoder->private_->header_warmup[0], frame_crc); | ||
1393 | FLAC__CRC16_UPDATE(decoder->private_->header_warmup[1], frame_crc); | ||
1394 | FLAC__bitbuffer_reset_read_crc16(decoder->private_->input, frame_crc); | ||
1395 | |||
1396 | if(!read_frame_header_(decoder)) | ||
1397 | return false; | ||
1398 | if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) | ||
1399 | return true; | ||
1400 | if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) | ||
1401 | return false; | ||
1402 | for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { | ||
1403 | /* | ||
1404 | * first figure the correct bits-per-sample of the subframe | ||
1405 | */ | ||
1406 | unsigned bps = decoder->private_->frame.header.bits_per_sample; | ||
1407 | switch(decoder->private_->frame.header.channel_assignment) { | ||
1408 | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | ||
1409 | /* no adjustment needed */ | ||
1410 | break; | ||
1411 | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | ||
1412 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1413 | if(channel == 1) | ||
1414 | bps++; | ||
1415 | break; | ||
1416 | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | ||
1417 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1418 | if(channel == 0) | ||
1419 | bps++; | ||
1420 | break; | ||
1421 | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | ||
1422 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1423 | if(channel == 1) | ||
1424 | bps++; | ||
1425 | break; | ||
1426 | default: | ||
1427 | FLAC__ASSERT(0); | ||
1428 | } | ||
1429 | /* | ||
1430 | * now read it | ||
1431 | */ | ||
1432 | if(!read_subframe_(decoder, channel, bps, do_full_decode)) | ||
1433 | return false; | ||
1434 | if(decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME) { | ||
1435 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1436 | return true; | ||
1437 | } | ||
1438 | } | ||
1439 | if(!read_zero_padding_(decoder)) | ||
1440 | return false; | ||
1441 | |||
1442 | /* | ||
1443 | * Read the frame CRC-16 from the footer and check | ||
1444 | */ | ||
1445 | frame_crc = FLAC__bitbuffer_get_read_crc16(decoder->private_->input); | ||
1446 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder)) | ||
1447 | return false; /* the read_callback_ sets the state for us */ | ||
1448 | if(frame_crc == (FLAC__uint16)x) { | ||
1449 | if(do_full_decode) { | ||
1450 | /* Undo any special channel coding */ | ||
1451 | switch(decoder->private_->frame.header.channel_assignment) { | ||
1452 | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | ||
1453 | /* do nothing */ | ||
1454 | break; | ||
1455 | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | ||
1456 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1457 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) | ||
1458 | decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; | ||
1459 | break; | ||
1460 | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | ||
1461 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1462 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) | ||
1463 | decoder->private_->output[0][i] += decoder->private_->output[1][i]; | ||
1464 | break; | ||
1465 | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | ||
1466 | FLAC__ASSERT(decoder->private_->frame.header.channels == 2); | ||
1467 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { | ||
1468 | mid = decoder->private_->output[0][i]; | ||
1469 | side = decoder->private_->output[1][i]; | ||
1470 | mid <<= 1; | ||
1471 | if(side & 1) /* i.e. if 'side' is odd... */ | ||
1472 | mid++; | ||
1473 | left = mid + side; | ||
1474 | right = mid - side; | ||
1475 | decoder->private_->output[0][i] = left >> 1; | ||
1476 | decoder->private_->output[1][i] = right >> 1; | ||
1477 | } | ||
1478 | break; | ||
1479 | default: | ||
1480 | FLAC__ASSERT(0); | ||
1481 | break; | ||
1482 | } | ||
1483 | } | ||
1484 | } | ||
1485 | else { | ||
1486 | /* Bad frame, emit error and zero the output signal */ | ||
1487 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, decoder->private_->client_data); | ||
1488 | if(do_full_decode) { | ||
1489 | for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { | ||
1490 | memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); | ||
1491 | } | ||
1492 | } | ||
1493 | } | ||
1494 | |||
1495 | *got_a_frame = true; | ||
1496 | |||
1497 | /* put the latest values into the public section of the decoder instance */ | ||
1498 | decoder->protected_->channels = decoder->private_->frame.header.channels; | ||
1499 | decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; | ||
1500 | decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; | ||
1501 | decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; | ||
1502 | decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; | ||
1503 | |||
1504 | FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); | ||
1505 | decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; | ||
1506 | |||
1507 | /* write it */ | ||
1508 | if(do_full_decode) { | ||
1509 | if(decoder->private_->write_callback(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output, decoder->private_->client_data) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) | ||
1510 | return false; | ||
1511 | } | ||
1512 | |||
1513 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1514 | return true; | ||
1515 | } | ||
1516 | |||
1517 | FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) | ||
1518 | { | ||
1519 | FLAC__uint32 x; | ||
1520 | FLAC__uint64 xx; | ||
1521 | unsigned i, blocksize_hint = 0, sample_rate_hint = 0; | ||
1522 | FLAC__byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */ | ||
1523 | unsigned raw_header_len; | ||
1524 | FLAC__bool is_unparseable = false; | ||
1525 | const FLAC__bool is_known_variable_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize != decoder->private_->stream_info.data.stream_info.max_blocksize); | ||
1526 | const FLAC__bool is_known_fixed_blocksize_stream = (decoder->private_->has_stream_info && decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize); | ||
1527 | |||
1528 | FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)); | ||
1529 | |||
1530 | /* init the raw header with the saved bits from synchronization */ | ||
1531 | raw_header[0] = decoder->private_->header_warmup[0]; | ||
1532 | raw_header[1] = decoder->private_->header_warmup[1]; | ||
1533 | raw_header_len = 2; | ||
1534 | |||
1535 | /* | ||
1536 | * check to make sure that the reserved bits are 0 | ||
1537 | */ | ||
1538 | if(raw_header[1] & 0x03) { /* MAGIC NUMBER */ | ||
1539 | is_unparseable = true; | ||
1540 | } | ||
1541 | |||
1542 | /* | ||
1543 | * Note that along the way as we read the header, we look for a sync | ||
1544 | * code inside. If we find one it would indicate that our original | ||
1545 | * sync was bad since there cannot be a sync code in a valid header. | ||
1546 | */ | ||
1547 | |||
1548 | /* | ||
1549 | * read in the raw header as bytes so we can CRC it, and parse it on the way | ||
1550 | */ | ||
1551 | for(i = 0; i < 2; i++) { | ||
1552 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1553 | return false; /* the read_callback_ sets the state for us */ | ||
1554 | if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ | ||
1555 | /* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */ | ||
1556 | decoder->private_->lookahead = (FLAC__byte)x; | ||
1557 | decoder->private_->cached = true; | ||
1558 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1559 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1560 | return true; | ||
1561 | } | ||
1562 | raw_header[raw_header_len++] = (FLAC__byte)x; | ||
1563 | } | ||
1564 | |||
1565 | switch(x = raw_header[2] >> 4) { | ||
1566 | case 0: | ||
1567 | if(is_known_fixed_blocksize_stream) | ||
1568 | decoder->private_->frame.header.blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; | ||
1569 | else | ||
1570 | is_unparseable = true; | ||
1571 | break; | ||
1572 | case 1: | ||
1573 | decoder->private_->frame.header.blocksize = 192; | ||
1574 | break; | ||
1575 | case 2: | ||
1576 | case 3: | ||
1577 | case 4: | ||
1578 | case 5: | ||
1579 | decoder->private_->frame.header.blocksize = 576 << (x-2); | ||
1580 | break; | ||
1581 | case 6: | ||
1582 | case 7: | ||
1583 | blocksize_hint = x; | ||
1584 | break; | ||
1585 | case 8: | ||
1586 | case 9: | ||
1587 | case 10: | ||
1588 | case 11: | ||
1589 | case 12: | ||
1590 | case 13: | ||
1591 | case 14: | ||
1592 | case 15: | ||
1593 | decoder->private_->frame.header.blocksize = 256 << (x-8); | ||
1594 | break; | ||
1595 | default: | ||
1596 | FLAC__ASSERT(0); | ||
1597 | break; | ||
1598 | } | ||
1599 | |||
1600 | switch(x = raw_header[2] & 0x0f) { | ||
1601 | case 0: | ||
1602 | if(decoder->private_->has_stream_info) | ||
1603 | decoder->private_->frame.header.sample_rate = decoder->private_->stream_info.data.stream_info.sample_rate; | ||
1604 | else | ||
1605 | is_unparseable = true; | ||
1606 | break; | ||
1607 | case 1: | ||
1608 | case 2: | ||
1609 | case 3: | ||
1610 | is_unparseable = true; | ||
1611 | break; | ||
1612 | case 4: | ||
1613 | decoder->private_->frame.header.sample_rate = 8000; | ||
1614 | break; | ||
1615 | case 5: | ||
1616 | decoder->private_->frame.header.sample_rate = 16000; | ||
1617 | break; | ||
1618 | case 6: | ||
1619 | decoder->private_->frame.header.sample_rate = 22050; | ||
1620 | break; | ||
1621 | case 7: | ||
1622 | decoder->private_->frame.header.sample_rate = 24000; | ||
1623 | break; | ||
1624 | case 8: | ||
1625 | decoder->private_->frame.header.sample_rate = 32000; | ||
1626 | break; | ||
1627 | case 9: | ||
1628 | decoder->private_->frame.header.sample_rate = 44100; | ||
1629 | break; | ||
1630 | case 10: | ||
1631 | decoder->private_->frame.header.sample_rate = 48000; | ||
1632 | break; | ||
1633 | case 11: | ||
1634 | decoder->private_->frame.header.sample_rate = 96000; | ||
1635 | break; | ||
1636 | case 12: | ||
1637 | case 13: | ||
1638 | case 14: | ||
1639 | sample_rate_hint = x; | ||
1640 | break; | ||
1641 | case 15: | ||
1642 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1643 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1644 | return true; | ||
1645 | default: | ||
1646 | FLAC__ASSERT(0); | ||
1647 | } | ||
1648 | |||
1649 | x = (unsigned)(raw_header[3] >> 4); | ||
1650 | if(x & 8) { | ||
1651 | decoder->private_->frame.header.channels = 2; | ||
1652 | switch(x & 7) { | ||
1653 | case 0: | ||
1654 | decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE; | ||
1655 | break; | ||
1656 | case 1: | ||
1657 | decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE; | ||
1658 | break; | ||
1659 | case 2: | ||
1660 | decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_MID_SIDE; | ||
1661 | break; | ||
1662 | default: | ||
1663 | is_unparseable = true; | ||
1664 | break; | ||
1665 | } | ||
1666 | } | ||
1667 | else { | ||
1668 | decoder->private_->frame.header.channels = (unsigned)x + 1; | ||
1669 | decoder->private_->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; | ||
1670 | } | ||
1671 | |||
1672 | switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) { | ||
1673 | case 0: | ||
1674 | if(decoder->private_->has_stream_info) | ||
1675 | decoder->private_->frame.header.bits_per_sample = decoder->private_->stream_info.data.stream_info.bits_per_sample; | ||
1676 | else | ||
1677 | is_unparseable = true; | ||
1678 | break; | ||
1679 | case 1: | ||
1680 | decoder->private_->frame.header.bits_per_sample = 8; | ||
1681 | break; | ||
1682 | case 2: | ||
1683 | decoder->private_->frame.header.bits_per_sample = 12; | ||
1684 | break; | ||
1685 | case 4: | ||
1686 | decoder->private_->frame.header.bits_per_sample = 16; | ||
1687 | break; | ||
1688 | case 5: | ||
1689 | decoder->private_->frame.header.bits_per_sample = 20; | ||
1690 | break; | ||
1691 | case 6: | ||
1692 | decoder->private_->frame.header.bits_per_sample = 24; | ||
1693 | break; | ||
1694 | case 3: | ||
1695 | case 7: | ||
1696 | is_unparseable = true; | ||
1697 | break; | ||
1698 | default: | ||
1699 | FLAC__ASSERT(0); | ||
1700 | break; | ||
1701 | } | ||
1702 | |||
1703 | if(raw_header[3] & 0x01) { /* this should be a zero padding bit */ | ||
1704 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1705 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1706 | return true; | ||
1707 | } | ||
1708 | |||
1709 | /* | ||
1710 | * Now we get to the regrettable consequences of not knowing for sure | ||
1711 | * whether we got a frame number or a sample number. There are no | ||
1712 | * encoders that do variable-blocksize encoding so unless we know from | ||
1713 | * the STREAMINFO that it is variable-blocksize we will assume it is | ||
1714 | * fixed-blocksize. The trouble comes when we have no STREAMINFO; again | ||
1715 | * we will guess that is fixed-blocksize. Where this can go wrong: 1) a | ||
1716 | * variable-blocksize stream with no STREAMINFO; 2) a fixed-blocksize | ||
1717 | * stream that was edited such that one or more frames before or | ||
1718 | * including this one do not have the same number of samples as the | ||
1719 | * STREAMINFO's min and max blocksize. | ||
1720 | */ | ||
1721 | if(is_known_variable_blocksize_stream) { | ||
1722 | if(blocksize_hint) { | ||
1723 | if(!FLAC__bitbuffer_read_utf8_uint64(decoder->private_->input, &xx, read_callback_, decoder, raw_header, &raw_header_len)) | ||
1724 | return false; /* the read_callback_ sets the state for us */ | ||
1725 | if(xx == FLAC__U64L(0xffffffffffffffff)) { /* i.e. non-UTF8 code... */ | ||
1726 | decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ | ||
1727 | decoder->private_->cached = true; | ||
1728 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1729 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1730 | return true; | ||
1731 | } | ||
1732 | decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; | ||
1733 | decoder->private_->frame.header.number.sample_number = xx; | ||
1734 | } | ||
1735 | else | ||
1736 | is_unparseable = true; | ||
1737 | } | ||
1738 | else { | ||
1739 | if(!FLAC__bitbuffer_read_utf8_uint32(decoder->private_->input, &x, read_callback_, decoder, raw_header, &raw_header_len)) | ||
1740 | return false; /* the read_callback_ sets the state for us */ | ||
1741 | if(x == 0xffffffff) { /* i.e. non-UTF8 code... */ | ||
1742 | decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ | ||
1743 | decoder->private_->cached = true; | ||
1744 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1745 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1746 | return true; | ||
1747 | } | ||
1748 | decoder->private_->last_frame_number = x; | ||
1749 | decoder->private_->frame.header.number_type = FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER; | ||
1750 | if(decoder->private_->has_stream_info) { | ||
1751 | FLAC__ASSERT(decoder->private_->stream_info.data.stream_info.min_blocksize == decoder->private_->stream_info.data.stream_info.max_blocksize); | ||
1752 | decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->stream_info.data.stream_info.min_blocksize * (FLAC__uint64)x; | ||
1753 | decoder->private_->last_block_size = decoder->private_->frame.header.blocksize; | ||
1754 | } | ||
1755 | else if(blocksize_hint) { | ||
1756 | if(decoder->private_->last_block_size) | ||
1757 | decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->last_block_size * (FLAC__uint64)x; | ||
1758 | else | ||
1759 | is_unparseable = true; | ||
1760 | } | ||
1761 | else { | ||
1762 | decoder->private_->frame.header.number.sample_number = (FLAC__uint64)decoder->private_->frame.header.blocksize * (FLAC__uint64)x; | ||
1763 | decoder->private_->last_block_size = decoder->private_->frame.header.blocksize; | ||
1764 | } | ||
1765 | } | ||
1766 | |||
1767 | if(blocksize_hint) { | ||
1768 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1769 | return false; /* the read_callback_ sets the state for us */ | ||
1770 | raw_header[raw_header_len++] = (FLAC__byte)x; | ||
1771 | if(blocksize_hint == 7) { | ||
1772 | FLAC__uint32 _x; | ||
1773 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder)) | ||
1774 | return false; /* the read_callback_ sets the state for us */ | ||
1775 | raw_header[raw_header_len++] = (FLAC__byte)_x; | ||
1776 | x = (x << 8) | _x; | ||
1777 | } | ||
1778 | decoder->private_->frame.header.blocksize = x+1; | ||
1779 | } | ||
1780 | |||
1781 | if(sample_rate_hint) { | ||
1782 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1783 | return false; /* the read_callback_ sets the state for us */ | ||
1784 | raw_header[raw_header_len++] = (FLAC__byte)x; | ||
1785 | if(sample_rate_hint != 12) { | ||
1786 | FLAC__uint32 _x; | ||
1787 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &_x, 8, read_callback_, decoder)) | ||
1788 | return false; /* the read_callback_ sets the state for us */ | ||
1789 | raw_header[raw_header_len++] = (FLAC__byte)_x; | ||
1790 | x = (x << 8) | _x; | ||
1791 | } | ||
1792 | if(sample_rate_hint == 12) | ||
1793 | decoder->private_->frame.header.sample_rate = x*1000; | ||
1794 | else if(sample_rate_hint == 13) | ||
1795 | decoder->private_->frame.header.sample_rate = x; | ||
1796 | else | ||
1797 | decoder->private_->frame.header.sample_rate = x*10; | ||
1798 | } | ||
1799 | |||
1800 | /* read the CRC-8 byte */ | ||
1801 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) | ||
1802 | return false; /* the read_callback_ sets the state for us */ | ||
1803 | crc8 = (FLAC__byte)x; | ||
1804 | |||
1805 | if(FLAC__crc8(raw_header, raw_header_len) != crc8) { | ||
1806 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, decoder->private_->client_data); | ||
1807 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1808 | return true; | ||
1809 | } | ||
1810 | |||
1811 | if(is_unparseable) { | ||
1812 | decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM; | ||
1813 | return false; | ||
1814 | } | ||
1815 | |||
1816 | return true; | ||
1817 | } | ||
1818 | |||
1819 | FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) | ||
1820 | { | ||
1821 | FLAC__uint32 x; | ||
1822 | FLAC__bool wasted_bits; | ||
1823 | |||
1824 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */ | ||
1825 | return false; /* the read_callback_ sets the state for us */ | ||
1826 | |||
1827 | wasted_bits = (x & 1); | ||
1828 | x &= 0xfe; | ||
1829 | |||
1830 | if(wasted_bits) { | ||
1831 | unsigned u; | ||
1832 | if(!FLAC__bitbuffer_read_unary_unsigned(decoder->private_->input, &u, read_callback_, decoder)) | ||
1833 | return false; /* the read_callback_ sets the state for us */ | ||
1834 | decoder->private_->frame.subframes[channel].wasted_bits = u+1; | ||
1835 | bps -= decoder->private_->frame.subframes[channel].wasted_bits; | ||
1836 | } | ||
1837 | else | ||
1838 | decoder->private_->frame.subframes[channel].wasted_bits = 0; | ||
1839 | |||
1840 | /* | ||
1841 | * Lots of magic numbers here | ||
1842 | */ | ||
1843 | if(x & 0x80) { | ||
1844 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
1845 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1846 | return true; | ||
1847 | } | ||
1848 | else if(x == 0) { | ||
1849 | if(!read_subframe_constant_(decoder, channel, bps, do_full_decode)) | ||
1850 | return false; | ||
1851 | } | ||
1852 | else if(x == 2) { | ||
1853 | if(!read_subframe_verbatim_(decoder, channel, bps, do_full_decode)) | ||
1854 | return false; | ||
1855 | } | ||
1856 | else if(x < 16) { | ||
1857 | decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM; | ||
1858 | return false; | ||
1859 | } | ||
1860 | else if(x <= 24) { | ||
1861 | if(!read_subframe_fixed_(decoder, channel, bps, (x>>1)&7, do_full_decode)) | ||
1862 | return false; | ||
1863 | } | ||
1864 | else if(x < 64) { | ||
1865 | decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM; | ||
1866 | return false; | ||
1867 | } | ||
1868 | else { | ||
1869 | if(!read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1, do_full_decode)) | ||
1870 | return false; | ||
1871 | } | ||
1872 | |||
1873 | if(wasted_bits && do_full_decode) { | ||
1874 | unsigned i; | ||
1875 | x = decoder->private_->frame.subframes[channel].wasted_bits; | ||
1876 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) | ||
1877 | decoder->private_->output[channel][i] <<= x; | ||
1878 | } | ||
1879 | |||
1880 | return true; | ||
1881 | } | ||
1882 | |||
1883 | FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) | ||
1884 | { | ||
1885 | FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; | ||
1886 | FLAC__int32 x; | ||
1887 | unsigned i; | ||
1888 | FLAC__int32 *output = decoder->private_->output[channel]; | ||
1889 | |||
1890 | decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; | ||
1891 | |||
1892 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder)) | ||
1893 | return false; /* the read_callback_ sets the state for us */ | ||
1894 | |||
1895 | subframe->value = x; | ||
1896 | |||
1897 | /* decode the subframe */ | ||
1898 | if(do_full_decode) { | ||
1899 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) | ||
1900 | output[i] = x; | ||
1901 | } | ||
1902 | |||
1903 | return true; | ||
1904 | } | ||
1905 | |||
1906 | FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode) | ||
1907 | { | ||
1908 | FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; | ||
1909 | FLAC__int32 i32; | ||
1910 | FLAC__uint32 u32; | ||
1911 | unsigned u; | ||
1912 | |||
1913 | decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_FIXED; | ||
1914 | |||
1915 | subframe->residual = decoder->private_->residual[channel]; | ||
1916 | subframe->order = order; | ||
1917 | |||
1918 | /* read warm-up samples */ | ||
1919 | for(u = 0; u < order; u++) { | ||
1920 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder)) | ||
1921 | return false; /* the read_callback_ sets the state for us */ | ||
1922 | subframe->warmup[u] = i32; | ||
1923 | } | ||
1924 | |||
1925 | /* read entropy coding method info */ | ||
1926 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) | ||
1927 | return false; /* the read_callback_ sets the state for us */ | ||
1928 | subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; | ||
1929 | switch(subframe->entropy_coding_method.type) { | ||
1930 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
1931 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) | ||
1932 | return false; /* the read_callback_ sets the state for us */ | ||
1933 | subframe->entropy_coding_method.data.partitioned_rice.order = u32; | ||
1934 | subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; | ||
1935 | break; | ||
1936 | default: | ||
1937 | decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM; | ||
1938 | return false; | ||
1939 | } | ||
1940 | |||
1941 | /* read residual */ | ||
1942 | switch(subframe->entropy_coding_method.type) { | ||
1943 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
1944 | if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel])) | ||
1945 | return false; | ||
1946 | break; | ||
1947 | default: | ||
1948 | FLAC__ASSERT(0); | ||
1949 | } | ||
1950 | |||
1951 | /* decode the subframe */ | ||
1952 | if(do_full_decode) { | ||
1953 | memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); | ||
1954 | FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); | ||
1955 | } | ||
1956 | |||
1957 | return true; | ||
1958 | } | ||
1959 | |||
1960 | FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, const unsigned order, FLAC__bool do_full_decode) | ||
1961 | { | ||
1962 | FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; | ||
1963 | FLAC__int32 i32; | ||
1964 | FLAC__uint32 u32; | ||
1965 | unsigned u; | ||
1966 | |||
1967 | decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_LPC; | ||
1968 | |||
1969 | subframe->residual = decoder->private_->residual[channel]; | ||
1970 | subframe->order = order; | ||
1971 | |||
1972 | /* read warm-up samples */ | ||
1973 | for(u = 0; u < order; u++) { | ||
1974 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, bps, read_callback_, decoder)) | ||
1975 | return false; /* the read_callback_ sets the state for us */ | ||
1976 | subframe->warmup[u] = i32; | ||
1977 | } | ||
1978 | |||
1979 | /* read qlp coeff precision */ | ||
1980 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN, read_callback_, decoder)) | ||
1981 | return false; /* the read_callback_ sets the state for us */ | ||
1982 | if(u32 == (1u << FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { | ||
1983 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
1984 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
1985 | return true; | ||
1986 | } | ||
1987 | subframe->qlp_coeff_precision = u32+1; | ||
1988 | |||
1989 | /* read qlp shift */ | ||
1990 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN, read_callback_, decoder)) | ||
1991 | return false; /* the read_callback_ sets the state for us */ | ||
1992 | subframe->quantization_level = i32; | ||
1993 | |||
1994 | /* read quantized lp coefficiencts */ | ||
1995 | for(u = 0; u < order; u++) { | ||
1996 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i32, subframe->qlp_coeff_precision, read_callback_, decoder)) | ||
1997 | return false; /* the read_callback_ sets the state for us */ | ||
1998 | subframe->qlp_coeff[u] = i32; | ||
1999 | } | ||
2000 | |||
2001 | /* read entropy coding method info */ | ||
2002 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN, read_callback_, decoder)) | ||
2003 | return false; /* the read_callback_ sets the state for us */ | ||
2004 | subframe->entropy_coding_method.type = (FLAC__EntropyCodingMethodType)u32; | ||
2005 | switch(subframe->entropy_coding_method.type) { | ||
2006 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
2007 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN, read_callback_, decoder)) | ||
2008 | return false; /* the read_callback_ sets the state for us */ | ||
2009 | subframe->entropy_coding_method.data.partitioned_rice.order = u32; | ||
2010 | subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; | ||
2011 | break; | ||
2012 | default: | ||
2013 | decoder->protected_->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM; | ||
2014 | return false; | ||
2015 | } | ||
2016 | |||
2017 | /* read residual */ | ||
2018 | switch(subframe->entropy_coding_method.type) { | ||
2019 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
2020 | if(!read_residual_partitioned_rice_(decoder, order, subframe->entropy_coding_method.data.partitioned_rice.order, &decoder->private_->partitioned_rice_contents[channel], decoder->private_->residual[channel])) | ||
2021 | return false; | ||
2022 | break; | ||
2023 | default: | ||
2024 | FLAC__ASSERT(0); | ||
2025 | } | ||
2026 | |||
2027 | /* decode the subframe */ | ||
2028 | if(do_full_decode) { | ||
2029 | memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); | ||
2030 | if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) | ||
2031 | if(bps <= 16 && subframe->qlp_coeff_precision <= 16) { | ||
2032 | if(order <= 8) | ||
2033 | decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); | ||
2034 | else | ||
2035 | decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); | ||
2036 | } | ||
2037 | else | ||
2038 | decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); | ||
2039 | else | ||
2040 | decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); | ||
2041 | } | ||
2042 | |||
2043 | return true; | ||
2044 | } | ||
2045 | |||
2046 | FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps, FLAC__bool do_full_decode) | ||
2047 | { | ||
2048 | FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; | ||
2049 | FLAC__int32 x, *residual = decoder->private_->residual[channel]; | ||
2050 | unsigned i; | ||
2051 | |||
2052 | decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; | ||
2053 | |||
2054 | subframe->data = residual; | ||
2055 | |||
2056 | for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { | ||
2057 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &x, bps, read_callback_, decoder)) | ||
2058 | return false; /* the read_callback_ sets the state for us */ | ||
2059 | residual[i] = x; | ||
2060 | } | ||
2061 | |||
2062 | /* decode the subframe */ | ||
2063 | if(do_full_decode) | ||
2064 | memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); | ||
2065 | |||
2066 | return true; | ||
2067 | } | ||
2068 | |||
2069 | FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigned predictor_order, unsigned partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual) | ||
2070 | { | ||
2071 | FLAC__uint32 rice_parameter; | ||
2072 | int i; | ||
2073 | unsigned partition, sample, u; | ||
2074 | const unsigned partitions = 1u << partition_order; | ||
2075 | const unsigned partition_samples = partition_order > 0? decoder->private_->frame.header.blocksize >> partition_order : decoder->private_->frame.header.blocksize - predictor_order; | ||
2076 | |||
2077 | /* sanity checks */ | ||
2078 | if(partition_order == 0) { | ||
2079 | if(decoder->private_->frame.header.blocksize < predictor_order) { | ||
2080 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
2081 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
2082 | return true; | ||
2083 | } | ||
2084 | } | ||
2085 | else { | ||
2086 | if(partition_samples < predictor_order) { | ||
2087 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
2088 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
2089 | return true; | ||
2090 | } | ||
2091 | } | ||
2092 | |||
2093 | if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) { | ||
2094 | decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; | ||
2095 | return false; | ||
2096 | } | ||
2097 | |||
2098 | sample = 0; | ||
2099 | for(partition = 0; partition < partitions; partition++) { | ||
2100 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN, read_callback_, decoder)) | ||
2101 | return false; /* the read_callback_ sets the state for us */ | ||
2102 | partitioned_rice_contents->parameters[partition] = rice_parameter; | ||
2103 | if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2104 | #ifdef FLAC__SYMMETRIC_RICE | ||
2105 | for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { | ||
2106 | if(!FLAC__bitbuffer_read_symmetric_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) | ||
2107 | return false; /* the read_callback_ sets the state for us */ | ||
2108 | residual[sample] = i; | ||
2109 | } | ||
2110 | #else | ||
2111 | u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; | ||
2112 | if(!FLAC__bitbuffer_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter, read_callback_, decoder)) | ||
2113 | return false; /* the read_callback_ sets the state for us */ | ||
2114 | sample += u; | ||
2115 | #endif | ||
2116 | } | ||
2117 | else { | ||
2118 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN, read_callback_, decoder)) | ||
2119 | return false; /* the read_callback_ sets the state for us */ | ||
2120 | partitioned_rice_contents->raw_bits[partition] = rice_parameter; | ||
2121 | for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) { | ||
2122 | if(!FLAC__bitbuffer_read_raw_int32(decoder->private_->input, &i, rice_parameter, read_callback_, decoder)) | ||
2123 | return false; /* the read_callback_ sets the state for us */ | ||
2124 | residual[sample] = i; | ||
2125 | } | ||
2126 | } | ||
2127 | } | ||
2128 | |||
2129 | return true; | ||
2130 | } | ||
2131 | |||
2132 | FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder) | ||
2133 | { | ||
2134 | if(!FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input)) { | ||
2135 | FLAC__uint32 zero = 0; | ||
2136 | if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &zero, FLAC__bitbuffer_bits_left_for_byte_alignment(decoder->private_->input), read_callback_, decoder)) | ||
2137 | return false; /* the read_callback_ sets the state for us */ | ||
2138 | if(zero != 0) { | ||
2139 | decoder->private_->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, decoder->private_->client_data); | ||
2140 | decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; | ||
2141 | } | ||
2142 | } | ||
2143 | return true; | ||
2144 | } | ||
2145 | |||
2146 | FLAC__bool read_callback_(FLAC__byte buffer[], unsigned *bytes, void *client_data) | ||
2147 | { | ||
2148 | FLAC__StreamDecoder *decoder = (FLAC__StreamDecoder *)client_data; | ||
2149 | FLAC__StreamDecoderReadStatus status; | ||
2150 | |||
2151 | status = decoder->private_->read_callback(decoder, buffer, bytes, decoder->private_->client_data); | ||
2152 | if(status == FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM) | ||
2153 | decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; | ||
2154 | else if(status == FLAC__STREAM_DECODER_READ_STATUS_ABORT) | ||
2155 | decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; | ||
2156 | return status == FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; | ||
2157 | } | ||
diff --git a/apps/codecs/libFLAC/stream_encoder.c b/apps/codecs/libFLAC/stream_encoder.c new file mode 100644 index 0000000000..33debfc06a --- /dev/null +++ b/apps/codecs/libFLAC/stream_encoder.c | |||
@@ -0,0 +1,3394 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <limits.h> | ||
33 | #include <stdio.h> | ||
34 | #include <stdlib.h> /* for malloc() */ | ||
35 | #include <string.h> /* for memcpy() */ | ||
36 | #include "FLAC/assert.h" | ||
37 | #include "FLAC/stream_decoder.h" | ||
38 | #include "protected/stream_encoder.h" | ||
39 | #include "private/bitbuffer.h" | ||
40 | #include "private/bitmath.h" | ||
41 | #include "private/crc.h" | ||
42 | #include "private/cpu.h" | ||
43 | #include "private/fixed.h" | ||
44 | #include "private/format.h" | ||
45 | #include "private/lpc.h" | ||
46 | #include "private/md5.h" | ||
47 | #include "private/memory.h" | ||
48 | #include "private/stream_encoder_framing.h" | ||
49 | |||
50 | #ifdef HAVE_CONFIG_H | ||
51 | #include <config.h> | ||
52 | #endif | ||
53 | |||
54 | #ifdef min | ||
55 | #undef min | ||
56 | #endif | ||
57 | #define min(x,y) ((x)<(y)?(x):(y)) | ||
58 | |||
59 | #ifdef max | ||
60 | #undef max | ||
61 | #endif | ||
62 | #define max(x,y) ((x)>(y)?(x):(y)) | ||
63 | |||
64 | typedef struct { | ||
65 | FLAC__int32 *data[FLAC__MAX_CHANNELS]; | ||
66 | unsigned size; /* of each data[] in samples */ | ||
67 | unsigned tail; | ||
68 | } verify_input_fifo; | ||
69 | |||
70 | typedef struct { | ||
71 | const FLAC__byte *data; | ||
72 | unsigned capacity; | ||
73 | unsigned bytes; | ||
74 | } verify_output; | ||
75 | |||
76 | typedef enum { | ||
77 | ENCODER_IN_MAGIC = 0, | ||
78 | ENCODER_IN_METADATA = 1, | ||
79 | ENCODER_IN_AUDIO = 2 | ||
80 | } EncoderStateHint; | ||
81 | |||
82 | /*********************************************************************** | ||
83 | * | ||
84 | * Private class method prototypes | ||
85 | * | ||
86 | ***********************************************************************/ | ||
87 | |||
88 | static void set_defaults_(FLAC__StreamEncoder *encoder); | ||
89 | static void free_(FLAC__StreamEncoder *encoder); | ||
90 | static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size); | ||
91 | static FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples); | ||
92 | static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); | ||
93 | static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); | ||
94 | |||
95 | static FLAC__bool process_subframe_( | ||
96 | FLAC__StreamEncoder *encoder, | ||
97 | unsigned min_partition_order, | ||
98 | unsigned max_partition_order, | ||
99 | FLAC__bool precompute_partition_sums, | ||
100 | const FLAC__FrameHeader *frame_header, | ||
101 | unsigned subframe_bps, | ||
102 | const FLAC__int32 integer_signal[], | ||
103 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
104 | const FLAC__real real_signal[], | ||
105 | #endif | ||
106 | FLAC__Subframe *subframe[2], | ||
107 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], | ||
108 | FLAC__int32 *residual[2], | ||
109 | unsigned *best_subframe, | ||
110 | unsigned *best_bits | ||
111 | ); | ||
112 | |||
113 | static FLAC__bool add_subframe_( | ||
114 | FLAC__StreamEncoder *encoder, | ||
115 | const FLAC__FrameHeader *frame_header, | ||
116 | unsigned subframe_bps, | ||
117 | const FLAC__Subframe *subframe, | ||
118 | FLAC__BitBuffer *frame | ||
119 | ); | ||
120 | |||
121 | static unsigned evaluate_constant_subframe_( | ||
122 | const FLAC__int32 signal, | ||
123 | unsigned subframe_bps, | ||
124 | FLAC__Subframe *subframe | ||
125 | ); | ||
126 | |||
127 | static unsigned evaluate_fixed_subframe_( | ||
128 | FLAC__StreamEncoder *encoder, | ||
129 | const FLAC__int32 signal[], | ||
130 | FLAC__int32 residual[], | ||
131 | FLAC__uint32 abs_residual[], | ||
132 | FLAC__uint64 abs_residual_partition_sums[], | ||
133 | unsigned raw_bits_per_partition[], | ||
134 | unsigned blocksize, | ||
135 | unsigned subframe_bps, | ||
136 | unsigned order, | ||
137 | unsigned rice_parameter, | ||
138 | unsigned min_partition_order, | ||
139 | unsigned max_partition_order, | ||
140 | FLAC__bool precompute_partition_sums, | ||
141 | FLAC__bool do_escape_coding, | ||
142 | unsigned rice_parameter_search_dist, | ||
143 | FLAC__Subframe *subframe, | ||
144 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents | ||
145 | ); | ||
146 | |||
147 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
148 | static unsigned evaluate_lpc_subframe_( | ||
149 | FLAC__StreamEncoder *encoder, | ||
150 | const FLAC__int32 signal[], | ||
151 | FLAC__int32 residual[], | ||
152 | FLAC__uint32 abs_residual[], | ||
153 | FLAC__uint64 abs_residual_partition_sums[], | ||
154 | unsigned raw_bits_per_partition[], | ||
155 | const FLAC__real lp_coeff[], | ||
156 | unsigned blocksize, | ||
157 | unsigned subframe_bps, | ||
158 | unsigned order, | ||
159 | unsigned qlp_coeff_precision, | ||
160 | unsigned rice_parameter, | ||
161 | unsigned min_partition_order, | ||
162 | unsigned max_partition_order, | ||
163 | FLAC__bool precompute_partition_sums, | ||
164 | FLAC__bool do_escape_coding, | ||
165 | unsigned rice_parameter_search_dist, | ||
166 | FLAC__Subframe *subframe, | ||
167 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents | ||
168 | ); | ||
169 | #endif | ||
170 | |||
171 | static unsigned evaluate_verbatim_subframe_( | ||
172 | const FLAC__int32 signal[], | ||
173 | unsigned blocksize, | ||
174 | unsigned subframe_bps, | ||
175 | FLAC__Subframe *subframe | ||
176 | ); | ||
177 | |||
178 | static unsigned find_best_partition_order_( | ||
179 | struct FLAC__StreamEncoderPrivate *private_, | ||
180 | const FLAC__int32 residual[], | ||
181 | FLAC__uint32 abs_residual[], | ||
182 | FLAC__uint64 abs_residual_partition_sums[], | ||
183 | unsigned raw_bits_per_partition[], | ||
184 | unsigned residual_samples, | ||
185 | unsigned predictor_order, | ||
186 | unsigned rice_parameter, | ||
187 | unsigned min_partition_order, | ||
188 | unsigned max_partition_order, | ||
189 | FLAC__bool precompute_partition_sums, | ||
190 | FLAC__bool do_escape_coding, | ||
191 | unsigned rice_parameter_search_dist, | ||
192 | FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice | ||
193 | ); | ||
194 | |||
195 | static void precompute_partition_info_sums_( | ||
196 | const FLAC__uint32 abs_residual[], | ||
197 | FLAC__uint64 abs_residual_partition_sums[], | ||
198 | unsigned residual_samples, | ||
199 | unsigned predictor_order, | ||
200 | unsigned min_partition_order, | ||
201 | unsigned max_partition_order | ||
202 | ); | ||
203 | |||
204 | static void precompute_partition_info_escapes_( | ||
205 | const FLAC__int32 residual[], | ||
206 | unsigned raw_bits_per_partition[], | ||
207 | unsigned residual_samples, | ||
208 | unsigned predictor_order, | ||
209 | unsigned min_partition_order, | ||
210 | unsigned max_partition_order | ||
211 | ); | ||
212 | |||
213 | #ifdef DONT_ESTIMATE_RICE_BITS | ||
214 | static FLAC__bool set_partitioned_rice_( | ||
215 | const FLAC__uint32 abs_residual[], | ||
216 | const FLAC__int32 residual[], | ||
217 | const unsigned residual_samples, | ||
218 | const unsigned predictor_order, | ||
219 | const unsigned suggested_rice_parameter, | ||
220 | const unsigned rice_parameter_search_dist, | ||
221 | const unsigned partition_order, | ||
222 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
223 | unsigned *bits | ||
224 | ); | ||
225 | |||
226 | static FLAC__bool set_partitioned_rice_with_precompute_( | ||
227 | const FLAC__int32 residual[], | ||
228 | const FLAC__uint64 abs_residual_partition_sums[], | ||
229 | const unsigned raw_bits_per_partition[], | ||
230 | const unsigned residual_samples, | ||
231 | const unsigned predictor_order, | ||
232 | const unsigned suggested_rice_parameter, | ||
233 | const unsigned rice_parameter_search_dist, | ||
234 | const unsigned partition_order, | ||
235 | const FLAC__bool search_for_escapes, | ||
236 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
237 | unsigned *bits | ||
238 | ); | ||
239 | #else | ||
240 | static FLAC__bool set_partitioned_rice_( | ||
241 | const FLAC__uint32 abs_residual[], | ||
242 | const unsigned residual_samples, | ||
243 | const unsigned predictor_order, | ||
244 | const unsigned suggested_rice_parameter, | ||
245 | const unsigned rice_parameter_search_dist, | ||
246 | const unsigned partition_order, | ||
247 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
248 | unsigned *bits | ||
249 | ); | ||
250 | |||
251 | static FLAC__bool set_partitioned_rice_with_precompute_( | ||
252 | const FLAC__uint32 abs_residual[], | ||
253 | const FLAC__uint64 abs_residual_partition_sums[], | ||
254 | const unsigned raw_bits_per_partition[], | ||
255 | const unsigned residual_samples, | ||
256 | const unsigned predictor_order, | ||
257 | const unsigned suggested_rice_parameter, | ||
258 | const unsigned rice_parameter_search_dist, | ||
259 | const unsigned partition_order, | ||
260 | const FLAC__bool search_for_escapes, | ||
261 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
262 | unsigned *bits | ||
263 | ); | ||
264 | #endif | ||
265 | |||
266 | static unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples); | ||
267 | |||
268 | /* verify-related routines: */ | ||
269 | static void append_to_verify_fifo_( | ||
270 | verify_input_fifo *fifo, | ||
271 | const FLAC__int32 * const input[], | ||
272 | unsigned input_offset, | ||
273 | unsigned channels, | ||
274 | unsigned wide_samples | ||
275 | ); | ||
276 | |||
277 | static void append_to_verify_fifo_interleaved_( | ||
278 | verify_input_fifo *fifo, | ||
279 | const FLAC__int32 input[], | ||
280 | unsigned input_offset, | ||
281 | unsigned channels, | ||
282 | unsigned wide_samples | ||
283 | ); | ||
284 | |||
285 | static FLAC__StreamDecoderReadStatus verify_read_callback_( | ||
286 | const FLAC__StreamDecoder *decoder, | ||
287 | FLAC__byte buffer[], | ||
288 | unsigned *bytes, | ||
289 | void *client_data | ||
290 | ); | ||
291 | |||
292 | static FLAC__StreamDecoderWriteStatus verify_write_callback_( | ||
293 | const FLAC__StreamDecoder *decoder, | ||
294 | const FLAC__Frame *frame, | ||
295 | const FLAC__int32 * const buffer[], | ||
296 | void *client_data | ||
297 | ); | ||
298 | |||
299 | static void verify_metadata_callback_( | ||
300 | const FLAC__StreamDecoder *decoder, | ||
301 | const FLAC__StreamMetadata *metadata, | ||
302 | void *client_data | ||
303 | ); | ||
304 | |||
305 | static void verify_error_callback_( | ||
306 | const FLAC__StreamDecoder *decoder, | ||
307 | FLAC__StreamDecoderErrorStatus status, | ||
308 | void *client_data | ||
309 | ); | ||
310 | |||
311 | |||
312 | /*********************************************************************** | ||
313 | * | ||
314 | * Private class data | ||
315 | * | ||
316 | ***********************************************************************/ | ||
317 | |||
318 | typedef struct FLAC__StreamEncoderPrivate { | ||
319 | unsigned input_capacity; /* current size (in samples) of the signal and residual buffers */ | ||
320 | FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */ | ||
321 | FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */ | ||
322 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
323 | FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */ | ||
324 | FLAC__real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */ | ||
325 | #endif | ||
326 | unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */ | ||
327 | unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */ | ||
328 | FLAC__int32 *residual_workspace[FLAC__MAX_CHANNELS][2]; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */ | ||
329 | FLAC__int32 *residual_workspace_mid_side[2][2]; | ||
330 | FLAC__Subframe subframe_workspace[FLAC__MAX_CHANNELS][2]; | ||
331 | FLAC__Subframe subframe_workspace_mid_side[2][2]; | ||
332 | FLAC__Subframe *subframe_workspace_ptr[FLAC__MAX_CHANNELS][2]; | ||
333 | FLAC__Subframe *subframe_workspace_ptr_mid_side[2][2]; | ||
334 | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace[FLAC__MAX_CHANNELS][2]; | ||
335 | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_workspace_mid_side[FLAC__MAX_CHANNELS][2]; | ||
336 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr[FLAC__MAX_CHANNELS][2]; | ||
337 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents_workspace_ptr_mid_side[FLAC__MAX_CHANNELS][2]; | ||
338 | unsigned best_subframe[FLAC__MAX_CHANNELS]; /* index into the above workspaces */ | ||
339 | unsigned best_subframe_mid_side[2]; | ||
340 | unsigned best_subframe_bits[FLAC__MAX_CHANNELS]; /* size in bits of the best subframe for each channel */ | ||
341 | unsigned best_subframe_bits_mid_side[2]; | ||
342 | FLAC__uint32 *abs_residual; /* workspace where abs(candidate residual) is stored */ | ||
343 | FLAC__uint64 *abs_residual_partition_sums; /* workspace where the sum of abs(candidate residual) for each partition is stored */ | ||
344 | unsigned *raw_bits_per_partition; /* workspace where the sum of silog2(candidate residual) for each partition is stored */ | ||
345 | FLAC__BitBuffer *frame; /* the current frame being worked on */ | ||
346 | unsigned loose_mid_side_stereo_frames; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */ | ||
347 | unsigned loose_mid_side_stereo_frame_count; /* number of frames using the current channel assignment */ | ||
348 | FLAC__ChannelAssignment last_channel_assignment; | ||
349 | FLAC__StreamMetadata metadata; | ||
350 | unsigned current_sample_number; | ||
351 | unsigned current_frame_number; | ||
352 | struct FLAC__MD5Context md5context; | ||
353 | FLAC__CPUInfo cpuinfo; | ||
354 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
355 | unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
356 | #else | ||
357 | unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | ||
358 | #endif | ||
359 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
360 | void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | ||
361 | void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
362 | void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
363 | void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | ||
364 | #endif | ||
365 | FLAC__bool use_wide_by_block; /* use slow 64-bit versions of some functions because of the block size */ | ||
366 | FLAC__bool use_wide_by_partition; /* use slow 64-bit versions of some functions because of the min partition order and blocksize */ | ||
367 | FLAC__bool use_wide_by_order; /* use slow 64-bit versions of some functions because of the lpc order */ | ||
368 | FLAC__bool precompute_partition_sums; /* our initial guess as to whether precomputing the partitions sums will be a speed improvement */ | ||
369 | FLAC__bool disable_constant_subframes; | ||
370 | FLAC__bool disable_fixed_subframes; | ||
371 | FLAC__bool disable_verbatim_subframes; | ||
372 | FLAC__StreamEncoderWriteCallback write_callback; | ||
373 | FLAC__StreamEncoderMetadataCallback metadata_callback; | ||
374 | void *client_data; | ||
375 | /* unaligned (original) pointers to allocated data */ | ||
376 | FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS]; | ||
377 | FLAC__int32 *integer_signal_mid_side_unaligned[2]; | ||
378 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
379 | FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; | ||
380 | FLAC__real *real_signal_mid_side_unaligned[2]; | ||
381 | #endif | ||
382 | FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2]; | ||
383 | FLAC__int32 *residual_workspace_mid_side_unaligned[2][2]; | ||
384 | FLAC__uint32 *abs_residual_unaligned; | ||
385 | FLAC__uint64 *abs_residual_partition_sums_unaligned; | ||
386 | unsigned *raw_bits_per_partition_unaligned; | ||
387 | /* | ||
388 | * These fields have been moved here from private function local | ||
389 | * declarations merely to save stack space during encoding. | ||
390 | */ | ||
391 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
392 | FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */ | ||
393 | #endif | ||
394 | FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents_extra[2]; /* from find_best_partition_order_() */ | ||
395 | /* | ||
396 | * The data for the verify section | ||
397 | */ | ||
398 | struct { | ||
399 | FLAC__StreamDecoder *decoder; | ||
400 | EncoderStateHint state_hint; | ||
401 | FLAC__bool needs_magic_hack; | ||
402 | verify_input_fifo input_fifo; | ||
403 | verify_output output; | ||
404 | struct { | ||
405 | FLAC__uint64 absolute_sample; | ||
406 | unsigned frame_number; | ||
407 | unsigned channel; | ||
408 | unsigned sample; | ||
409 | FLAC__int32 expected; | ||
410 | FLAC__int32 got; | ||
411 | } error_stats; | ||
412 | } verify; | ||
413 | FLAC__bool is_being_deleted; /* if true, call to ..._finish() from ..._delete() will not call the callbacks */ | ||
414 | } FLAC__StreamEncoderPrivate; | ||
415 | |||
416 | /*********************************************************************** | ||
417 | * | ||
418 | * Public static class data | ||
419 | * | ||
420 | ***********************************************************************/ | ||
421 | |||
422 | FLAC_API const char * const FLAC__StreamEncoderStateString[] = { | ||
423 | "FLAC__STREAM_ENCODER_OK", | ||
424 | "FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR", | ||
425 | "FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA", | ||
426 | "FLAC__STREAM_ENCODER_INVALID_CALLBACK", | ||
427 | "FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS", | ||
428 | "FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE", | ||
429 | "FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE", | ||
430 | "FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE", | ||
431 | "FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER", | ||
432 | "FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION", | ||
433 | "FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH", | ||
434 | "FLAC__STREAM_ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH", | ||
435 | "FLAC__STREAM_ENCODER_ILLEGAL_MID_SIDE_FORCE", | ||
436 | "FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER", | ||
437 | "FLAC__STREAM_ENCODER_NOT_STREAMABLE", | ||
438 | "FLAC__STREAM_ENCODER_FRAMING_ERROR", | ||
439 | "FLAC__STREAM_ENCODER_INVALID_METADATA", | ||
440 | "FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING", | ||
441 | "FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING", | ||
442 | "FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR", | ||
443 | "FLAC__STREAM_ENCODER_ALREADY_INITIALIZED", | ||
444 | "FLAC__STREAM_ENCODER_UNINITIALIZED" | ||
445 | }; | ||
446 | |||
447 | FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[] = { | ||
448 | "FLAC__STREAM_ENCODER_WRITE_STATUS_OK", | ||
449 | "FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR" | ||
450 | }; | ||
451 | |||
452 | /*********************************************************************** | ||
453 | * | ||
454 | * Class constructor/destructor | ||
455 | * | ||
456 | */ | ||
457 | FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new() | ||
458 | { | ||
459 | FLAC__StreamEncoder *encoder; | ||
460 | unsigned i; | ||
461 | |||
462 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
463 | |||
464 | encoder = (FLAC__StreamEncoder*)calloc(1, sizeof(FLAC__StreamEncoder)); | ||
465 | if(encoder == 0) { | ||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | encoder->protected_ = (FLAC__StreamEncoderProtected*)calloc(1, sizeof(FLAC__StreamEncoderProtected)); | ||
470 | if(encoder->protected_ == 0) { | ||
471 | free(encoder); | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | encoder->private_ = (FLAC__StreamEncoderPrivate*)calloc(1, sizeof(FLAC__StreamEncoderPrivate)); | ||
476 | if(encoder->private_ == 0) { | ||
477 | free(encoder->protected_); | ||
478 | free(encoder); | ||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | encoder->private_->frame = FLAC__bitbuffer_new(); | ||
483 | if(encoder->private_->frame == 0) { | ||
484 | free(encoder->private_); | ||
485 | free(encoder->protected_); | ||
486 | free(encoder); | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | set_defaults_(encoder); | ||
491 | |||
492 | encoder->private_->is_being_deleted = false; | ||
493 | |||
494 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
495 | encoder->private_->subframe_workspace_ptr[i][0] = &encoder->private_->subframe_workspace[i][0]; | ||
496 | encoder->private_->subframe_workspace_ptr[i][1] = &encoder->private_->subframe_workspace[i][1]; | ||
497 | } | ||
498 | for(i = 0; i < 2; i++) { | ||
499 | encoder->private_->subframe_workspace_ptr_mid_side[i][0] = &encoder->private_->subframe_workspace_mid_side[i][0]; | ||
500 | encoder->private_->subframe_workspace_ptr_mid_side[i][1] = &encoder->private_->subframe_workspace_mid_side[i][1]; | ||
501 | } | ||
502 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
503 | encoder->private_->partitioned_rice_contents_workspace_ptr[i][0] = &encoder->private_->partitioned_rice_contents_workspace[i][0]; | ||
504 | encoder->private_->partitioned_rice_contents_workspace_ptr[i][1] = &encoder->private_->partitioned_rice_contents_workspace[i][1]; | ||
505 | } | ||
506 | for(i = 0; i < 2; i++) { | ||
507 | encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][0] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]; | ||
508 | encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[i][1] = &encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]; | ||
509 | } | ||
510 | |||
511 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
512 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][0]); | ||
513 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace[i][1]); | ||
514 | } | ||
515 | for(i = 0; i < 2; i++) { | ||
516 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); | ||
517 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); | ||
518 | } | ||
519 | for(i = 0; i < 2; i++) | ||
520 | FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]); | ||
521 | |||
522 | encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; | ||
523 | |||
524 | return encoder; | ||
525 | } | ||
526 | |||
527 | FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) | ||
528 | { | ||
529 | unsigned i; | ||
530 | |||
531 | FLAC__ASSERT(0 != encoder); | ||
532 | FLAC__ASSERT(0 != encoder->protected_); | ||
533 | FLAC__ASSERT(0 != encoder->private_); | ||
534 | FLAC__ASSERT(0 != encoder->private_->frame); | ||
535 | |||
536 | encoder->private_->is_being_deleted = true; | ||
537 | |||
538 | FLAC__stream_encoder_finish(encoder); | ||
539 | |||
540 | if(0 != encoder->private_->verify.decoder) | ||
541 | FLAC__stream_decoder_delete(encoder->private_->verify.decoder); | ||
542 | |||
543 | for(i = 0; i < FLAC__MAX_CHANNELS; i++) { | ||
544 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][0]); | ||
545 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace[i][1]); | ||
546 | } | ||
547 | for(i = 0; i < 2; i++) { | ||
548 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][0]); | ||
549 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_workspace_mid_side[i][1]); | ||
550 | } | ||
551 | for(i = 0; i < 2; i++) | ||
552 | FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(&encoder->private_->partitioned_rice_contents_extra[i]); | ||
553 | |||
554 | FLAC__bitbuffer_delete(encoder->private_->frame); | ||
555 | free(encoder->private_); | ||
556 | free(encoder->protected_); | ||
557 | free(encoder); | ||
558 | } | ||
559 | |||
560 | /*********************************************************************** | ||
561 | * | ||
562 | * Public class methods | ||
563 | * | ||
564 | ***********************************************************************/ | ||
565 | |||
566 | FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) | ||
567 | { | ||
568 | unsigned i; | ||
569 | FLAC__bool metadata_has_seektable, metadata_has_vorbis_comment; | ||
570 | |||
571 | FLAC__ASSERT(0 != encoder); | ||
572 | |||
573 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
574 | return encoder->protected_->state = FLAC__STREAM_ENCODER_ALREADY_INITIALIZED; | ||
575 | |||
576 | encoder->protected_->state = FLAC__STREAM_ENCODER_OK; | ||
577 | |||
578 | if(0 == encoder->private_->write_callback || 0 == encoder->private_->metadata_callback) | ||
579 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_CALLBACK; | ||
580 | |||
581 | if(encoder->protected_->channels == 0 || encoder->protected_->channels > FLAC__MAX_CHANNELS) | ||
582 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_NUMBER_OF_CHANNELS; | ||
583 | |||
584 | if(encoder->protected_->do_mid_side_stereo && encoder->protected_->channels != 2) | ||
585 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MID_SIDE_CHANNELS_MISMATCH; | ||
586 | |||
587 | if(encoder->protected_->loose_mid_side_stereo && !encoder->protected_->do_mid_side_stereo) | ||
588 | return encoder->protected_->state = FLAC__STREAM_ENCODER_ILLEGAL_MID_SIDE_FORCE; | ||
589 | |||
590 | if(encoder->protected_->bits_per_sample >= 32) | ||
591 | encoder->protected_->do_mid_side_stereo = false; /* since we do 32-bit math, the side channel would have 33 bps and overflow */ | ||
592 | |||
593 | if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE) | ||
594 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_BITS_PER_SAMPLE; | ||
595 | |||
596 | if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate)) | ||
597 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_SAMPLE_RATE; | ||
598 | |||
599 | if(encoder->protected_->blocksize < FLAC__MIN_BLOCK_SIZE || encoder->protected_->blocksize > FLAC__MAX_BLOCK_SIZE) | ||
600 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_BLOCK_SIZE; | ||
601 | |||
602 | if(encoder->protected_->max_lpc_order > FLAC__MAX_LPC_ORDER) | ||
603 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_MAX_LPC_ORDER; | ||
604 | |||
605 | if(encoder->protected_->blocksize < encoder->protected_->max_lpc_order) | ||
606 | return encoder->protected_->state = FLAC__STREAM_ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER; | ||
607 | |||
608 | if(encoder->protected_->qlp_coeff_precision == 0) { | ||
609 | if(encoder->protected_->bits_per_sample < 16) { | ||
610 | /* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */ | ||
611 | /* @@@ until then we'll make a guess */ | ||
612 | encoder->protected_->qlp_coeff_precision = max(FLAC__MIN_QLP_COEFF_PRECISION, 2 + encoder->protected_->bits_per_sample / 2); | ||
613 | } | ||
614 | else if(encoder->protected_->bits_per_sample == 16) { | ||
615 | if(encoder->protected_->blocksize <= 192) | ||
616 | encoder->protected_->qlp_coeff_precision = 7; | ||
617 | else if(encoder->protected_->blocksize <= 384) | ||
618 | encoder->protected_->qlp_coeff_precision = 8; | ||
619 | else if(encoder->protected_->blocksize <= 576) | ||
620 | encoder->protected_->qlp_coeff_precision = 9; | ||
621 | else if(encoder->protected_->blocksize <= 1152) | ||
622 | encoder->protected_->qlp_coeff_precision = 10; | ||
623 | else if(encoder->protected_->blocksize <= 2304) | ||
624 | encoder->protected_->qlp_coeff_precision = 11; | ||
625 | else if(encoder->protected_->blocksize <= 4608) | ||
626 | encoder->protected_->qlp_coeff_precision = 12; | ||
627 | else | ||
628 | encoder->protected_->qlp_coeff_precision = 13; | ||
629 | } | ||
630 | else { | ||
631 | if(encoder->protected_->blocksize <= 384) | ||
632 | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-2; | ||
633 | else if(encoder->protected_->blocksize <= 1152) | ||
634 | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION-1; | ||
635 | else | ||
636 | encoder->protected_->qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; | ||
637 | } | ||
638 | FLAC__ASSERT(encoder->protected_->qlp_coeff_precision <= FLAC__MAX_QLP_COEFF_PRECISION); | ||
639 | } | ||
640 | else if(encoder->protected_->qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION || encoder->protected_->qlp_coeff_precision > FLAC__MAX_QLP_COEFF_PRECISION) | ||
641 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_QLP_COEFF_PRECISION; | ||
642 | |||
643 | if(encoder->protected_->streamable_subset) { | ||
644 | if( | ||
645 | encoder->protected_->blocksize != 192 && | ||
646 | encoder->protected_->blocksize != 576 && | ||
647 | encoder->protected_->blocksize != 1152 && | ||
648 | encoder->protected_->blocksize != 2304 && | ||
649 | encoder->protected_->blocksize != 4608 && | ||
650 | encoder->protected_->blocksize != 256 && | ||
651 | encoder->protected_->blocksize != 512 && | ||
652 | encoder->protected_->blocksize != 1024 && | ||
653 | encoder->protected_->blocksize != 2048 && | ||
654 | encoder->protected_->blocksize != 4096 && | ||
655 | encoder->protected_->blocksize != 8192 && | ||
656 | encoder->protected_->blocksize != 16384 | ||
657 | ) | ||
658 | return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE; | ||
659 | if( | ||
660 | encoder->protected_->sample_rate != 8000 && | ||
661 | encoder->protected_->sample_rate != 16000 && | ||
662 | encoder->protected_->sample_rate != 22050 && | ||
663 | encoder->protected_->sample_rate != 24000 && | ||
664 | encoder->protected_->sample_rate != 32000 && | ||
665 | encoder->protected_->sample_rate != 44100 && | ||
666 | encoder->protected_->sample_rate != 48000 && | ||
667 | encoder->protected_->sample_rate != 96000 | ||
668 | ) | ||
669 | return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE; | ||
670 | if( | ||
671 | encoder->protected_->bits_per_sample != 8 && | ||
672 | encoder->protected_->bits_per_sample != 12 && | ||
673 | encoder->protected_->bits_per_sample != 16 && | ||
674 | encoder->protected_->bits_per_sample != 20 && | ||
675 | encoder->protected_->bits_per_sample != 24 | ||
676 | ) | ||
677 | return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE; | ||
678 | if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER) | ||
679 | return encoder->protected_->state = FLAC__STREAM_ENCODER_NOT_STREAMABLE; | ||
680 | } | ||
681 | |||
682 | if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) | ||
683 | encoder->protected_->max_residual_partition_order = (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN) - 1; | ||
684 | if(encoder->protected_->min_residual_partition_order >= encoder->protected_->max_residual_partition_order) | ||
685 | encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order; | ||
686 | |||
687 | /* validate metadata */ | ||
688 | if(0 == encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) | ||
689 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
690 | metadata_has_seektable = false; | ||
691 | metadata_has_vorbis_comment = false; | ||
692 | for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { | ||
693 | if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_STREAMINFO) | ||
694 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
695 | else if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) { | ||
696 | if(metadata_has_seektable) /* only one is allowed */ | ||
697 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
698 | metadata_has_seektable = true; | ||
699 | if(!FLAC__format_seektable_is_legal(&encoder->protected_->metadata[i]->data.seek_table)) | ||
700 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
701 | } | ||
702 | else if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | ||
703 | if(metadata_has_vorbis_comment) /* only one is allowed */ | ||
704 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
705 | metadata_has_vorbis_comment = true; | ||
706 | } | ||
707 | else if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_CUESHEET) { | ||
708 | if(!FLAC__format_cuesheet_is_legal(&encoder->protected_->metadata[i]->data.cue_sheet, encoder->protected_->metadata[i]->data.cue_sheet.is_cd, /*violation=*/0)) | ||
709 | return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | encoder->private_->input_capacity = 0; | ||
714 | for(i = 0; i < encoder->protected_->channels; i++) { | ||
715 | encoder->private_->integer_signal_unaligned[i] = encoder->private_->integer_signal[i] = 0; | ||
716 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
717 | encoder->private_->real_signal_unaligned[i] = encoder->private_->real_signal[i] = 0; | ||
718 | #endif | ||
719 | } | ||
720 | for(i = 0; i < 2; i++) { | ||
721 | encoder->private_->integer_signal_mid_side_unaligned[i] = encoder->private_->integer_signal_mid_side[i] = 0; | ||
722 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
723 | encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0; | ||
724 | #endif | ||
725 | } | ||
726 | for(i = 0; i < encoder->protected_->channels; i++) { | ||
727 | encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0; | ||
728 | encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0; | ||
729 | encoder->private_->best_subframe[i] = 0; | ||
730 | } | ||
731 | for(i = 0; i < 2; i++) { | ||
732 | encoder->private_->residual_workspace_mid_side_unaligned[i][0] = encoder->private_->residual_workspace_mid_side[i][0] = 0; | ||
733 | encoder->private_->residual_workspace_mid_side_unaligned[i][1] = encoder->private_->residual_workspace_mid_side[i][1] = 0; | ||
734 | encoder->private_->best_subframe_mid_side[i] = 0; | ||
735 | } | ||
736 | encoder->private_->abs_residual_unaligned = encoder->private_->abs_residual = 0; | ||
737 | encoder->private_->abs_residual_partition_sums_unaligned = encoder->private_->abs_residual_partition_sums = 0; | ||
738 | encoder->private_->raw_bits_per_partition_unaligned = encoder->private_->raw_bits_per_partition = 0; | ||
739 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
740 | encoder->private_->loose_mid_side_stereo_frames = (unsigned)((FLAC__double)encoder->protected_->sample_rate * 0.4 / (FLAC__double)encoder->protected_->blocksize + 0.5); | ||
741 | #else | ||
742 | /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */ | ||
743 | /* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ | ||
744 | FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350); | ||
745 | FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535); | ||
746 | FLAC__ASSERT(encoder->protected_->sample_rate <= 655350); | ||
747 | FLAC__ASSERT(encoder->protected_->blocksize <= 65535); | ||
748 | encoder->private_->loose_mid_side_stereo_frames = (unsigned)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF); | ||
749 | #endif | ||
750 | if(encoder->private_->loose_mid_side_stereo_frames == 0) | ||
751 | encoder->private_->loose_mid_side_stereo_frames = 1; | ||
752 | encoder->private_->loose_mid_side_stereo_frame_count = 0; | ||
753 | encoder->private_->current_sample_number = 0; | ||
754 | encoder->private_->current_frame_number = 0; | ||
755 | |||
756 | encoder->private_->use_wide_by_block = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(encoder->protected_->blocksize)+1 > 30); | ||
757 | encoder->private_->use_wide_by_order = (encoder->protected_->bits_per_sample + FLAC__bitmath_ilog2(max(encoder->protected_->max_lpc_order, FLAC__MAX_FIXED_ORDER))+1 > 30); /*@@@ need to use this? */ | ||
758 | encoder->private_->use_wide_by_partition = (false); /*@@@ need to set this */ | ||
759 | |||
760 | /* | ||
761 | * get the CPU info and set the function pointers | ||
762 | */ | ||
763 | FLAC__cpu_info(&encoder->private_->cpuinfo); | ||
764 | /* first default to the non-asm routines */ | ||
765 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
766 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; | ||
767 | #endif | ||
768 | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; | ||
769 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
770 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; | ||
771 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; | ||
772 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients; | ||
773 | #endif | ||
774 | /* now override with asm where appropriate */ | ||
775 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
776 | # ifndef FLAC__NO_ASM | ||
777 | if(encoder->private_->cpuinfo.use_asm) { | ||
778 | # ifdef FLAC__CPU_IA32 | ||
779 | FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); | ||
780 | # ifdef FLAC__HAS_NASM | ||
781 | # ifdef FLAC__SSE_OS | ||
782 | if(encoder->private_->cpuinfo.data.ia32.sse) { | ||
783 | if(encoder->protected_->max_lpc_order < 4) | ||
784 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4; | ||
785 | else if(encoder->protected_->max_lpc_order < 8) | ||
786 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8; | ||
787 | else if(encoder->protected_->max_lpc_order < 12) | ||
788 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12; | ||
789 | else | ||
790 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; | ||
791 | } | ||
792 | else | ||
793 | # endif /* FLAC__SSE_OS */ | ||
794 | if(encoder->private_->cpuinfo.data.ia32._3dnow) | ||
795 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow; | ||
796 | else | ||
797 | encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; | ||
798 | if(encoder->private_->cpuinfo.data.ia32.mmx) { | ||
799 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; | ||
800 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; | ||
801 | } | ||
802 | else { | ||
803 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; | ||
804 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; | ||
805 | } | ||
806 | if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov) | ||
807 | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; | ||
808 | # endif /* FLAC__HAS_NASM */ | ||
809 | # endif /* FLAC__CPU_IA32 */ | ||
810 | } | ||
811 | # endif /* !FLAC__NO_ASM */ | ||
812 | #endif /* !FLAC__INTEGER_ONLY_LIBRARY */ | ||
813 | /* finally override based on wide-ness if necessary */ | ||
814 | if(encoder->private_->use_wide_by_block) { | ||
815 | encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide; | ||
816 | } | ||
817 | |||
818 | /* we require precompute_partition_sums if do_escape_coding because of their intertwined nature */ | ||
819 | encoder->private_->precompute_partition_sums = (encoder->protected_->max_residual_partition_order > encoder->protected_->min_residual_partition_order) || encoder->protected_->do_escape_coding; | ||
820 | |||
821 | if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { | ||
822 | /* the above function sets the state for us in case of an error */ | ||
823 | return encoder->protected_->state; | ||
824 | } | ||
825 | |||
826 | if(!FLAC__bitbuffer_init(encoder->private_->frame)) | ||
827 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
828 | |||
829 | /* | ||
830 | * Set up the verify stuff if necessary | ||
831 | */ | ||
832 | if(encoder->protected_->verify) { | ||
833 | /* | ||
834 | * First, set up the fifo which will hold the | ||
835 | * original signal to compare against | ||
836 | */ | ||
837 | encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize; | ||
838 | for(i = 0; i < encoder->protected_->channels; i++) { | ||
839 | if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder->private_->verify.input_fifo.size))) | ||
840 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
841 | } | ||
842 | encoder->private_->verify.input_fifo.tail = 0; | ||
843 | |||
844 | /* | ||
845 | * Now set up a stream decoder for verification | ||
846 | */ | ||
847 | encoder->private_->verify.decoder = FLAC__stream_decoder_new(); | ||
848 | if(0 == encoder->private_->verify.decoder) | ||
849 | return encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | ||
850 | |||
851 | FLAC__stream_decoder_set_read_callback(encoder->private_->verify.decoder, verify_read_callback_); | ||
852 | FLAC__stream_decoder_set_write_callback(encoder->private_->verify.decoder, verify_write_callback_); | ||
853 | FLAC__stream_decoder_set_metadata_callback(encoder->private_->verify.decoder, verify_metadata_callback_); | ||
854 | FLAC__stream_decoder_set_error_callback(encoder->private_->verify.decoder, verify_error_callback_); | ||
855 | FLAC__stream_decoder_set_client_data(encoder->private_->verify.decoder, encoder); | ||
856 | if(FLAC__stream_decoder_init(encoder->private_->verify.decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) | ||
857 | return encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | ||
858 | } | ||
859 | encoder->private_->verify.error_stats.absolute_sample = 0; | ||
860 | encoder->private_->verify.error_stats.frame_number = 0; | ||
861 | encoder->private_->verify.error_stats.channel = 0; | ||
862 | encoder->private_->verify.error_stats.sample = 0; | ||
863 | encoder->private_->verify.error_stats.expected = 0; | ||
864 | encoder->private_->verify.error_stats.got = 0; | ||
865 | |||
866 | /* | ||
867 | * write the stream header | ||
868 | */ | ||
869 | if(encoder->protected_->verify) | ||
870 | encoder->private_->verify.state_hint = ENCODER_IN_MAGIC; | ||
871 | if(!FLAC__bitbuffer_write_raw_uint32(encoder->private_->frame, FLAC__STREAM_SYNC, FLAC__STREAM_SYNC_LEN)) | ||
872 | return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
873 | if(!write_bitbuffer_(encoder, 0)) { | ||
874 | /* the above function sets the state for us in case of an error */ | ||
875 | return encoder->protected_->state; | ||
876 | } | ||
877 | |||
878 | /* | ||
879 | * write the STREAMINFO metadata block | ||
880 | */ | ||
881 | if(encoder->protected_->verify) | ||
882 | encoder->private_->verify.state_hint = ENCODER_IN_METADATA; | ||
883 | encoder->private_->metadata.type = FLAC__METADATA_TYPE_STREAMINFO; | ||
884 | encoder->private_->metadata.is_last = false; /* we will have at a minimum a VORBIS_COMMENT afterwards */ | ||
885 | encoder->private_->metadata.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; | ||
886 | encoder->private_->metadata.data.stream_info.min_blocksize = encoder->protected_->blocksize; /* this encoder uses the same blocksize for the whole stream */ | ||
887 | encoder->private_->metadata.data.stream_info.max_blocksize = encoder->protected_->blocksize; | ||
888 | encoder->private_->metadata.data.stream_info.min_framesize = 0; /* we don't know this yet; have to fill it in later */ | ||
889 | encoder->private_->metadata.data.stream_info.max_framesize = 0; /* we don't know this yet; have to fill it in later */ | ||
890 | encoder->private_->metadata.data.stream_info.sample_rate = encoder->protected_->sample_rate; | ||
891 | encoder->private_->metadata.data.stream_info.channels = encoder->protected_->channels; | ||
892 | encoder->private_->metadata.data.stream_info.bits_per_sample = encoder->protected_->bits_per_sample; | ||
893 | encoder->private_->metadata.data.stream_info.total_samples = encoder->protected_->total_samples_estimate; /* we will replace this later with the real total */ | ||
894 | memset(encoder->private_->metadata.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */ | ||
895 | FLAC__MD5Init(&encoder->private_->md5context); | ||
896 | if(!FLAC__bitbuffer_clear(encoder->private_->frame)) | ||
897 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
898 | if(!FLAC__add_metadata_block(&encoder->private_->metadata, encoder->private_->frame)) | ||
899 | return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
900 | if(!write_bitbuffer_(encoder, 0)) { | ||
901 | /* the above function sets the state for us in case of an error */ | ||
902 | return encoder->protected_->state; | ||
903 | } | ||
904 | |||
905 | /* | ||
906 | * Now that the STREAMINFO block is written, we can init this to an | ||
907 | * absurdly-high value... | ||
908 | */ | ||
909 | encoder->private_->metadata.data.stream_info.min_framesize = (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN) - 1; | ||
910 | /* ... and clear this to 0 */ | ||
911 | encoder->private_->metadata.data.stream_info.total_samples = 0; | ||
912 | |||
913 | /* | ||
914 | * Check to see if the supplied metadata contains a VORBIS_COMMENT; | ||
915 | * if not, we will write an empty one (FLAC__add_metadata_block() | ||
916 | * automatically supplies the vendor string). | ||
917 | * | ||
918 | * WATCHOUT: libOggFLAC depends on us to write this block after the | ||
919 | * STREAMINFO since that's what the mapping requires. (In the case | ||
920 | * that metadata_has_vorbis_comment is true it will have already | ||
921 | * insured that the metadata list is properly ordered.) | ||
922 | */ | ||
923 | if(!metadata_has_vorbis_comment) { | ||
924 | FLAC__StreamMetadata vorbis_comment; | ||
925 | vorbis_comment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT; | ||
926 | vorbis_comment.is_last = (encoder->protected_->num_metadata_blocks == 0); | ||
927 | vorbis_comment.length = 4 + 4; /* MAGIC NUMBER */ | ||
928 | vorbis_comment.data.vorbis_comment.vendor_string.length = 0; | ||
929 | vorbis_comment.data.vorbis_comment.vendor_string.entry = 0; | ||
930 | vorbis_comment.data.vorbis_comment.num_comments = 0; | ||
931 | vorbis_comment.data.vorbis_comment.comments = 0; | ||
932 | if(!FLAC__bitbuffer_clear(encoder->private_->frame)) | ||
933 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
934 | if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame)) | ||
935 | return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
936 | if(!write_bitbuffer_(encoder, 0)) { | ||
937 | /* the above function sets the state for us in case of an error */ | ||
938 | return encoder->protected_->state; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | /* | ||
943 | * write the user's metadata blocks | ||
944 | */ | ||
945 | for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { | ||
946 | encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1); | ||
947 | if(!FLAC__bitbuffer_clear(encoder->private_->frame)) | ||
948 | return encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
949 | if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame)) | ||
950 | return encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
951 | if(!write_bitbuffer_(encoder, 0)) { | ||
952 | /* the above function sets the state for us in case of an error */ | ||
953 | return encoder->protected_->state; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | if(encoder->protected_->verify) | ||
958 | encoder->private_->verify.state_hint = ENCODER_IN_AUDIO; | ||
959 | |||
960 | return encoder->protected_->state; | ||
961 | } | ||
962 | |||
963 | FLAC_API void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) | ||
964 | { | ||
965 | FLAC__ASSERT(0 != encoder); | ||
966 | |||
967 | if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
968 | return; | ||
969 | |||
970 | if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) { | ||
971 | if(encoder->private_->current_sample_number != 0) { | ||
972 | encoder->protected_->blocksize = encoder->private_->current_sample_number; | ||
973 | process_frame_(encoder, true); /* true => is last frame */ | ||
974 | } | ||
975 | } | ||
976 | |||
977 | FLAC__MD5Final(encoder->private_->metadata.data.stream_info.md5sum, &encoder->private_->md5context); | ||
978 | |||
979 | if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) { | ||
980 | encoder->private_->metadata_callback(encoder, &encoder->private_->metadata, encoder->private_->client_data); | ||
981 | } | ||
982 | |||
983 | if(encoder->protected_->verify && 0 != encoder->private_->verify.decoder) | ||
984 | FLAC__stream_decoder_finish(encoder->private_->verify.decoder); | ||
985 | |||
986 | free_(encoder); | ||
987 | set_defaults_(encoder); | ||
988 | |||
989 | encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; | ||
990 | } | ||
991 | |||
992 | FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
993 | { | ||
994 | FLAC__ASSERT(0 != encoder); | ||
995 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
996 | return false; | ||
997 | #ifndef FLAC__MANDATORY_VERIFY_WHILE_ENCODING | ||
998 | encoder->protected_->verify = value; | ||
999 | #endif | ||
1000 | return true; | ||
1001 | } | ||
1002 | |||
1003 | FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1004 | { | ||
1005 | FLAC__ASSERT(0 != encoder); | ||
1006 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1007 | return false; | ||
1008 | encoder->protected_->streamable_subset = value; | ||
1009 | return true; | ||
1010 | } | ||
1011 | |||
1012 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1013 | { | ||
1014 | FLAC__ASSERT(0 != encoder); | ||
1015 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1016 | return false; | ||
1017 | encoder->protected_->do_mid_side_stereo = value; | ||
1018 | return true; | ||
1019 | } | ||
1020 | |||
1021 | FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1022 | { | ||
1023 | FLAC__ASSERT(0 != encoder); | ||
1024 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1025 | return false; | ||
1026 | encoder->protected_->loose_mid_side_stereo = value; | ||
1027 | return true; | ||
1028 | } | ||
1029 | |||
1030 | FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value) | ||
1031 | { | ||
1032 | FLAC__ASSERT(0 != encoder); | ||
1033 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1034 | return false; | ||
1035 | encoder->protected_->channels = value; | ||
1036 | return true; | ||
1037 | } | ||
1038 | |||
1039 | FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value) | ||
1040 | { | ||
1041 | FLAC__ASSERT(0 != encoder); | ||
1042 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1043 | return false; | ||
1044 | encoder->protected_->bits_per_sample = value; | ||
1045 | return true; | ||
1046 | } | ||
1047 | |||
1048 | FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value) | ||
1049 | { | ||
1050 | FLAC__ASSERT(0 != encoder); | ||
1051 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1052 | return false; | ||
1053 | encoder->protected_->sample_rate = value; | ||
1054 | return true; | ||
1055 | } | ||
1056 | |||
1057 | FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value) | ||
1058 | { | ||
1059 | FLAC__ASSERT(0 != encoder); | ||
1060 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1061 | return false; | ||
1062 | encoder->protected_->blocksize = value; | ||
1063 | return true; | ||
1064 | } | ||
1065 | |||
1066 | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value) | ||
1067 | { | ||
1068 | FLAC__ASSERT(0 != encoder); | ||
1069 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1070 | return false; | ||
1071 | encoder->protected_->max_lpc_order = value; | ||
1072 | return true; | ||
1073 | } | ||
1074 | |||
1075 | FLAC_API FLAC__bool FLAC__stream_encoder_set_qlp_coeff_precision(FLAC__StreamEncoder *encoder, unsigned value) | ||
1076 | { | ||
1077 | FLAC__ASSERT(0 != encoder); | ||
1078 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1079 | return false; | ||
1080 | encoder->protected_->qlp_coeff_precision = value; | ||
1081 | return true; | ||
1082 | } | ||
1083 | |||
1084 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_qlp_coeff_prec_search(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1085 | { | ||
1086 | FLAC__ASSERT(0 != encoder); | ||
1087 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1088 | return false; | ||
1089 | encoder->protected_->do_qlp_coeff_prec_search = value; | ||
1090 | return true; | ||
1091 | } | ||
1092 | |||
1093 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1094 | { | ||
1095 | FLAC__ASSERT(0 != encoder); | ||
1096 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1097 | return false; | ||
1098 | #if 0 | ||
1099 | /*@@@ deprecated: */ | ||
1100 | encoder->protected_->do_escape_coding = value; | ||
1101 | #else | ||
1102 | (void)value; | ||
1103 | #endif | ||
1104 | return true; | ||
1105 | } | ||
1106 | |||
1107 | FLAC_API FLAC__bool FLAC__stream_encoder_set_do_exhaustive_model_search(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1108 | { | ||
1109 | FLAC__ASSERT(0 != encoder); | ||
1110 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1111 | return false; | ||
1112 | encoder->protected_->do_exhaustive_model_search = value; | ||
1113 | return true; | ||
1114 | } | ||
1115 | |||
1116 | FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value) | ||
1117 | { | ||
1118 | FLAC__ASSERT(0 != encoder); | ||
1119 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1120 | return false; | ||
1121 | encoder->protected_->min_residual_partition_order = value; | ||
1122 | return true; | ||
1123 | } | ||
1124 | |||
1125 | FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value) | ||
1126 | { | ||
1127 | FLAC__ASSERT(0 != encoder); | ||
1128 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1129 | return false; | ||
1130 | encoder->protected_->max_residual_partition_order = value; | ||
1131 | return true; | ||
1132 | } | ||
1133 | |||
1134 | FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value) | ||
1135 | { | ||
1136 | FLAC__ASSERT(0 != encoder); | ||
1137 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1138 | return false; | ||
1139 | #if 0 | ||
1140 | /*@@@ deprecated: */ | ||
1141 | encoder->protected_->rice_parameter_search_dist = value; | ||
1142 | #else | ||
1143 | (void)value; | ||
1144 | #endif | ||
1145 | return true; | ||
1146 | } | ||
1147 | |||
1148 | FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value) | ||
1149 | { | ||
1150 | FLAC__ASSERT(0 != encoder); | ||
1151 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1152 | return false; | ||
1153 | encoder->protected_->total_samples_estimate = value; | ||
1154 | return true; | ||
1155 | } | ||
1156 | |||
1157 | FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) | ||
1158 | { | ||
1159 | FLAC__ASSERT(0 != encoder); | ||
1160 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1161 | return false; | ||
1162 | encoder->protected_->metadata = metadata; | ||
1163 | encoder->protected_->num_metadata_blocks = num_blocks; | ||
1164 | return true; | ||
1165 | } | ||
1166 | |||
1167 | FLAC_API FLAC__bool FLAC__stream_encoder_set_write_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteCallback value) | ||
1168 | { | ||
1169 | FLAC__ASSERT(0 != encoder); | ||
1170 | FLAC__ASSERT(0 != value); | ||
1171 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1172 | return false; | ||
1173 | encoder->private_->write_callback = value; | ||
1174 | return true; | ||
1175 | } | ||
1176 | |||
1177 | FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderMetadataCallback value) | ||
1178 | { | ||
1179 | FLAC__ASSERT(0 != encoder); | ||
1180 | FLAC__ASSERT(0 != value); | ||
1181 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1182 | return false; | ||
1183 | encoder->private_->metadata_callback = value; | ||
1184 | return true; | ||
1185 | } | ||
1186 | |||
1187 | FLAC_API FLAC__bool FLAC__stream_encoder_set_client_data(FLAC__StreamEncoder *encoder, void *value) | ||
1188 | { | ||
1189 | FLAC__ASSERT(0 != encoder); | ||
1190 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1191 | return false; | ||
1192 | encoder->private_->client_data = value; | ||
1193 | return true; | ||
1194 | } | ||
1195 | |||
1196 | /* | ||
1197 | * These three functions are not static, but not publically exposed in | ||
1198 | * include/FLAC/ either. They are used by the test suite. | ||
1199 | */ | ||
1200 | FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1201 | { | ||
1202 | FLAC__ASSERT(0 != encoder); | ||
1203 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1204 | return false; | ||
1205 | encoder->private_->disable_constant_subframes = value; | ||
1206 | return true; | ||
1207 | } | ||
1208 | |||
1209 | FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1210 | { | ||
1211 | FLAC__ASSERT(0 != encoder); | ||
1212 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1213 | return false; | ||
1214 | encoder->private_->disable_fixed_subframes = value; | ||
1215 | return true; | ||
1216 | } | ||
1217 | |||
1218 | FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) | ||
1219 | { | ||
1220 | FLAC__ASSERT(0 != encoder); | ||
1221 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) | ||
1222 | return false; | ||
1223 | encoder->private_->disable_verbatim_subframes = value; | ||
1224 | return true; | ||
1225 | } | ||
1226 | |||
1227 | FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder) | ||
1228 | { | ||
1229 | FLAC__ASSERT(0 != encoder); | ||
1230 | return encoder->protected_->state; | ||
1231 | } | ||
1232 | |||
1233 | FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder) | ||
1234 | { | ||
1235 | FLAC__ASSERT(0 != encoder); | ||
1236 | if(encoder->protected_->verify) | ||
1237 | return FLAC__stream_decoder_get_state(encoder->private_->verify.decoder); | ||
1238 | else | ||
1239 | return FLAC__STREAM_DECODER_UNINITIALIZED; | ||
1240 | } | ||
1241 | |||
1242 | FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder) | ||
1243 | { | ||
1244 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) | ||
1245 | return FLAC__StreamEncoderStateString[encoder->protected_->state]; | ||
1246 | else | ||
1247 | return FLAC__stream_decoder_get_resolved_state_string(encoder->private_->verify.decoder); | ||
1248 | } | ||
1249 | |||
1250 | FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got) | ||
1251 | { | ||
1252 | FLAC__ASSERT(0 != encoder); | ||
1253 | if(0 != absolute_sample) | ||
1254 | *absolute_sample = encoder->private_->verify.error_stats.absolute_sample; | ||
1255 | if(0 != frame_number) | ||
1256 | *frame_number = encoder->private_->verify.error_stats.frame_number; | ||
1257 | if(0 != channel) | ||
1258 | *channel = encoder->private_->verify.error_stats.channel; | ||
1259 | if(0 != sample) | ||
1260 | *sample = encoder->private_->verify.error_stats.sample; | ||
1261 | if(0 != expected) | ||
1262 | *expected = encoder->private_->verify.error_stats.expected; | ||
1263 | if(0 != got) | ||
1264 | *got = encoder->private_->verify.error_stats.got; | ||
1265 | } | ||
1266 | |||
1267 | FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder) | ||
1268 | { | ||
1269 | FLAC__ASSERT(0 != encoder); | ||
1270 | return encoder->protected_->verify; | ||
1271 | } | ||
1272 | |||
1273 | FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__StreamEncoder *encoder) | ||
1274 | { | ||
1275 | FLAC__ASSERT(0 != encoder); | ||
1276 | return encoder->protected_->streamable_subset; | ||
1277 | } | ||
1278 | |||
1279 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_mid_side_stereo(const FLAC__StreamEncoder *encoder) | ||
1280 | { | ||
1281 | FLAC__ASSERT(0 != encoder); | ||
1282 | return encoder->protected_->do_mid_side_stereo; | ||
1283 | } | ||
1284 | |||
1285 | FLAC_API FLAC__bool FLAC__stream_encoder_get_loose_mid_side_stereo(const FLAC__StreamEncoder *encoder) | ||
1286 | { | ||
1287 | FLAC__ASSERT(0 != encoder); | ||
1288 | return encoder->protected_->loose_mid_side_stereo; | ||
1289 | } | ||
1290 | |||
1291 | FLAC_API unsigned FLAC__stream_encoder_get_channels(const FLAC__StreamEncoder *encoder) | ||
1292 | { | ||
1293 | FLAC__ASSERT(0 != encoder); | ||
1294 | return encoder->protected_->channels; | ||
1295 | } | ||
1296 | |||
1297 | FLAC_API unsigned FLAC__stream_encoder_get_bits_per_sample(const FLAC__StreamEncoder *encoder) | ||
1298 | { | ||
1299 | FLAC__ASSERT(0 != encoder); | ||
1300 | return encoder->protected_->bits_per_sample; | ||
1301 | } | ||
1302 | |||
1303 | FLAC_API unsigned FLAC__stream_encoder_get_sample_rate(const FLAC__StreamEncoder *encoder) | ||
1304 | { | ||
1305 | FLAC__ASSERT(0 != encoder); | ||
1306 | return encoder->protected_->sample_rate; | ||
1307 | } | ||
1308 | |||
1309 | FLAC_API unsigned FLAC__stream_encoder_get_blocksize(const FLAC__StreamEncoder *encoder) | ||
1310 | { | ||
1311 | FLAC__ASSERT(0 != encoder); | ||
1312 | return encoder->protected_->blocksize; | ||
1313 | } | ||
1314 | |||
1315 | FLAC_API unsigned FLAC__stream_encoder_get_max_lpc_order(const FLAC__StreamEncoder *encoder) | ||
1316 | { | ||
1317 | FLAC__ASSERT(0 != encoder); | ||
1318 | return encoder->protected_->max_lpc_order; | ||
1319 | } | ||
1320 | |||
1321 | FLAC_API unsigned FLAC__stream_encoder_get_qlp_coeff_precision(const FLAC__StreamEncoder *encoder) | ||
1322 | { | ||
1323 | FLAC__ASSERT(0 != encoder); | ||
1324 | return encoder->protected_->qlp_coeff_precision; | ||
1325 | } | ||
1326 | |||
1327 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__StreamEncoder *encoder) | ||
1328 | { | ||
1329 | FLAC__ASSERT(0 != encoder); | ||
1330 | return encoder->protected_->do_qlp_coeff_prec_search; | ||
1331 | } | ||
1332 | |||
1333 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_escape_coding(const FLAC__StreamEncoder *encoder) | ||
1334 | { | ||
1335 | FLAC__ASSERT(0 != encoder); | ||
1336 | return encoder->protected_->do_escape_coding; | ||
1337 | } | ||
1338 | |||
1339 | FLAC_API FLAC__bool FLAC__stream_encoder_get_do_exhaustive_model_search(const FLAC__StreamEncoder *encoder) | ||
1340 | { | ||
1341 | FLAC__ASSERT(0 != encoder); | ||
1342 | return encoder->protected_->do_exhaustive_model_search; | ||
1343 | } | ||
1344 | |||
1345 | FLAC_API unsigned FLAC__stream_encoder_get_min_residual_partition_order(const FLAC__StreamEncoder *encoder) | ||
1346 | { | ||
1347 | FLAC__ASSERT(0 != encoder); | ||
1348 | return encoder->protected_->min_residual_partition_order; | ||
1349 | } | ||
1350 | |||
1351 | FLAC_API unsigned FLAC__stream_encoder_get_max_residual_partition_order(const FLAC__StreamEncoder *encoder) | ||
1352 | { | ||
1353 | FLAC__ASSERT(0 != encoder); | ||
1354 | return encoder->protected_->max_residual_partition_order; | ||
1355 | } | ||
1356 | |||
1357 | FLAC_API unsigned FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC__StreamEncoder *encoder) | ||
1358 | { | ||
1359 | FLAC__ASSERT(0 != encoder); | ||
1360 | return encoder->protected_->rice_parameter_search_dist; | ||
1361 | } | ||
1362 | |||
1363 | FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder) | ||
1364 | { | ||
1365 | FLAC__ASSERT(0 != encoder); | ||
1366 | return encoder->protected_->total_samples_estimate; | ||
1367 | } | ||
1368 | |||
1369 | FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) | ||
1370 | { | ||
1371 | unsigned i, j, channel; | ||
1372 | FLAC__int32 x, mid, side; | ||
1373 | const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; | ||
1374 | |||
1375 | FLAC__ASSERT(0 != encoder); | ||
1376 | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | ||
1377 | |||
1378 | j = 0; | ||
1379 | /* | ||
1380 | * we have several flavors of the same basic loop, optimized for | ||
1381 | * different conditions: | ||
1382 | */ | ||
1383 | if(encoder->protected_->max_lpc_order > 0) { | ||
1384 | if(encoder->protected_->do_mid_side_stereo && channels == 2) { | ||
1385 | /* | ||
1386 | * stereo coding: unroll channel loop | ||
1387 | * with LPC: calculate floating point version of signal | ||
1388 | */ | ||
1389 | do { | ||
1390 | if(encoder->protected_->verify) | ||
1391 | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1392 | |||
1393 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1394 | x = mid = side = buffer[0][j]; | ||
1395 | encoder->private_->integer_signal[0][i] = x; | ||
1396 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1397 | encoder->private_->real_signal[0][i] = (FLAC__real)x; | ||
1398 | #endif | ||
1399 | x = buffer[1][j]; | ||
1400 | encoder->private_->integer_signal[1][i] = x; | ||
1401 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1402 | encoder->private_->real_signal[1][i] = (FLAC__real)x; | ||
1403 | #endif | ||
1404 | mid += x; | ||
1405 | side -= x; | ||
1406 | mid >>= 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ | ||
1407 | encoder->private_->integer_signal_mid_side[1][i] = side; | ||
1408 | encoder->private_->integer_signal_mid_side[0][i] = mid; | ||
1409 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1410 | encoder->private_->real_signal_mid_side[1][i] = (FLAC__real)side; | ||
1411 | encoder->private_->real_signal_mid_side[0][i] = (FLAC__real)mid; | ||
1412 | #endif | ||
1413 | encoder->private_->current_sample_number++; | ||
1414 | } | ||
1415 | if(i == blocksize) { | ||
1416 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1417 | return false; | ||
1418 | } | ||
1419 | } while(j < samples); | ||
1420 | } | ||
1421 | else { | ||
1422 | /* | ||
1423 | * independent channel coding: buffer each channel in inner loop | ||
1424 | * with LPC: calculate floating point version of signal | ||
1425 | */ | ||
1426 | do { | ||
1427 | if(encoder->protected_->verify) | ||
1428 | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1429 | |||
1430 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1431 | for(channel = 0; channel < channels; channel++) { | ||
1432 | x = buffer[channel][j]; | ||
1433 | encoder->private_->integer_signal[channel][i] = x; | ||
1434 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1435 | encoder->private_->real_signal[channel][i] = (FLAC__real)x; | ||
1436 | #endif | ||
1437 | } | ||
1438 | encoder->private_->current_sample_number++; | ||
1439 | } | ||
1440 | if(i == blocksize) { | ||
1441 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1442 | return false; | ||
1443 | } | ||
1444 | } while(j < samples); | ||
1445 | } | ||
1446 | } | ||
1447 | else { | ||
1448 | if(encoder->protected_->do_mid_side_stereo && channels == 2) { | ||
1449 | /* | ||
1450 | * stereo coding: unroll channel loop | ||
1451 | * without LPC: no need to calculate floating point version of signal | ||
1452 | */ | ||
1453 | do { | ||
1454 | if(encoder->protected_->verify) | ||
1455 | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1456 | |||
1457 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1458 | encoder->private_->integer_signal[0][i] = mid = side = buffer[0][j]; | ||
1459 | x = buffer[1][j]; | ||
1460 | encoder->private_->integer_signal[1][i] = x; | ||
1461 | mid += x; | ||
1462 | side -= x; | ||
1463 | mid >>= 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ | ||
1464 | encoder->private_->integer_signal_mid_side[1][i] = side; | ||
1465 | encoder->private_->integer_signal_mid_side[0][i] = mid; | ||
1466 | encoder->private_->current_sample_number++; | ||
1467 | } | ||
1468 | if(i == blocksize) { | ||
1469 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1470 | return false; | ||
1471 | } | ||
1472 | } while(j < samples); | ||
1473 | } | ||
1474 | else { | ||
1475 | /* | ||
1476 | * independent channel coding: buffer each channel in inner loop | ||
1477 | * without LPC: no need to calculate floating point version of signal | ||
1478 | */ | ||
1479 | do { | ||
1480 | if(encoder->protected_->verify) | ||
1481 | append_to_verify_fifo_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1482 | |||
1483 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1484 | for(channel = 0; channel < channels; channel++) | ||
1485 | encoder->private_->integer_signal[channel][i] = buffer[channel][j]; | ||
1486 | encoder->private_->current_sample_number++; | ||
1487 | } | ||
1488 | if(i == blocksize) { | ||
1489 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1490 | return false; | ||
1491 | } | ||
1492 | } while(j < samples); | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1496 | return true; | ||
1497 | } | ||
1498 | |||
1499 | FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) | ||
1500 | { | ||
1501 | unsigned i, j, k, channel; | ||
1502 | FLAC__int32 x, mid, side; | ||
1503 | const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; | ||
1504 | |||
1505 | FLAC__ASSERT(0 != encoder); | ||
1506 | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | ||
1507 | |||
1508 | j = k = 0; | ||
1509 | /* | ||
1510 | * we have several flavors of the same basic loop, optimized for | ||
1511 | * different conditions: | ||
1512 | */ | ||
1513 | if(encoder->protected_->max_lpc_order > 0) { | ||
1514 | if(encoder->protected_->do_mid_side_stereo && channels == 2) { | ||
1515 | /* | ||
1516 | * stereo coding: unroll channel loop | ||
1517 | * with LPC: calculate floating point version of signal | ||
1518 | */ | ||
1519 | do { | ||
1520 | if(encoder->protected_->verify) | ||
1521 | append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1522 | |||
1523 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1524 | x = mid = side = buffer[k++]; | ||
1525 | encoder->private_->integer_signal[0][i] = x; | ||
1526 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1527 | encoder->private_->real_signal[0][i] = (FLAC__real)x; | ||
1528 | #endif | ||
1529 | x = buffer[k++]; | ||
1530 | encoder->private_->integer_signal[1][i] = x; | ||
1531 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1532 | encoder->private_->real_signal[1][i] = (FLAC__real)x; | ||
1533 | #endif | ||
1534 | mid += x; | ||
1535 | side -= x; | ||
1536 | mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */ | ||
1537 | encoder->private_->integer_signal_mid_side[1][i] = side; | ||
1538 | encoder->private_->integer_signal_mid_side[0][i] = mid; | ||
1539 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1540 | encoder->private_->real_signal_mid_side[1][i] = (FLAC__real)side; | ||
1541 | encoder->private_->real_signal_mid_side[0][i] = (FLAC__real)mid; | ||
1542 | #endif | ||
1543 | encoder->private_->current_sample_number++; | ||
1544 | } | ||
1545 | if(i == blocksize) { | ||
1546 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1547 | return false; | ||
1548 | } | ||
1549 | } while(j < samples); | ||
1550 | } | ||
1551 | else { | ||
1552 | /* | ||
1553 | * independent channel coding: buffer each channel in inner loop | ||
1554 | * with LPC: calculate floating point version of signal | ||
1555 | */ | ||
1556 | do { | ||
1557 | if(encoder->protected_->verify) | ||
1558 | append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1559 | |||
1560 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1561 | for(channel = 0; channel < channels; channel++) { | ||
1562 | x = buffer[k++]; | ||
1563 | encoder->private_->integer_signal[channel][i] = x; | ||
1564 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1565 | encoder->private_->real_signal[channel][i] = (FLAC__real)x; | ||
1566 | #endif | ||
1567 | } | ||
1568 | encoder->private_->current_sample_number++; | ||
1569 | } | ||
1570 | if(i == blocksize) { | ||
1571 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1572 | return false; | ||
1573 | } | ||
1574 | } while(j < samples); | ||
1575 | } | ||
1576 | } | ||
1577 | else { | ||
1578 | if(encoder->protected_->do_mid_side_stereo && channels == 2) { | ||
1579 | /* | ||
1580 | * stereo coding: unroll channel loop | ||
1581 | * without LPC: no need to calculate floating point version of signal | ||
1582 | */ | ||
1583 | do { | ||
1584 | if(encoder->protected_->verify) | ||
1585 | append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1586 | |||
1587 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1588 | encoder->private_->integer_signal[0][i] = mid = side = buffer[k++]; | ||
1589 | x = buffer[k++]; | ||
1590 | encoder->private_->integer_signal[1][i] = x; | ||
1591 | mid += x; | ||
1592 | side -= x; | ||
1593 | mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */ | ||
1594 | encoder->private_->integer_signal_mid_side[1][i] = side; | ||
1595 | encoder->private_->integer_signal_mid_side[0][i] = mid; | ||
1596 | encoder->private_->current_sample_number++; | ||
1597 | } | ||
1598 | if(i == blocksize) { | ||
1599 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1600 | return false; | ||
1601 | } | ||
1602 | } while(j < samples); | ||
1603 | } | ||
1604 | else { | ||
1605 | /* | ||
1606 | * independent channel coding: buffer each channel in inner loop | ||
1607 | * without LPC: no need to calculate floating point version of signal | ||
1608 | */ | ||
1609 | do { | ||
1610 | if(encoder->protected_->verify) | ||
1611 | append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, min(blocksize-encoder->private_->current_sample_number, samples-j)); | ||
1612 | |||
1613 | for(i = encoder->private_->current_sample_number; i < blocksize && j < samples; i++, j++) { | ||
1614 | for(channel = 0; channel < channels; channel++) | ||
1615 | encoder->private_->integer_signal[channel][i] = buffer[k++]; | ||
1616 | encoder->private_->current_sample_number++; | ||
1617 | } | ||
1618 | if(i == blocksize) { | ||
1619 | if(!process_frame_(encoder, false)) /* false => not last frame */ | ||
1620 | return false; | ||
1621 | } | ||
1622 | } while(j < samples); | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | return true; | ||
1627 | } | ||
1628 | |||
1629 | /*********************************************************************** | ||
1630 | * | ||
1631 | * Private class methods | ||
1632 | * | ||
1633 | ***********************************************************************/ | ||
1634 | |||
1635 | void set_defaults_(FLAC__StreamEncoder *encoder) | ||
1636 | { | ||
1637 | FLAC__ASSERT(0 != encoder); | ||
1638 | |||
1639 | #ifdef FLAC__MANDATORY_VERIFY_WHILE_ENCODING | ||
1640 | encoder->protected_->verify = true; | ||
1641 | #else | ||
1642 | encoder->protected_->verify = false; | ||
1643 | #endif | ||
1644 | encoder->protected_->streamable_subset = true; | ||
1645 | encoder->protected_->do_mid_side_stereo = false; | ||
1646 | encoder->protected_->loose_mid_side_stereo = false; | ||
1647 | encoder->protected_->channels = 2; | ||
1648 | encoder->protected_->bits_per_sample = 16; | ||
1649 | encoder->protected_->sample_rate = 44100; | ||
1650 | encoder->protected_->blocksize = 1152; | ||
1651 | encoder->protected_->max_lpc_order = 0; | ||
1652 | encoder->protected_->qlp_coeff_precision = 0; | ||
1653 | encoder->protected_->do_qlp_coeff_prec_search = false; | ||
1654 | encoder->protected_->do_exhaustive_model_search = false; | ||
1655 | encoder->protected_->do_escape_coding = false; | ||
1656 | encoder->protected_->min_residual_partition_order = 0; | ||
1657 | encoder->protected_->max_residual_partition_order = 0; | ||
1658 | encoder->protected_->rice_parameter_search_dist = 0; | ||
1659 | encoder->protected_->total_samples_estimate = 0; | ||
1660 | encoder->protected_->metadata = 0; | ||
1661 | encoder->protected_->num_metadata_blocks = 0; | ||
1662 | |||
1663 | encoder->private_->disable_constant_subframes = false; | ||
1664 | encoder->private_->disable_fixed_subframes = false; | ||
1665 | encoder->private_->disable_verbatim_subframes = false; | ||
1666 | encoder->private_->write_callback = 0; | ||
1667 | encoder->private_->metadata_callback = 0; | ||
1668 | encoder->private_->client_data = 0; | ||
1669 | } | ||
1670 | |||
1671 | void free_(FLAC__StreamEncoder *encoder) | ||
1672 | { | ||
1673 | unsigned i, channel; | ||
1674 | |||
1675 | FLAC__ASSERT(0 != encoder); | ||
1676 | for(i = 0; i < encoder->protected_->channels; i++) { | ||
1677 | if(0 != encoder->private_->integer_signal_unaligned[i]) { | ||
1678 | free(encoder->private_->integer_signal_unaligned[i]); | ||
1679 | encoder->private_->integer_signal_unaligned[i] = 0; | ||
1680 | } | ||
1681 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1682 | if(0 != encoder->private_->real_signal_unaligned[i]) { | ||
1683 | free(encoder->private_->real_signal_unaligned[i]); | ||
1684 | encoder->private_->real_signal_unaligned[i] = 0; | ||
1685 | } | ||
1686 | #endif | ||
1687 | } | ||
1688 | for(i = 0; i < 2; i++) { | ||
1689 | if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) { | ||
1690 | free(encoder->private_->integer_signal_mid_side_unaligned[i]); | ||
1691 | encoder->private_->integer_signal_mid_side_unaligned[i] = 0; | ||
1692 | } | ||
1693 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1694 | if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) { | ||
1695 | free(encoder->private_->real_signal_mid_side_unaligned[i]); | ||
1696 | encoder->private_->real_signal_mid_side_unaligned[i] = 0; | ||
1697 | } | ||
1698 | #endif | ||
1699 | } | ||
1700 | for(channel = 0; channel < encoder->protected_->channels; channel++) { | ||
1701 | for(i = 0; i < 2; i++) { | ||
1702 | if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) { | ||
1703 | free(encoder->private_->residual_workspace_unaligned[channel][i]); | ||
1704 | encoder->private_->residual_workspace_unaligned[channel][i] = 0; | ||
1705 | } | ||
1706 | } | ||
1707 | } | ||
1708 | for(channel = 0; channel < 2; channel++) { | ||
1709 | for(i = 0; i < 2; i++) { | ||
1710 | if(0 != encoder->private_->residual_workspace_mid_side_unaligned[channel][i]) { | ||
1711 | free(encoder->private_->residual_workspace_mid_side_unaligned[channel][i]); | ||
1712 | encoder->private_->residual_workspace_mid_side_unaligned[channel][i] = 0; | ||
1713 | } | ||
1714 | } | ||
1715 | } | ||
1716 | if(0 != encoder->private_->abs_residual_unaligned) { | ||
1717 | free(encoder->private_->abs_residual_unaligned); | ||
1718 | encoder->private_->abs_residual_unaligned = 0; | ||
1719 | } | ||
1720 | if(0 != encoder->private_->abs_residual_partition_sums_unaligned) { | ||
1721 | free(encoder->private_->abs_residual_partition_sums_unaligned); | ||
1722 | encoder->private_->abs_residual_partition_sums_unaligned = 0; | ||
1723 | } | ||
1724 | if(0 != encoder->private_->raw_bits_per_partition_unaligned) { | ||
1725 | free(encoder->private_->raw_bits_per_partition_unaligned); | ||
1726 | encoder->private_->raw_bits_per_partition_unaligned = 0; | ||
1727 | } | ||
1728 | if(encoder->protected_->verify) { | ||
1729 | for(i = 0; i < encoder->protected_->channels; i++) { | ||
1730 | if(0 != encoder->private_->verify.input_fifo.data[i]) { | ||
1731 | free(encoder->private_->verify.input_fifo.data[i]); | ||
1732 | encoder->private_->verify.input_fifo.data[i] = 0; | ||
1733 | } | ||
1734 | } | ||
1735 | } | ||
1736 | FLAC__bitbuffer_free(encoder->private_->frame); | ||
1737 | } | ||
1738 | |||
1739 | FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size) | ||
1740 | { | ||
1741 | FLAC__bool ok; | ||
1742 | unsigned i, channel; | ||
1743 | |||
1744 | FLAC__ASSERT(new_size > 0); | ||
1745 | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | ||
1746 | FLAC__ASSERT(encoder->private_->current_sample_number == 0); | ||
1747 | |||
1748 | /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */ | ||
1749 | if(new_size <= encoder->private_->input_capacity) | ||
1750 | return true; | ||
1751 | |||
1752 | ok = true; | ||
1753 | |||
1754 | /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() | ||
1755 | * requires that the input arrays (in our case the integer signals) | ||
1756 | * have a buffer of up to 3 zeroes in front (at negative indices) for | ||
1757 | * alignment purposes; we use 4 to keep the data well-aligned. | ||
1758 | */ | ||
1759 | |||
1760 | for(i = 0; ok && i < encoder->protected_->channels; i++) { | ||
1761 | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size+4, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]); | ||
1762 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1763 | if(encoder->protected_->max_lpc_order > 0) | ||
1764 | ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]); | ||
1765 | #endif | ||
1766 | memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4); | ||
1767 | encoder->private_->integer_signal[i] += 4; | ||
1768 | } | ||
1769 | for(i = 0; ok && i < 2; i++) { | ||
1770 | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size+4, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]); | ||
1771 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1772 | if(encoder->protected_->max_lpc_order > 0) | ||
1773 | ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]); | ||
1774 | #endif | ||
1775 | memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); | ||
1776 | encoder->private_->integer_signal_mid_side[i] += 4; | ||
1777 | } | ||
1778 | for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { | ||
1779 | for(i = 0; ok && i < 2; i++) { | ||
1780 | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]); | ||
1781 | } | ||
1782 | } | ||
1783 | for(channel = 0; ok && channel < 2; channel++) { | ||
1784 | for(i = 0; ok && i < 2; i++) { | ||
1785 | ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]); | ||
1786 | } | ||
1787 | } | ||
1788 | ok = ok && FLAC__memory_alloc_aligned_uint32_array(new_size, &encoder->private_->abs_residual_unaligned, &encoder->private_->abs_residual); | ||
1789 | if(encoder->private_->precompute_partition_sums || encoder->protected_->do_escape_coding) /* we require precompute_partition_sums if do_escape_coding because of their intertwined nature */ | ||
1790 | ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_size * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums); | ||
1791 | if(encoder->protected_->do_escape_coding) | ||
1792 | ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_size * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition); | ||
1793 | |||
1794 | if(ok) | ||
1795 | encoder->private_->input_capacity = new_size; | ||
1796 | else | ||
1797 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
1798 | |||
1799 | return ok; | ||
1800 | } | ||
1801 | |||
1802 | FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, unsigned samples) | ||
1803 | { | ||
1804 | const FLAC__byte *buffer; | ||
1805 | unsigned bytes; | ||
1806 | |||
1807 | FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(encoder->private_->frame)); | ||
1808 | |||
1809 | FLAC__bitbuffer_get_buffer(encoder->private_->frame, &buffer, &bytes); | ||
1810 | |||
1811 | if(encoder->protected_->verify) { | ||
1812 | encoder->private_->verify.output.data = buffer; | ||
1813 | encoder->private_->verify.output.bytes = bytes; | ||
1814 | if(encoder->private_->verify.state_hint == ENCODER_IN_MAGIC) { | ||
1815 | encoder->private_->verify.needs_magic_hack = true; | ||
1816 | } | ||
1817 | else { | ||
1818 | if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)) { | ||
1819 | FLAC__bitbuffer_release_buffer(encoder->private_->frame); | ||
1820 | if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) | ||
1821 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | ||
1822 | return false; | ||
1823 | } | ||
1824 | } | ||
1825 | } | ||
1826 | |||
1827 | if(encoder->private_->write_callback(encoder, buffer, bytes, samples, encoder->private_->current_frame_number, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) { | ||
1828 | FLAC__bitbuffer_release_buffer(encoder->private_->frame); | ||
1829 | encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_WRITING; | ||
1830 | return false; | ||
1831 | } | ||
1832 | |||
1833 | FLAC__bitbuffer_release_buffer(encoder->private_->frame); | ||
1834 | |||
1835 | if(samples > 0) { | ||
1836 | encoder->private_->metadata.data.stream_info.min_framesize = min(bytes, encoder->private_->metadata.data.stream_info.min_framesize); | ||
1837 | encoder->private_->metadata.data.stream_info.max_framesize = max(bytes, encoder->private_->metadata.data.stream_info.max_framesize); | ||
1838 | } | ||
1839 | |||
1840 | return true; | ||
1841 | } | ||
1842 | |||
1843 | FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) | ||
1844 | { | ||
1845 | FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); | ||
1846 | |||
1847 | /* | ||
1848 | * Accumulate raw signal to the MD5 signature | ||
1849 | */ | ||
1850 | if(!FLAC__MD5Accumulate(&encoder->private_->md5context, (const FLAC__int32 * const *)encoder->private_->integer_signal, encoder->protected_->channels, encoder->protected_->blocksize, (encoder->protected_->bits_per_sample+7) / 8)) { | ||
1851 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
1852 | return false; | ||
1853 | } | ||
1854 | |||
1855 | /* | ||
1856 | * Process the frame header and subframes into the frame bitbuffer | ||
1857 | */ | ||
1858 | if(!process_subframes_(encoder, is_last_frame)) { | ||
1859 | /* the above function sets the state for us in case of an error */ | ||
1860 | return false; | ||
1861 | } | ||
1862 | |||
1863 | /* | ||
1864 | * Zero-pad the frame to a byte_boundary | ||
1865 | */ | ||
1866 | if(!FLAC__bitbuffer_zero_pad_to_byte_boundary(encoder->private_->frame)) { | ||
1867 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
1868 | return false; | ||
1869 | } | ||
1870 | |||
1871 | /* | ||
1872 | * CRC-16 the whole thing | ||
1873 | */ | ||
1874 | FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(encoder->private_->frame)); | ||
1875 | FLAC__bitbuffer_write_raw_uint32(encoder->private_->frame, FLAC__bitbuffer_get_write_crc16(encoder->private_->frame), FLAC__FRAME_FOOTER_CRC_LEN); | ||
1876 | |||
1877 | /* | ||
1878 | * Write it | ||
1879 | */ | ||
1880 | if(!write_bitbuffer_(encoder, encoder->protected_->blocksize)) { | ||
1881 | /* the above function sets the state for us in case of an error */ | ||
1882 | return false; | ||
1883 | } | ||
1884 | |||
1885 | /* | ||
1886 | * Get ready for the next frame | ||
1887 | */ | ||
1888 | encoder->private_->current_sample_number = 0; | ||
1889 | encoder->private_->current_frame_number++; | ||
1890 | encoder->private_->metadata.data.stream_info.total_samples += (FLAC__uint64)encoder->protected_->blocksize; | ||
1891 | |||
1892 | return true; | ||
1893 | } | ||
1894 | |||
1895 | FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) | ||
1896 | { | ||
1897 | FLAC__FrameHeader frame_header; | ||
1898 | unsigned channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order; | ||
1899 | FLAC__bool do_independent, do_mid_side, precompute_partition_sums; | ||
1900 | |||
1901 | /* | ||
1902 | * Calculate the min,max Rice partition orders | ||
1903 | */ | ||
1904 | if(is_last_frame) { | ||
1905 | max_partition_order = 0; | ||
1906 | } | ||
1907 | else { | ||
1908 | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); | ||
1909 | max_partition_order = min(max_partition_order, encoder->protected_->max_residual_partition_order); | ||
1910 | } | ||
1911 | min_partition_order = min(min_partition_order, max_partition_order); | ||
1912 | |||
1913 | precompute_partition_sums = encoder->private_->precompute_partition_sums && ((max_partition_order > min_partition_order) || encoder->protected_->do_escape_coding); | ||
1914 | |||
1915 | /* | ||
1916 | * Setup the frame | ||
1917 | */ | ||
1918 | if(!FLAC__bitbuffer_clear(encoder->private_->frame)) { | ||
1919 | encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
1920 | return false; | ||
1921 | } | ||
1922 | frame_header.blocksize = encoder->protected_->blocksize; | ||
1923 | frame_header.sample_rate = encoder->protected_->sample_rate; | ||
1924 | frame_header.channels = encoder->protected_->channels; | ||
1925 | frame_header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; /* the default unless the encoder determines otherwise */ | ||
1926 | frame_header.bits_per_sample = encoder->protected_->bits_per_sample; | ||
1927 | frame_header.number_type = FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER; | ||
1928 | frame_header.number.frame_number = encoder->private_->current_frame_number; | ||
1929 | |||
1930 | /* | ||
1931 | * Figure out what channel assignments to try | ||
1932 | */ | ||
1933 | if(encoder->protected_->do_mid_side_stereo) { | ||
1934 | if(encoder->protected_->loose_mid_side_stereo) { | ||
1935 | if(encoder->private_->loose_mid_side_stereo_frame_count == 0) { | ||
1936 | do_independent = true; | ||
1937 | do_mid_side = true; | ||
1938 | } | ||
1939 | else { | ||
1940 | do_independent = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT); | ||
1941 | do_mid_side = !do_independent; | ||
1942 | } | ||
1943 | } | ||
1944 | else { | ||
1945 | do_independent = true; | ||
1946 | do_mid_side = true; | ||
1947 | } | ||
1948 | } | ||
1949 | else { | ||
1950 | do_independent = true; | ||
1951 | do_mid_side = false; | ||
1952 | } | ||
1953 | |||
1954 | FLAC__ASSERT(do_independent || do_mid_side); | ||
1955 | |||
1956 | /* | ||
1957 | * Check for wasted bits; set effective bps for each subframe | ||
1958 | */ | ||
1959 | if(do_independent) { | ||
1960 | for(channel = 0; channel < encoder->protected_->channels; channel++) { | ||
1961 | const unsigned w = get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize); | ||
1962 | encoder->private_->subframe_workspace[channel][0].wasted_bits = encoder->private_->subframe_workspace[channel][1].wasted_bits = w; | ||
1963 | encoder->private_->subframe_bps[channel] = encoder->protected_->bits_per_sample - w; | ||
1964 | } | ||
1965 | } | ||
1966 | if(do_mid_side) { | ||
1967 | FLAC__ASSERT(encoder->protected_->channels == 2); | ||
1968 | for(channel = 0; channel < 2; channel++) { | ||
1969 | const unsigned w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); | ||
1970 | encoder->private_->subframe_workspace_mid_side[channel][0].wasted_bits = encoder->private_->subframe_workspace_mid_side[channel][1].wasted_bits = w; | ||
1971 | encoder->private_->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1); | ||
1972 | } | ||
1973 | } | ||
1974 | |||
1975 | /* | ||
1976 | * First do a normal encoding pass of each independent channel | ||
1977 | */ | ||
1978 | if(do_independent) { | ||
1979 | for(channel = 0; channel < encoder->protected_->channels; channel++) { | ||
1980 | if(! | ||
1981 | process_subframe_( | ||
1982 | encoder, | ||
1983 | min_partition_order, | ||
1984 | max_partition_order, | ||
1985 | precompute_partition_sums, | ||
1986 | &frame_header, | ||
1987 | encoder->private_->subframe_bps[channel], | ||
1988 | encoder->private_->integer_signal[channel], | ||
1989 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
1990 | encoder->private_->real_signal[channel], | ||
1991 | #endif | ||
1992 | encoder->private_->subframe_workspace_ptr[channel], | ||
1993 | encoder->private_->partitioned_rice_contents_workspace_ptr[channel], | ||
1994 | encoder->private_->residual_workspace[channel], | ||
1995 | encoder->private_->best_subframe+channel, | ||
1996 | encoder->private_->best_subframe_bits+channel | ||
1997 | ) | ||
1998 | ) | ||
1999 | return false; | ||
2000 | } | ||
2001 | } | ||
2002 | |||
2003 | /* | ||
2004 | * Now do mid and side channels if requested | ||
2005 | */ | ||
2006 | if(do_mid_side) { | ||
2007 | FLAC__ASSERT(encoder->protected_->channels == 2); | ||
2008 | |||
2009 | for(channel = 0; channel < 2; channel++) { | ||
2010 | if(! | ||
2011 | process_subframe_( | ||
2012 | encoder, | ||
2013 | min_partition_order, | ||
2014 | max_partition_order, | ||
2015 | precompute_partition_sums, | ||
2016 | &frame_header, | ||
2017 | encoder->private_->subframe_bps_mid_side[channel], | ||
2018 | encoder->private_->integer_signal_mid_side[channel], | ||
2019 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2020 | encoder->private_->real_signal_mid_side[channel], | ||
2021 | #endif | ||
2022 | encoder->private_->subframe_workspace_ptr_mid_side[channel], | ||
2023 | encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel], | ||
2024 | encoder->private_->residual_workspace_mid_side[channel], | ||
2025 | encoder->private_->best_subframe_mid_side+channel, | ||
2026 | encoder->private_->best_subframe_bits_mid_side+channel | ||
2027 | ) | ||
2028 | ) | ||
2029 | return false; | ||
2030 | } | ||
2031 | } | ||
2032 | |||
2033 | /* | ||
2034 | * Compose the frame bitbuffer | ||
2035 | */ | ||
2036 | if(do_mid_side) { | ||
2037 | unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */ | ||
2038 | FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */ | ||
2039 | FLAC__ChannelAssignment channel_assignment; | ||
2040 | |||
2041 | FLAC__ASSERT(encoder->protected_->channels == 2); | ||
2042 | |||
2043 | if(encoder->protected_->loose_mid_side_stereo && encoder->private_->loose_mid_side_stereo_frame_count > 0) { | ||
2044 | channel_assignment = (encoder->private_->last_channel_assignment == FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE); | ||
2045 | } | ||
2046 | else { | ||
2047 | unsigned bits[4]; /* WATCHOUT - indexed by FLAC__ChannelAssignment */ | ||
2048 | unsigned min_bits; | ||
2049 | FLAC__ChannelAssignment ca; | ||
2050 | |||
2051 | FLAC__ASSERT(do_independent && do_mid_side); | ||
2052 | |||
2053 | /* We have to figure out which channel assignent results in the smallest frame */ | ||
2054 | bits[FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits [1]; | ||
2055 | bits[FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ] = encoder->private_->best_subframe_bits [0] + encoder->private_->best_subframe_bits_mid_side[1]; | ||
2056 | bits[FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = encoder->private_->best_subframe_bits [1] + encoder->private_->best_subframe_bits_mid_side[1]; | ||
2057 | bits[FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ] = encoder->private_->best_subframe_bits_mid_side[0] + encoder->private_->best_subframe_bits_mid_side[1]; | ||
2058 | |||
2059 | for(channel_assignment = (FLAC__ChannelAssignment)0, min_bits = bits[0], ca = (FLAC__ChannelAssignment)1; (int)ca <= 3; ca = (FLAC__ChannelAssignment)((int)ca + 1)) { | ||
2060 | if(bits[ca] < min_bits) { | ||
2061 | min_bits = bits[ca]; | ||
2062 | channel_assignment = ca; | ||
2063 | } | ||
2064 | } | ||
2065 | } | ||
2066 | |||
2067 | frame_header.channel_assignment = channel_assignment; | ||
2068 | |||
2069 | if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) { | ||
2070 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
2071 | return false; | ||
2072 | } | ||
2073 | |||
2074 | switch(channel_assignment) { | ||
2075 | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | ||
2076 | left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]]; | ||
2077 | right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]]; | ||
2078 | break; | ||
2079 | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | ||
2080 | left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]]; | ||
2081 | right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; | ||
2082 | break; | ||
2083 | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | ||
2084 | left_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; | ||
2085 | right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]]; | ||
2086 | break; | ||
2087 | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | ||
2088 | left_subframe = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]]; | ||
2089 | right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]]; | ||
2090 | break; | ||
2091 | default: | ||
2092 | FLAC__ASSERT(0); | ||
2093 | } | ||
2094 | |||
2095 | switch(channel_assignment) { | ||
2096 | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | ||
2097 | left_bps = encoder->private_->subframe_bps [0]; | ||
2098 | right_bps = encoder->private_->subframe_bps [1]; | ||
2099 | break; | ||
2100 | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | ||
2101 | left_bps = encoder->private_->subframe_bps [0]; | ||
2102 | right_bps = encoder->private_->subframe_bps_mid_side[1]; | ||
2103 | break; | ||
2104 | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | ||
2105 | left_bps = encoder->private_->subframe_bps_mid_side[1]; | ||
2106 | right_bps = encoder->private_->subframe_bps [1]; | ||
2107 | break; | ||
2108 | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | ||
2109 | left_bps = encoder->private_->subframe_bps_mid_side[0]; | ||
2110 | right_bps = encoder->private_->subframe_bps_mid_side[1]; | ||
2111 | break; | ||
2112 | default: | ||
2113 | FLAC__ASSERT(0); | ||
2114 | } | ||
2115 | |||
2116 | /* note that encoder_add_subframe_ sets the state for us in case of an error */ | ||
2117 | if(!add_subframe_(encoder, &frame_header, left_bps , left_subframe , encoder->private_->frame)) | ||
2118 | return false; | ||
2119 | if(!add_subframe_(encoder, &frame_header, right_bps, right_subframe, encoder->private_->frame)) | ||
2120 | return false; | ||
2121 | } | ||
2122 | else { | ||
2123 | if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) { | ||
2124 | encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; | ||
2125 | return false; | ||
2126 | } | ||
2127 | |||
2128 | for(channel = 0; channel < encoder->protected_->channels; channel++) { | ||
2129 | if(!add_subframe_(encoder, &frame_header, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) { | ||
2130 | /* the above function sets the state for us in case of an error */ | ||
2131 | return false; | ||
2132 | } | ||
2133 | } | ||
2134 | } | ||
2135 | |||
2136 | if(encoder->protected_->loose_mid_side_stereo) { | ||
2137 | encoder->private_->loose_mid_side_stereo_frame_count++; | ||
2138 | if(encoder->private_->loose_mid_side_stereo_frame_count >= encoder->private_->loose_mid_side_stereo_frames) | ||
2139 | encoder->private_->loose_mid_side_stereo_frame_count = 0; | ||
2140 | } | ||
2141 | |||
2142 | encoder->private_->last_channel_assignment = frame_header.channel_assignment; | ||
2143 | |||
2144 | return true; | ||
2145 | } | ||
2146 | |||
2147 | FLAC__bool process_subframe_( | ||
2148 | FLAC__StreamEncoder *encoder, | ||
2149 | unsigned min_partition_order, | ||
2150 | unsigned max_partition_order, | ||
2151 | FLAC__bool precompute_partition_sums, | ||
2152 | const FLAC__FrameHeader *frame_header, | ||
2153 | unsigned subframe_bps, | ||
2154 | const FLAC__int32 integer_signal[], | ||
2155 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2156 | const FLAC__real real_signal[], | ||
2157 | #endif | ||
2158 | FLAC__Subframe *subframe[2], | ||
2159 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], | ||
2160 | FLAC__int32 *residual[2], | ||
2161 | unsigned *best_subframe, | ||
2162 | unsigned *best_bits | ||
2163 | ) | ||
2164 | { | ||
2165 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2166 | FLAC__float fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; | ||
2167 | #else | ||
2168 | FLAC__fixedpoint fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; | ||
2169 | #endif | ||
2170 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2171 | FLAC__double lpc_residual_bits_per_sample; | ||
2172 | FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */ | ||
2173 | FLAC__double lpc_error[FLAC__MAX_LPC_ORDER]; | ||
2174 | unsigned min_lpc_order, max_lpc_order, lpc_order; | ||
2175 | unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; | ||
2176 | #endif | ||
2177 | unsigned min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; | ||
2178 | unsigned rice_parameter; | ||
2179 | unsigned _candidate_bits, _best_bits; | ||
2180 | unsigned _best_subframe; | ||
2181 | |||
2182 | /* verbatim subframe is the baseline against which we measure other compressed subframes */ | ||
2183 | _best_subframe = 0; | ||
2184 | if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) | ||
2185 | _best_bits = UINT_MAX; | ||
2186 | else | ||
2187 | _best_bits = evaluate_verbatim_subframe_(integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); | ||
2188 | |||
2189 | if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) { | ||
2190 | unsigned signal_is_constant = false; | ||
2191 | guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); | ||
2192 | /* check for constant subframe */ | ||
2193 | if( | ||
2194 | !encoder->private_->disable_constant_subframes && | ||
2195 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2196 | fixed_residual_bits_per_sample[1] == 0.0 | ||
2197 | #else | ||
2198 | fixed_residual_bits_per_sample[1] == FLAC__FP_ZERO | ||
2199 | #endif | ||
2200 | ) { | ||
2201 | /* the above means it's possible all samples are the same value; now double-check it: */ | ||
2202 | unsigned i; | ||
2203 | signal_is_constant = true; | ||
2204 | for(i = 1; i < frame_header->blocksize; i++) { | ||
2205 | if(integer_signal[0] != integer_signal[i]) { | ||
2206 | signal_is_constant = false; | ||
2207 | break; | ||
2208 | } | ||
2209 | } | ||
2210 | } | ||
2211 | if(signal_is_constant) { | ||
2212 | _candidate_bits = evaluate_constant_subframe_(integer_signal[0], subframe_bps, subframe[!_best_subframe]); | ||
2213 | if(_candidate_bits < _best_bits) { | ||
2214 | _best_subframe = !_best_subframe; | ||
2215 | _best_bits = _candidate_bits; | ||
2216 | } | ||
2217 | } | ||
2218 | else { | ||
2219 | if(!encoder->private_->disable_fixed_subframes || (encoder->protected_->max_lpc_order == 0 && _best_bits == UINT_MAX)) { | ||
2220 | /* encode fixed */ | ||
2221 | if(encoder->protected_->do_exhaustive_model_search) { | ||
2222 | min_fixed_order = 0; | ||
2223 | max_fixed_order = FLAC__MAX_FIXED_ORDER; | ||
2224 | } | ||
2225 | else { | ||
2226 | min_fixed_order = max_fixed_order = guess_fixed_order; | ||
2227 | } | ||
2228 | for(fixed_order = min_fixed_order; fixed_order <= max_fixed_order; fixed_order++) { | ||
2229 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2230 | if(fixed_residual_bits_per_sample[fixed_order] >= (FLAC__float)subframe_bps) | ||
2231 | continue; /* don't even try */ | ||
2232 | rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (unsigned)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */ | ||
2233 | #else | ||
2234 | if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps) | ||
2235 | continue; /* don't even try */ | ||
2236 | rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (unsigned)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ | ||
2237 | #endif | ||
2238 | #ifndef FLAC__SYMMETRIC_RICE | ||
2239 | rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ | ||
2240 | #endif | ||
2241 | if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2242 | #ifdef DEBUG_VERBOSE | ||
2243 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
2244 | #endif | ||
2245 | rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
2246 | } | ||
2247 | _candidate_bits = | ||
2248 | evaluate_fixed_subframe_( | ||
2249 | encoder, | ||
2250 | integer_signal, | ||
2251 | residual[!_best_subframe], | ||
2252 | encoder->private_->abs_residual, | ||
2253 | encoder->private_->abs_residual_partition_sums, | ||
2254 | encoder->private_->raw_bits_per_partition, | ||
2255 | frame_header->blocksize, | ||
2256 | subframe_bps, | ||
2257 | fixed_order, | ||
2258 | rice_parameter, | ||
2259 | min_partition_order, | ||
2260 | max_partition_order, | ||
2261 | precompute_partition_sums, | ||
2262 | encoder->protected_->do_escape_coding, | ||
2263 | encoder->protected_->rice_parameter_search_dist, | ||
2264 | subframe[!_best_subframe], | ||
2265 | partitioned_rice_contents[!_best_subframe] | ||
2266 | ); | ||
2267 | if(_candidate_bits < _best_bits) { | ||
2268 | _best_subframe = !_best_subframe; | ||
2269 | _best_bits = _candidate_bits; | ||
2270 | } | ||
2271 | } | ||
2272 | } | ||
2273 | |||
2274 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2275 | /* encode lpc */ | ||
2276 | if(encoder->protected_->max_lpc_order > 0) { | ||
2277 | if(encoder->protected_->max_lpc_order >= frame_header->blocksize) | ||
2278 | max_lpc_order = frame_header->blocksize-1; | ||
2279 | else | ||
2280 | max_lpc_order = encoder->protected_->max_lpc_order; | ||
2281 | if(max_lpc_order > 0) { | ||
2282 | encoder->private_->local_lpc_compute_autocorrelation(real_signal, frame_header->blocksize, max_lpc_order+1, autoc); | ||
2283 | /* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */ | ||
2284 | if(autoc[0] != 0.0) { | ||
2285 | FLAC__lpc_compute_lp_coefficients(autoc, max_lpc_order, encoder->private_->lp_coeff, lpc_error); | ||
2286 | if(encoder->protected_->do_exhaustive_model_search) { | ||
2287 | min_lpc_order = 1; | ||
2288 | } | ||
2289 | else { | ||
2290 | unsigned guess_lpc_order = FLAC__lpc_compute_best_order(lpc_error, max_lpc_order, frame_header->blocksize, subframe_bps); | ||
2291 | min_lpc_order = max_lpc_order = guess_lpc_order; | ||
2292 | } | ||
2293 | for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) { | ||
2294 | lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order); | ||
2295 | if(lpc_residual_bits_per_sample >= (FLAC__double)subframe_bps) | ||
2296 | continue; /* don't even try */ | ||
2297 | rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */ | ||
2298 | #ifndef FLAC__SYMMETRIC_RICE | ||
2299 | rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */ | ||
2300 | #endif | ||
2301 | if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2302 | #ifdef DEBUG_VERBOSE | ||
2303 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
2304 | #endif | ||
2305 | rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
2306 | } | ||
2307 | if(encoder->protected_->do_qlp_coeff_prec_search) { | ||
2308 | min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; | ||
2309 | /* ensure a 32-bit datapath throughout for 16bps or less */ | ||
2310 | if(subframe_bps <= 16) | ||
2311 | max_qlp_coeff_precision = min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); | ||
2312 | else | ||
2313 | max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; | ||
2314 | } | ||
2315 | else { | ||
2316 | min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision; | ||
2317 | } | ||
2318 | for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { | ||
2319 | _candidate_bits = | ||
2320 | evaluate_lpc_subframe_( | ||
2321 | encoder, | ||
2322 | integer_signal, | ||
2323 | residual[!_best_subframe], | ||
2324 | encoder->private_->abs_residual, | ||
2325 | encoder->private_->abs_residual_partition_sums, | ||
2326 | encoder->private_->raw_bits_per_partition, | ||
2327 | encoder->private_->lp_coeff[lpc_order-1], | ||
2328 | frame_header->blocksize, | ||
2329 | subframe_bps, | ||
2330 | lpc_order, | ||
2331 | qlp_coeff_precision, | ||
2332 | rice_parameter, | ||
2333 | min_partition_order, | ||
2334 | max_partition_order, | ||
2335 | precompute_partition_sums, | ||
2336 | encoder->protected_->do_escape_coding, | ||
2337 | encoder->protected_->rice_parameter_search_dist, | ||
2338 | subframe[!_best_subframe], | ||
2339 | partitioned_rice_contents[!_best_subframe] | ||
2340 | ); | ||
2341 | if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ | ||
2342 | if(_candidate_bits < _best_bits) { | ||
2343 | _best_subframe = !_best_subframe; | ||
2344 | _best_bits = _candidate_bits; | ||
2345 | } | ||
2346 | } | ||
2347 | } | ||
2348 | } | ||
2349 | } | ||
2350 | } | ||
2351 | } | ||
2352 | #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | ||
2353 | } | ||
2354 | } | ||
2355 | |||
2356 | /* under rare circumstances this can happen when all but lpc subframe types are disabled: */ | ||
2357 | if(_best_bits == UINT_MAX) { | ||
2358 | FLAC__ASSERT(_best_subframe == 0); | ||
2359 | _best_bits = evaluate_verbatim_subframe_(integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); | ||
2360 | } | ||
2361 | |||
2362 | *best_subframe = _best_subframe; | ||
2363 | *best_bits = _best_bits; | ||
2364 | |||
2365 | return true; | ||
2366 | } | ||
2367 | |||
2368 | FLAC__bool add_subframe_( | ||
2369 | FLAC__StreamEncoder *encoder, | ||
2370 | const FLAC__FrameHeader *frame_header, | ||
2371 | unsigned subframe_bps, | ||
2372 | const FLAC__Subframe *subframe, | ||
2373 | FLAC__BitBuffer *frame | ||
2374 | ) | ||
2375 | { | ||
2376 | switch(subframe->type) { | ||
2377 | case FLAC__SUBFRAME_TYPE_CONSTANT: | ||
2378 | if(!FLAC__subframe_add_constant(&(subframe->data.constant), subframe_bps, subframe->wasted_bits, frame)) { | ||
2379 | encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING; | ||
2380 | return false; | ||
2381 | } | ||
2382 | break; | ||
2383 | case FLAC__SUBFRAME_TYPE_FIXED: | ||
2384 | if(!FLAC__subframe_add_fixed(&(subframe->data.fixed), frame_header->blocksize - subframe->data.fixed.order, subframe_bps, subframe->wasted_bits, frame)) { | ||
2385 | encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING; | ||
2386 | return false; | ||
2387 | } | ||
2388 | break; | ||
2389 | case FLAC__SUBFRAME_TYPE_LPC: | ||
2390 | if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), frame_header->blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) { | ||
2391 | encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING; | ||
2392 | return false; | ||
2393 | } | ||
2394 | break; | ||
2395 | case FLAC__SUBFRAME_TYPE_VERBATIM: | ||
2396 | if(!FLAC__subframe_add_verbatim(&(subframe->data.verbatim), frame_header->blocksize, subframe_bps, subframe->wasted_bits, frame)) { | ||
2397 | encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING; | ||
2398 | return false; | ||
2399 | } | ||
2400 | break; | ||
2401 | default: | ||
2402 | FLAC__ASSERT(0); | ||
2403 | } | ||
2404 | |||
2405 | return true; | ||
2406 | } | ||
2407 | |||
2408 | unsigned evaluate_constant_subframe_( | ||
2409 | const FLAC__int32 signal, | ||
2410 | unsigned subframe_bps, | ||
2411 | FLAC__Subframe *subframe | ||
2412 | ) | ||
2413 | { | ||
2414 | subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT; | ||
2415 | subframe->data.constant.value = signal; | ||
2416 | |||
2417 | return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe_bps; | ||
2418 | } | ||
2419 | |||
2420 | unsigned evaluate_fixed_subframe_( | ||
2421 | FLAC__StreamEncoder *encoder, | ||
2422 | const FLAC__int32 signal[], | ||
2423 | FLAC__int32 residual[], | ||
2424 | FLAC__uint32 abs_residual[], | ||
2425 | FLAC__uint64 abs_residual_partition_sums[], | ||
2426 | unsigned raw_bits_per_partition[], | ||
2427 | unsigned blocksize, | ||
2428 | unsigned subframe_bps, | ||
2429 | unsigned order, | ||
2430 | unsigned rice_parameter, | ||
2431 | unsigned min_partition_order, | ||
2432 | unsigned max_partition_order, | ||
2433 | FLAC__bool precompute_partition_sums, | ||
2434 | FLAC__bool do_escape_coding, | ||
2435 | unsigned rice_parameter_search_dist, | ||
2436 | FLAC__Subframe *subframe, | ||
2437 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents | ||
2438 | ) | ||
2439 | { | ||
2440 | unsigned i, residual_bits; | ||
2441 | const unsigned residual_samples = blocksize - order; | ||
2442 | |||
2443 | FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual); | ||
2444 | |||
2445 | subframe->type = FLAC__SUBFRAME_TYPE_FIXED; | ||
2446 | |||
2447 | subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; | ||
2448 | subframe->data.fixed.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; | ||
2449 | subframe->data.fixed.residual = residual; | ||
2450 | |||
2451 | residual_bits = | ||
2452 | find_best_partition_order_( | ||
2453 | encoder->private_, | ||
2454 | residual, | ||
2455 | abs_residual, | ||
2456 | abs_residual_partition_sums, | ||
2457 | raw_bits_per_partition, | ||
2458 | residual_samples, | ||
2459 | order, | ||
2460 | rice_parameter, | ||
2461 | min_partition_order, | ||
2462 | max_partition_order, | ||
2463 | precompute_partition_sums, | ||
2464 | do_escape_coding, | ||
2465 | rice_parameter_search_dist, | ||
2466 | &subframe->data.fixed.entropy_coding_method.data.partitioned_rice | ||
2467 | ); | ||
2468 | |||
2469 | subframe->data.fixed.order = order; | ||
2470 | for(i = 0; i < order; i++) | ||
2471 | subframe->data.fixed.warmup[i] = signal[i]; | ||
2472 | |||
2473 | return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (order * subframe_bps) + residual_bits; | ||
2474 | } | ||
2475 | |||
2476 | #ifndef FLAC__INTEGER_ONLY_LIBRARY | ||
2477 | unsigned evaluate_lpc_subframe_( | ||
2478 | FLAC__StreamEncoder *encoder, | ||
2479 | const FLAC__int32 signal[], | ||
2480 | FLAC__int32 residual[], | ||
2481 | FLAC__uint32 abs_residual[], | ||
2482 | FLAC__uint64 abs_residual_partition_sums[], | ||
2483 | unsigned raw_bits_per_partition[], | ||
2484 | const FLAC__real lp_coeff[], | ||
2485 | unsigned blocksize, | ||
2486 | unsigned subframe_bps, | ||
2487 | unsigned order, | ||
2488 | unsigned qlp_coeff_precision, | ||
2489 | unsigned rice_parameter, | ||
2490 | unsigned min_partition_order, | ||
2491 | unsigned max_partition_order, | ||
2492 | FLAC__bool precompute_partition_sums, | ||
2493 | FLAC__bool do_escape_coding, | ||
2494 | unsigned rice_parameter_search_dist, | ||
2495 | FLAC__Subframe *subframe, | ||
2496 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents | ||
2497 | ) | ||
2498 | { | ||
2499 | FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; | ||
2500 | unsigned i, residual_bits; | ||
2501 | int quantization, ret; | ||
2502 | const unsigned residual_samples = blocksize - order; | ||
2503 | |||
2504 | /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */ | ||
2505 | if(subframe_bps <= 16) { | ||
2506 | FLAC__ASSERT(order > 0); | ||
2507 | FLAC__ASSERT(order <= FLAC__MAX_LPC_ORDER); | ||
2508 | qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order)); | ||
2509 | } | ||
2510 | |||
2511 | ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization); | ||
2512 | if(ret != 0) | ||
2513 | return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */ | ||
2514 | |||
2515 | if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) | ||
2516 | if(subframe_bps <= 16 && qlp_coeff_precision <= 16) | ||
2517 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); | ||
2518 | else | ||
2519 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual); | ||
2520 | else | ||
2521 | encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); | ||
2522 | |||
2523 | subframe->type = FLAC__SUBFRAME_TYPE_LPC; | ||
2524 | |||
2525 | subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; | ||
2526 | subframe->data.lpc.entropy_coding_method.data.partitioned_rice.contents = partitioned_rice_contents; | ||
2527 | subframe->data.lpc.residual = residual; | ||
2528 | |||
2529 | residual_bits = | ||
2530 | find_best_partition_order_( | ||
2531 | encoder->private_, | ||
2532 | residual, | ||
2533 | abs_residual, | ||
2534 | abs_residual_partition_sums, | ||
2535 | raw_bits_per_partition, | ||
2536 | residual_samples, | ||
2537 | order, | ||
2538 | rice_parameter, | ||
2539 | min_partition_order, | ||
2540 | max_partition_order, | ||
2541 | precompute_partition_sums, | ||
2542 | do_escape_coding, | ||
2543 | rice_parameter_search_dist, | ||
2544 | &subframe->data.fixed.entropy_coding_method.data.partitioned_rice | ||
2545 | ); | ||
2546 | |||
2547 | subframe->data.lpc.order = order; | ||
2548 | subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision; | ||
2549 | subframe->data.lpc.quantization_level = quantization; | ||
2550 | memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER); | ||
2551 | for(i = 0; i < order; i++) | ||
2552 | subframe->data.lpc.warmup[i] = signal[i]; | ||
2553 | |||
2554 | return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits; | ||
2555 | } | ||
2556 | #endif | ||
2557 | |||
2558 | unsigned evaluate_verbatim_subframe_( | ||
2559 | const FLAC__int32 signal[], | ||
2560 | unsigned blocksize, | ||
2561 | unsigned subframe_bps, | ||
2562 | FLAC__Subframe *subframe | ||
2563 | ) | ||
2564 | { | ||
2565 | subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; | ||
2566 | |||
2567 | subframe->data.verbatim.data = signal; | ||
2568 | |||
2569 | return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (blocksize * subframe_bps); | ||
2570 | } | ||
2571 | |||
2572 | unsigned find_best_partition_order_( | ||
2573 | FLAC__StreamEncoderPrivate *private_, | ||
2574 | const FLAC__int32 residual[], | ||
2575 | FLAC__uint32 abs_residual[], | ||
2576 | FLAC__uint64 abs_residual_partition_sums[], | ||
2577 | unsigned raw_bits_per_partition[], | ||
2578 | unsigned residual_samples, | ||
2579 | unsigned predictor_order, | ||
2580 | unsigned rice_parameter, | ||
2581 | unsigned min_partition_order, | ||
2582 | unsigned max_partition_order, | ||
2583 | FLAC__bool precompute_partition_sums, | ||
2584 | FLAC__bool do_escape_coding, | ||
2585 | unsigned rice_parameter_search_dist, | ||
2586 | FLAC__EntropyCodingMethod_PartitionedRice *best_partitioned_rice | ||
2587 | ) | ||
2588 | { | ||
2589 | FLAC__int32 r; | ||
2590 | unsigned residual_bits, best_residual_bits = 0; | ||
2591 | unsigned residual_sample; | ||
2592 | unsigned best_parameters_index = 0; | ||
2593 | const unsigned blocksize = residual_samples + predictor_order; | ||
2594 | |||
2595 | /* compute abs(residual) for use later */ | ||
2596 | for(residual_sample = 0; residual_sample < residual_samples; residual_sample++) { | ||
2597 | r = residual[residual_sample]; | ||
2598 | abs_residual[residual_sample] = (FLAC__uint32)(r<0? -r : r); | ||
2599 | } | ||
2600 | |||
2601 | max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); | ||
2602 | min_partition_order = min(min_partition_order, max_partition_order); | ||
2603 | |||
2604 | if(precompute_partition_sums) { | ||
2605 | int partition_order; | ||
2606 | unsigned sum; | ||
2607 | |||
2608 | precompute_partition_info_sums_(abs_residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order); | ||
2609 | |||
2610 | if(do_escape_coding) | ||
2611 | precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); | ||
2612 | |||
2613 | for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) { | ||
2614 | #ifdef DONT_ESTIMATE_RICE_BITS | ||
2615 | if(! | ||
2616 | set_partitioned_rice_with_precompute_( | ||
2617 | residual, | ||
2618 | abs_residual_partition_sums+sum, | ||
2619 | raw_bits_per_partition+sum, | ||
2620 | residual_samples, | ||
2621 | predictor_order, | ||
2622 | rice_parameter, | ||
2623 | rice_parameter_search_dist, | ||
2624 | (unsigned)partition_order, | ||
2625 | do_escape_coding, | ||
2626 | &private_->partitioned_rice_contents_extra[!best_parameters_index], | ||
2627 | &residual_bits | ||
2628 | ) | ||
2629 | ) | ||
2630 | #else | ||
2631 | if(! | ||
2632 | set_partitioned_rice_with_precompute_( | ||
2633 | abs_residual, | ||
2634 | abs_residual_partition_sums+sum, | ||
2635 | raw_bits_per_partition+sum, | ||
2636 | residual_samples, | ||
2637 | predictor_order, | ||
2638 | rice_parameter, | ||
2639 | rice_parameter_search_dist, | ||
2640 | (unsigned)partition_order, | ||
2641 | do_escape_coding, | ||
2642 | &private_->partitioned_rice_contents_extra[!best_parameters_index], | ||
2643 | &residual_bits | ||
2644 | ) | ||
2645 | ) | ||
2646 | #endif | ||
2647 | { | ||
2648 | FLAC__ASSERT(best_residual_bits != 0); | ||
2649 | break; | ||
2650 | } | ||
2651 | sum += 1u << partition_order; | ||
2652 | if(best_residual_bits == 0 || residual_bits < best_residual_bits) { | ||
2653 | best_residual_bits = residual_bits; | ||
2654 | best_parameters_index = !best_parameters_index; | ||
2655 | best_partitioned_rice->order = partition_order; | ||
2656 | } | ||
2657 | } | ||
2658 | } | ||
2659 | else { | ||
2660 | unsigned partition_order; | ||
2661 | for(partition_order = min_partition_order; partition_order <= max_partition_order; partition_order++) { | ||
2662 | #ifdef DONT_ESTIMATE_RICE_BITS | ||
2663 | if(! | ||
2664 | set_partitioned_rice_( | ||
2665 | abs_residual, | ||
2666 | residual, | ||
2667 | residual_samples, | ||
2668 | predictor_order, | ||
2669 | rice_parameter, | ||
2670 | rice_parameter_search_dist, | ||
2671 | partition_order, | ||
2672 | &private_->partitioned_rice_contents_extra[!best_parameters_index], | ||
2673 | &residual_bits | ||
2674 | ) | ||
2675 | ) | ||
2676 | #else | ||
2677 | if(! | ||
2678 | set_partitioned_rice_( | ||
2679 | abs_residual, | ||
2680 | residual_samples, | ||
2681 | predictor_order, | ||
2682 | rice_parameter, | ||
2683 | rice_parameter_search_dist, | ||
2684 | partition_order, | ||
2685 | &private_->partitioned_rice_contents_extra[!best_parameters_index], | ||
2686 | &residual_bits | ||
2687 | ) | ||
2688 | ) | ||
2689 | #endif | ||
2690 | { | ||
2691 | FLAC__ASSERT(best_residual_bits != 0); | ||
2692 | break; | ||
2693 | } | ||
2694 | if(best_residual_bits == 0 || residual_bits < best_residual_bits) { | ||
2695 | best_residual_bits = residual_bits; | ||
2696 | best_parameters_index = !best_parameters_index; | ||
2697 | best_partitioned_rice->order = partition_order; | ||
2698 | } | ||
2699 | } | ||
2700 | } | ||
2701 | |||
2702 | /* | ||
2703 | * We are allowed to de-const the pointer based on our special knowledge; | ||
2704 | * it is const to the outside world. | ||
2705 | */ | ||
2706 | { | ||
2707 | FLAC__EntropyCodingMethod_PartitionedRiceContents* best_partitioned_rice_contents = (FLAC__EntropyCodingMethod_PartitionedRiceContents*)best_partitioned_rice->contents; | ||
2708 | FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(best_partitioned_rice_contents, max(6, best_partitioned_rice->order)); | ||
2709 | memcpy(best_partitioned_rice_contents->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); | ||
2710 | memcpy(best_partitioned_rice_contents->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(unsigned)*(1<<(best_partitioned_rice->order))); | ||
2711 | } | ||
2712 | |||
2713 | return best_residual_bits; | ||
2714 | } | ||
2715 | |||
2716 | void precompute_partition_info_sums_( | ||
2717 | const FLAC__uint32 abs_residual[], | ||
2718 | FLAC__uint64 abs_residual_partition_sums[], | ||
2719 | unsigned residual_samples, | ||
2720 | unsigned predictor_order, | ||
2721 | unsigned min_partition_order, | ||
2722 | unsigned max_partition_order | ||
2723 | ) | ||
2724 | { | ||
2725 | int partition_order; | ||
2726 | unsigned from_partition, to_partition = 0; | ||
2727 | const unsigned blocksize = residual_samples + predictor_order; | ||
2728 | |||
2729 | /* first do max_partition_order */ | ||
2730 | for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) { | ||
2731 | FLAC__uint64 abs_residual_partition_sum; | ||
2732 | FLAC__uint32 abs_r; | ||
2733 | unsigned partition, partition_sample, partition_samples, residual_sample; | ||
2734 | const unsigned partitions = 1u << partition_order; | ||
2735 | const unsigned default_partition_samples = blocksize >> partition_order; | ||
2736 | |||
2737 | FLAC__ASSERT(default_partition_samples > predictor_order); | ||
2738 | |||
2739 | for(partition = residual_sample = 0; partition < partitions; partition++) { | ||
2740 | partition_samples = default_partition_samples; | ||
2741 | if(partition == 0) | ||
2742 | partition_samples -= predictor_order; | ||
2743 | abs_residual_partition_sum = 0; | ||
2744 | for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) { | ||
2745 | abs_r = abs_residual[residual_sample]; | ||
2746 | abs_residual_partition_sum += abs_r; | ||
2747 | residual_sample++; | ||
2748 | } | ||
2749 | abs_residual_partition_sums[partition] = abs_residual_partition_sum; | ||
2750 | } | ||
2751 | to_partition = partitions; | ||
2752 | break; | ||
2753 | } | ||
2754 | |||
2755 | /* now merge partitions for lower orders */ | ||
2756 | for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) { | ||
2757 | FLAC__uint64 s; | ||
2758 | unsigned i; | ||
2759 | const unsigned partitions = 1u << partition_order; | ||
2760 | for(i = 0; i < partitions; i++) { | ||
2761 | s = abs_residual_partition_sums[from_partition]; | ||
2762 | from_partition++; | ||
2763 | abs_residual_partition_sums[to_partition] = s + abs_residual_partition_sums[from_partition]; | ||
2764 | from_partition++; | ||
2765 | to_partition++; | ||
2766 | } | ||
2767 | } | ||
2768 | } | ||
2769 | |||
2770 | void precompute_partition_info_escapes_( | ||
2771 | const FLAC__int32 residual[], | ||
2772 | unsigned raw_bits_per_partition[], | ||
2773 | unsigned residual_samples, | ||
2774 | unsigned predictor_order, | ||
2775 | unsigned min_partition_order, | ||
2776 | unsigned max_partition_order | ||
2777 | ) | ||
2778 | { | ||
2779 | int partition_order; | ||
2780 | unsigned from_partition, to_partition = 0; | ||
2781 | const unsigned blocksize = residual_samples + predictor_order; | ||
2782 | |||
2783 | /* first do max_partition_order */ | ||
2784 | for(partition_order = (int)max_partition_order; partition_order >= 0; partition_order--) { | ||
2785 | FLAC__int32 r, residual_partition_min, residual_partition_max; | ||
2786 | unsigned silog2_min, silog2_max; | ||
2787 | unsigned partition, partition_sample, partition_samples, residual_sample; | ||
2788 | const unsigned partitions = 1u << partition_order; | ||
2789 | const unsigned default_partition_samples = blocksize >> partition_order; | ||
2790 | |||
2791 | FLAC__ASSERT(default_partition_samples > predictor_order); | ||
2792 | |||
2793 | for(partition = residual_sample = 0; partition < partitions; partition++) { | ||
2794 | partition_samples = default_partition_samples; | ||
2795 | if(partition == 0) | ||
2796 | partition_samples -= predictor_order; | ||
2797 | residual_partition_min = residual_partition_max = 0; | ||
2798 | for(partition_sample = 0; partition_sample < partition_samples; partition_sample++) { | ||
2799 | r = residual[residual_sample]; | ||
2800 | if(r < residual_partition_min) | ||
2801 | residual_partition_min = r; | ||
2802 | else if(r > residual_partition_max) | ||
2803 | residual_partition_max = r; | ||
2804 | residual_sample++; | ||
2805 | } | ||
2806 | silog2_min = FLAC__bitmath_silog2(residual_partition_min); | ||
2807 | silog2_max = FLAC__bitmath_silog2(residual_partition_max); | ||
2808 | raw_bits_per_partition[partition] = max(silog2_min, silog2_max); | ||
2809 | } | ||
2810 | to_partition = partitions; | ||
2811 | break; | ||
2812 | } | ||
2813 | |||
2814 | /* now merge partitions for lower orders */ | ||
2815 | for(from_partition = 0, --partition_order; partition_order >= (int)min_partition_order; partition_order--) { | ||
2816 | unsigned m; | ||
2817 | unsigned i; | ||
2818 | const unsigned partitions = 1u << partition_order; | ||
2819 | for(i = 0; i < partitions; i++) { | ||
2820 | m = raw_bits_per_partition[from_partition]; | ||
2821 | from_partition++; | ||
2822 | raw_bits_per_partition[to_partition] = max(m, raw_bits_per_partition[from_partition]); | ||
2823 | from_partition++; | ||
2824 | to_partition++; | ||
2825 | } | ||
2826 | } | ||
2827 | } | ||
2828 | |||
2829 | #ifdef VARIABLE_RICE_BITS | ||
2830 | #undef VARIABLE_RICE_BITS | ||
2831 | #endif | ||
2832 | #ifndef DONT_ESTIMATE_RICE_BITS | ||
2833 | #define VARIABLE_RICE_BITS(value, parameter) ((value) >> (parameter)) | ||
2834 | #endif | ||
2835 | |||
2836 | #ifdef DONT_ESTIMATE_RICE_BITS | ||
2837 | FLAC__bool set_partitioned_rice_( | ||
2838 | const FLAC__uint32 abs_residual[], | ||
2839 | const FLAC__int32 residual[], | ||
2840 | const unsigned residual_samples, | ||
2841 | const unsigned predictor_order, | ||
2842 | const unsigned suggested_rice_parameter, | ||
2843 | const unsigned rice_parameter_search_dist, | ||
2844 | const unsigned partition_order, | ||
2845 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
2846 | unsigned *bits | ||
2847 | ) | ||
2848 | #else | ||
2849 | FLAC__bool set_partitioned_rice_( | ||
2850 | const FLAC__uint32 abs_residual[], | ||
2851 | const unsigned residual_samples, | ||
2852 | const unsigned predictor_order, | ||
2853 | const unsigned suggested_rice_parameter, | ||
2854 | const unsigned rice_parameter_search_dist, | ||
2855 | const unsigned partition_order, | ||
2856 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
2857 | unsigned *bits | ||
2858 | ) | ||
2859 | #endif | ||
2860 | { | ||
2861 | unsigned rice_parameter, partition_bits; | ||
2862 | #ifndef NO_RICE_SEARCH | ||
2863 | unsigned best_partition_bits; | ||
2864 | unsigned min_rice_parameter, max_rice_parameter, best_rice_parameter = 0; | ||
2865 | #endif | ||
2866 | unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; | ||
2867 | unsigned *parameters; | ||
2868 | |||
2869 | FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER); | ||
2870 | |||
2871 | FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order)); | ||
2872 | parameters = partitioned_rice_contents->parameters; | ||
2873 | |||
2874 | if(partition_order == 0) { | ||
2875 | unsigned i; | ||
2876 | |||
2877 | #ifndef NO_RICE_SEARCH | ||
2878 | if(rice_parameter_search_dist) { | ||
2879 | if(suggested_rice_parameter < rice_parameter_search_dist) | ||
2880 | min_rice_parameter = 0; | ||
2881 | else | ||
2882 | min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; | ||
2883 | max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; | ||
2884 | if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2885 | #ifdef DEBUG_VERBOSE | ||
2886 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @2\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
2887 | #endif | ||
2888 | max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
2889 | } | ||
2890 | } | ||
2891 | else | ||
2892 | min_rice_parameter = max_rice_parameter = suggested_rice_parameter; | ||
2893 | |||
2894 | best_partition_bits = 0xffffffff; | ||
2895 | for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { | ||
2896 | #endif | ||
2897 | #ifdef VARIABLE_RICE_BITS | ||
2898 | #ifdef FLAC__SYMMETRIC_RICE | ||
2899 | partition_bits = (2+rice_parameter) * residual_samples; | ||
2900 | #else | ||
2901 | const unsigned rice_parameter_estimate = rice_parameter-1; | ||
2902 | partition_bits = (1+rice_parameter) * residual_samples; | ||
2903 | #endif | ||
2904 | #else | ||
2905 | partition_bits = 0; | ||
2906 | #endif | ||
2907 | partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | ||
2908 | for(i = 0; i < residual_samples; i++) { | ||
2909 | #ifdef VARIABLE_RICE_BITS | ||
2910 | #ifdef FLAC__SYMMETRIC_RICE | ||
2911 | partition_bits += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter); | ||
2912 | #else | ||
2913 | partition_bits += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter_estimate); | ||
2914 | #endif | ||
2915 | #else | ||
2916 | partition_bits += FLAC__bitbuffer_rice_bits(residual[i], rice_parameter); /* NOTE: we will need to pass in residual[] in addition to abs_residual[] */ | ||
2917 | #endif | ||
2918 | } | ||
2919 | #ifndef NO_RICE_SEARCH | ||
2920 | if(partition_bits < best_partition_bits) { | ||
2921 | best_rice_parameter = rice_parameter; | ||
2922 | best_partition_bits = partition_bits; | ||
2923 | } | ||
2924 | } | ||
2925 | #endif | ||
2926 | parameters[0] = best_rice_parameter; | ||
2927 | bits_ += best_partition_bits; | ||
2928 | } | ||
2929 | else { | ||
2930 | unsigned partition, residual_sample, save_residual_sample, partition_sample; | ||
2931 | unsigned partition_samples; | ||
2932 | FLAC__uint64 mean, k; | ||
2933 | const unsigned partitions = 1u << partition_order; | ||
2934 | for(partition = residual_sample = 0; partition < partitions; partition++) { | ||
2935 | partition_samples = (residual_samples+predictor_order) >> partition_order; | ||
2936 | if(partition == 0) { | ||
2937 | if(partition_samples <= predictor_order) | ||
2938 | return false; | ||
2939 | else | ||
2940 | partition_samples -= predictor_order; | ||
2941 | } | ||
2942 | mean = 0; | ||
2943 | save_residual_sample = residual_sample; | ||
2944 | for(partition_sample = 0; partition_sample < partition_samples; residual_sample++, partition_sample++) | ||
2945 | mean += abs_residual[residual_sample]; | ||
2946 | residual_sample = save_residual_sample; | ||
2947 | #ifdef FLAC__SYMMETRIC_RICE | ||
2948 | mean += partition_samples >> 1; /* for rounding effect */ | ||
2949 | mean /= partition_samples; | ||
2950 | |||
2951 | /* calc rice_parameter = floor(log2(mean)) */ | ||
2952 | rice_parameter = 0; | ||
2953 | mean>>=1; | ||
2954 | while(mean) { | ||
2955 | rice_parameter++; | ||
2956 | mean >>= 1; | ||
2957 | } | ||
2958 | #else | ||
2959 | /* we are basically calculating the size in bits of the | ||
2960 | * average residual magnitude in the partition: | ||
2961 | * rice_parameter = floor(log2(mean/partition_samples)) | ||
2962 | * 'mean' is not a good name for the variable, it is | ||
2963 | * actually the sum of magnitudes of all residual values | ||
2964 | * in the partition, so the actual mean is | ||
2965 | * mean/partition_samples | ||
2966 | */ | ||
2967 | for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) | ||
2968 | ; | ||
2969 | #endif | ||
2970 | if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2971 | #ifdef DEBUG_VERBOSE | ||
2972 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @3\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
2973 | #endif | ||
2974 | rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
2975 | } | ||
2976 | |||
2977 | #ifndef NO_RICE_SEARCH | ||
2978 | if(rice_parameter_search_dist) { | ||
2979 | if(rice_parameter < rice_parameter_search_dist) | ||
2980 | min_rice_parameter = 0; | ||
2981 | else | ||
2982 | min_rice_parameter = rice_parameter - rice_parameter_search_dist; | ||
2983 | max_rice_parameter = rice_parameter + rice_parameter_search_dist; | ||
2984 | if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
2985 | #ifdef DEBUG_VERBOSE | ||
2986 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @4\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
2987 | #endif | ||
2988 | max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
2989 | } | ||
2990 | } | ||
2991 | else | ||
2992 | min_rice_parameter = max_rice_parameter = rice_parameter; | ||
2993 | |||
2994 | best_partition_bits = 0xffffffff; | ||
2995 | for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { | ||
2996 | #endif | ||
2997 | #ifdef VARIABLE_RICE_BITS | ||
2998 | #ifdef FLAC__SYMMETRIC_RICE | ||
2999 | partition_bits = (2+rice_parameter) * partition_samples; | ||
3000 | #else | ||
3001 | const unsigned rice_parameter_estimate = rice_parameter-1; | ||
3002 | partition_bits = (1+rice_parameter) * partition_samples; | ||
3003 | #endif | ||
3004 | #else | ||
3005 | partition_bits = 0; | ||
3006 | #endif | ||
3007 | partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | ||
3008 | save_residual_sample = residual_sample; | ||
3009 | for(partition_sample = 0; partition_sample < partition_samples; residual_sample++, partition_sample++) { | ||
3010 | #ifdef VARIABLE_RICE_BITS | ||
3011 | #ifdef FLAC__SYMMETRIC_RICE | ||
3012 | partition_bits += VARIABLE_RICE_BITS(abs_residual[residual_sample], rice_parameter); | ||
3013 | #else | ||
3014 | partition_bits += VARIABLE_RICE_BITS(abs_residual[residual_sample], rice_parameter_estimate); | ||
3015 | #endif | ||
3016 | #else | ||
3017 | partition_bits += FLAC__bitbuffer_rice_bits(residual[residual_sample], rice_parameter); /* NOTE: we will need to pass in residual[] in addition to abs_residual[] */ | ||
3018 | #endif | ||
3019 | } | ||
3020 | #ifndef NO_RICE_SEARCH | ||
3021 | if(rice_parameter != max_rice_parameter) | ||
3022 | residual_sample = save_residual_sample; | ||
3023 | if(partition_bits < best_partition_bits) { | ||
3024 | best_rice_parameter = rice_parameter; | ||
3025 | best_partition_bits = partition_bits; | ||
3026 | } | ||
3027 | } | ||
3028 | #endif | ||
3029 | parameters[partition] = best_rice_parameter; | ||
3030 | bits_ += best_partition_bits; | ||
3031 | } | ||
3032 | } | ||
3033 | |||
3034 | *bits = bits_; | ||
3035 | return true; | ||
3036 | } | ||
3037 | |||
3038 | #ifdef DONT_ESTIMATE_RICE_BITS | ||
3039 | FLAC__bool set_partitioned_rice_with_precompute_( | ||
3040 | const FLAC__int32 residual[], | ||
3041 | const FLAC__uint64 abs_residual_partition_sums[], | ||
3042 | const unsigned raw_bits_per_partition[], | ||
3043 | const unsigned residual_samples, | ||
3044 | const unsigned predictor_order, | ||
3045 | const unsigned suggested_rice_parameter, | ||
3046 | const unsigned rice_parameter_search_dist, | ||
3047 | const unsigned partition_order, | ||
3048 | const FLAC__bool search_for_escapes, | ||
3049 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
3050 | unsigned *bits | ||
3051 | ) | ||
3052 | #else | ||
3053 | FLAC__bool set_partitioned_rice_with_precompute_( | ||
3054 | const FLAC__uint32 abs_residual[], | ||
3055 | const FLAC__uint64 abs_residual_partition_sums[], | ||
3056 | const unsigned raw_bits_per_partition[], | ||
3057 | const unsigned residual_samples, | ||
3058 | const unsigned predictor_order, | ||
3059 | const unsigned suggested_rice_parameter, | ||
3060 | const unsigned rice_parameter_search_dist, | ||
3061 | const unsigned partition_order, | ||
3062 | const FLAC__bool search_for_escapes, | ||
3063 | FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, | ||
3064 | unsigned *bits | ||
3065 | ) | ||
3066 | #endif | ||
3067 | { | ||
3068 | unsigned rice_parameter, partition_bits; | ||
3069 | #ifndef NO_RICE_SEARCH | ||
3070 | unsigned best_partition_bits; | ||
3071 | unsigned min_rice_parameter, max_rice_parameter, best_rice_parameter = 0; | ||
3072 | #endif | ||
3073 | unsigned flat_bits; | ||
3074 | unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; | ||
3075 | unsigned *parameters, *raw_bits; | ||
3076 | |||
3077 | FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER); | ||
3078 | |||
3079 | FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order)); | ||
3080 | parameters = partitioned_rice_contents->parameters; | ||
3081 | raw_bits = partitioned_rice_contents->raw_bits; | ||
3082 | |||
3083 | if(partition_order == 0) { | ||
3084 | unsigned i; | ||
3085 | |||
3086 | #ifndef NO_RICE_SEARCH | ||
3087 | if(rice_parameter_search_dist) { | ||
3088 | if(suggested_rice_parameter < rice_parameter_search_dist) | ||
3089 | min_rice_parameter = 0; | ||
3090 | else | ||
3091 | min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; | ||
3092 | max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; | ||
3093 | if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
3094 | #ifdef DEBUG_VERBOSE | ||
3095 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
3096 | #endif | ||
3097 | max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
3098 | } | ||
3099 | } | ||
3100 | else | ||
3101 | min_rice_parameter = max_rice_parameter = suggested_rice_parameter; | ||
3102 | |||
3103 | best_partition_bits = 0xffffffff; | ||
3104 | for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { | ||
3105 | #endif | ||
3106 | #ifdef VARIABLE_RICE_BITS | ||
3107 | #ifdef FLAC__SYMMETRIC_RICE | ||
3108 | partition_bits = (2+rice_parameter) * residual_samples; | ||
3109 | #else | ||
3110 | const unsigned rice_parameter_estimate = rice_parameter-1; | ||
3111 | partition_bits = (1+rice_parameter) * residual_samples; | ||
3112 | #endif | ||
3113 | #else | ||
3114 | partition_bits = 0; | ||
3115 | #endif | ||
3116 | partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | ||
3117 | for(i = 0; i < residual_samples; i++) { | ||
3118 | #ifdef VARIABLE_RICE_BITS | ||
3119 | #ifdef FLAC__SYMMETRIC_RICE | ||
3120 | partition_bits += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter); | ||
3121 | #else | ||
3122 | partition_bits += VARIABLE_RICE_BITS(abs_residual[i], rice_parameter_estimate); | ||
3123 | #endif | ||
3124 | #else | ||
3125 | partition_bits += FLAC__bitbuffer_rice_bits(residual[i], rice_parameter); /* NOTE: we will need to pass in residual[] instead of abs_residual[] */ | ||
3126 | #endif | ||
3127 | } | ||
3128 | #ifndef NO_RICE_SEARCH | ||
3129 | if(partition_bits < best_partition_bits) { | ||
3130 | best_rice_parameter = rice_parameter; | ||
3131 | best_partition_bits = partition_bits; | ||
3132 | } | ||
3133 | } | ||
3134 | #endif | ||
3135 | if(search_for_escapes) { | ||
3136 | flat_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; | ||
3137 | if(flat_bits <= best_partition_bits) { | ||
3138 | raw_bits[0] = raw_bits_per_partition[0]; | ||
3139 | best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; | ||
3140 | best_partition_bits = flat_bits; | ||
3141 | } | ||
3142 | } | ||
3143 | parameters[0] = best_rice_parameter; | ||
3144 | bits_ += best_partition_bits; | ||
3145 | } | ||
3146 | else { | ||
3147 | unsigned partition, residual_sample, save_residual_sample, partition_sample; | ||
3148 | unsigned partition_samples; | ||
3149 | FLAC__uint64 mean, k; | ||
3150 | const unsigned partitions = 1u << partition_order; | ||
3151 | for(partition = residual_sample = 0; partition < partitions; partition++) { | ||
3152 | partition_samples = (residual_samples+predictor_order) >> partition_order; | ||
3153 | if(partition == 0) { | ||
3154 | if(partition_samples <= predictor_order) | ||
3155 | return false; | ||
3156 | else | ||
3157 | partition_samples -= predictor_order; | ||
3158 | } | ||
3159 | mean = abs_residual_partition_sums[partition]; | ||
3160 | #ifdef FLAC__SYMMETRIC_RICE | ||
3161 | mean += partition_samples >> 1; /* for rounding effect */ | ||
3162 | mean /= partition_samples; | ||
3163 | |||
3164 | /* calc rice_parameter = floor(log2(mean)) */ | ||
3165 | rice_parameter = 0; | ||
3166 | mean>>=1; | ||
3167 | while(mean) { | ||
3168 | rice_parameter++; | ||
3169 | mean >>= 1; | ||
3170 | } | ||
3171 | #else | ||
3172 | /* we are basically calculating the size in bits of the | ||
3173 | * average residual magnitude in the partition: | ||
3174 | * rice_parameter = floor(log2(mean/partition_samples)) | ||
3175 | * 'mean' is not a good name for the variable, it is | ||
3176 | * actually the sum of magnitudes of all residual values | ||
3177 | * in the partition, so the actual mean is | ||
3178 | * mean/partition_samples | ||
3179 | */ | ||
3180 | for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) | ||
3181 | ; | ||
3182 | #endif | ||
3183 | if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
3184 | #ifdef DEBUG_VERBOSE | ||
3185 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
3186 | #endif | ||
3187 | rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
3188 | } | ||
3189 | |||
3190 | #ifndef NO_RICE_SEARCH | ||
3191 | if(rice_parameter_search_dist) { | ||
3192 | if(rice_parameter < rice_parameter_search_dist) | ||
3193 | min_rice_parameter = 0; | ||
3194 | else | ||
3195 | min_rice_parameter = rice_parameter - rice_parameter_search_dist; | ||
3196 | max_rice_parameter = rice_parameter + rice_parameter_search_dist; | ||
3197 | if(max_rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
3198 | #ifdef DEBUG_VERBOSE | ||
3199 | fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1); | ||
3200 | #endif | ||
3201 | max_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; | ||
3202 | } | ||
3203 | } | ||
3204 | else | ||
3205 | min_rice_parameter = max_rice_parameter = rice_parameter; | ||
3206 | |||
3207 | best_partition_bits = 0xffffffff; | ||
3208 | for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { | ||
3209 | #endif | ||
3210 | #ifdef VARIABLE_RICE_BITS | ||
3211 | #ifdef FLAC__SYMMETRIC_RICE | ||
3212 | partition_bits = (2+rice_parameter) * partition_samples; | ||
3213 | #else | ||
3214 | const unsigned rice_parameter_estimate = rice_parameter-1; | ||
3215 | partition_bits = (1+rice_parameter) * partition_samples; | ||
3216 | #endif | ||
3217 | #else | ||
3218 | partition_bits = 0; | ||
3219 | #endif | ||
3220 | partition_bits += FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | ||
3221 | save_residual_sample = residual_sample; | ||
3222 | for(partition_sample = 0; partition_sample < partition_samples; residual_sample++, partition_sample++) { | ||
3223 | #ifdef VARIABLE_RICE_BITS | ||
3224 | #ifdef FLAC__SYMMETRIC_RICE | ||
3225 | partition_bits += VARIABLE_RICE_BITS(abs_residual[residual_sample], rice_parameter); | ||
3226 | #else | ||
3227 | partition_bits += VARIABLE_RICE_BITS(abs_residual[residual_sample], rice_parameter_estimate); | ||
3228 | #endif | ||
3229 | #else | ||
3230 | partition_bits += FLAC__bitbuffer_rice_bits(residual[residual_sample], rice_parameter); /* NOTE: we will need to pass in residual[] instead of abs_residual[] */ | ||
3231 | #endif | ||
3232 | } | ||
3233 | #ifndef NO_RICE_SEARCH | ||
3234 | if(rice_parameter != max_rice_parameter) | ||
3235 | residual_sample = save_residual_sample; | ||
3236 | if(partition_bits < best_partition_bits) { | ||
3237 | best_rice_parameter = rice_parameter; | ||
3238 | best_partition_bits = partition_bits; | ||
3239 | } | ||
3240 | } | ||
3241 | #endif | ||
3242 | if(search_for_escapes) { | ||
3243 | flat_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; | ||
3244 | if(flat_bits <= best_partition_bits) { | ||
3245 | raw_bits[partition] = raw_bits_per_partition[partition]; | ||
3246 | best_rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; | ||
3247 | best_partition_bits = flat_bits; | ||
3248 | } | ||
3249 | } | ||
3250 | parameters[partition] = best_rice_parameter; | ||
3251 | bits_ += best_partition_bits; | ||
3252 | } | ||
3253 | } | ||
3254 | |||
3255 | *bits = bits_; | ||
3256 | return true; | ||
3257 | } | ||
3258 | |||
3259 | unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples) | ||
3260 | { | ||
3261 | unsigned i, shift; | ||
3262 | FLAC__int32 x = 0; | ||
3263 | |||
3264 | for(i = 0; i < samples && !(x&1); i++) | ||
3265 | x |= signal[i]; | ||
3266 | |||
3267 | if(x == 0) { | ||
3268 | shift = 0; | ||
3269 | } | ||
3270 | else { | ||
3271 | for(shift = 0; !(x&1); shift++) | ||
3272 | x >>= 1; | ||
3273 | } | ||
3274 | |||
3275 | if(shift > 0) { | ||
3276 | for(i = 0; i < samples; i++) | ||
3277 | signal[i] >>= shift; | ||
3278 | } | ||
3279 | |||
3280 | return shift; | ||
3281 | } | ||
3282 | |||
3283 | void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], unsigned input_offset, unsigned channels, unsigned wide_samples) | ||
3284 | { | ||
3285 | unsigned channel; | ||
3286 | |||
3287 | for(channel = 0; channel < channels; channel++) | ||
3288 | memcpy(&fifo->data[channel][fifo->tail], &input[channel][input_offset], sizeof(FLAC__int32) * wide_samples); | ||
3289 | |||
3290 | fifo->tail += wide_samples; | ||
3291 | |||
3292 | FLAC__ASSERT(fifo->tail <= fifo->size); | ||
3293 | } | ||
3294 | |||
3295 | void append_to_verify_fifo_interleaved_(verify_input_fifo *fifo, const FLAC__int32 input[], unsigned input_offset, unsigned channels, unsigned wide_samples) | ||
3296 | { | ||
3297 | unsigned channel; | ||
3298 | unsigned sample, wide_sample; | ||
3299 | unsigned tail = fifo->tail; | ||
3300 | |||
3301 | sample = input_offset * channels; | ||
3302 | for(wide_sample = 0; wide_sample < wide_samples; wide_sample++) { | ||
3303 | for(channel = 0; channel < channels; channel++) | ||
3304 | fifo->data[channel][tail] = input[sample++]; | ||
3305 | tail++; | ||
3306 | } | ||
3307 | fifo->tail = tail; | ||
3308 | |||
3309 | FLAC__ASSERT(fifo->tail <= fifo->size); | ||
3310 | } | ||
3311 | |||
3312 | FLAC__StreamDecoderReadStatus verify_read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) | ||
3313 | { | ||
3314 | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; | ||
3315 | const unsigned encoded_bytes = encoder->private_->verify.output.bytes; | ||
3316 | (void)decoder; | ||
3317 | |||
3318 | if(encoder->private_->verify.needs_magic_hack) { | ||
3319 | FLAC__ASSERT(*bytes >= FLAC__STREAM_SYNC_LENGTH); | ||
3320 | *bytes = FLAC__STREAM_SYNC_LENGTH; | ||
3321 | memcpy(buffer, FLAC__STREAM_SYNC_STRING, *bytes); | ||
3322 | encoder->private_->verify.needs_magic_hack = false; | ||
3323 | } | ||
3324 | else { | ||
3325 | if(encoded_bytes == 0) { | ||
3326 | /* | ||
3327 | * If we get here, a FIFO underflow has occurred, | ||
3328 | * which means there is a bug somewhere. | ||
3329 | */ | ||
3330 | FLAC__ASSERT(0); | ||
3331 | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; | ||
3332 | } | ||
3333 | else if(encoded_bytes < *bytes) | ||
3334 | *bytes = encoded_bytes; | ||
3335 | memcpy(buffer, encoder->private_->verify.output.data, *bytes); | ||
3336 | encoder->private_->verify.output.data += *bytes; | ||
3337 | encoder->private_->verify.output.bytes -= *bytes; | ||
3338 | } | ||
3339 | |||
3340 | return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; | ||
3341 | } | ||
3342 | |||
3343 | FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) | ||
3344 | { | ||
3345 | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder *)client_data; | ||
3346 | unsigned channel; | ||
3347 | const unsigned channels = FLAC__stream_decoder_get_channels(decoder); | ||
3348 | const unsigned blocksize = frame->header.blocksize; | ||
3349 | const unsigned bytes_per_block = sizeof(FLAC__int32) * blocksize; | ||
3350 | |||
3351 | for(channel = 0; channel < channels; channel++) { | ||
3352 | if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) { | ||
3353 | unsigned i, sample = 0; | ||
3354 | FLAC__int32 expect = 0, got = 0; | ||
3355 | |||
3356 | for(i = 0; i < blocksize; i++) { | ||
3357 | if(buffer[channel][i] != encoder->private_->verify.input_fifo.data[channel][i]) { | ||
3358 | sample = i; | ||
3359 | expect = (FLAC__int32)encoder->private_->verify.input_fifo.data[channel][i]; | ||
3360 | got = (FLAC__int32)buffer[channel][i]; | ||
3361 | break; | ||
3362 | } | ||
3363 | } | ||
3364 | FLAC__ASSERT(i < blocksize); | ||
3365 | FLAC__ASSERT(frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); | ||
3366 | encoder->private_->verify.error_stats.absolute_sample = frame->header.number.sample_number + sample; | ||
3367 | encoder->private_->verify.error_stats.frame_number = (unsigned)(frame->header.number.sample_number / blocksize); | ||
3368 | encoder->private_->verify.error_stats.channel = channel; | ||
3369 | encoder->private_->verify.error_stats.sample = sample; | ||
3370 | encoder->private_->verify.error_stats.expected = expect; | ||
3371 | encoder->private_->verify.error_stats.got = got; | ||
3372 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA; | ||
3373 | return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; | ||
3374 | } | ||
3375 | } | ||
3376 | /* dequeue the frame from the fifo */ | ||
3377 | for(channel = 0; channel < channels; channel++) { | ||
3378 | memmove(&encoder->private_->verify.input_fifo.data[channel][0], &encoder->private_->verify.input_fifo.data[channel][blocksize], encoder->private_->verify.input_fifo.tail - blocksize); | ||
3379 | } | ||
3380 | encoder->private_->verify.input_fifo.tail -= blocksize; | ||
3381 | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | ||
3382 | } | ||
3383 | |||
3384 | void verify_metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) | ||
3385 | { | ||
3386 | (void)decoder, (void)metadata, (void)client_data; | ||
3387 | } | ||
3388 | |||
3389 | void verify_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) | ||
3390 | { | ||
3391 | FLAC__StreamEncoder *encoder = (FLAC__StreamEncoder*)client_data; | ||
3392 | (void)decoder, (void)status; | ||
3393 | encoder->protected_->state = FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR; | ||
3394 | } | ||
diff --git a/apps/codecs/libFLAC/stream_encoder_framing.c b/apps/codecs/libFLAC/stream_encoder_framing.c new file mode 100644 index 0000000000..36bf952456 --- /dev/null +++ b/apps/codecs/libFLAC/stream_encoder_framing.c | |||
@@ -0,0 +1,499 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004,2005 Josh Coalson | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * - Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * - Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * | ||
15 | * - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived from | ||
17 | * this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <string.h> /* for strlen() */ | ||
34 | #include "private/stream_encoder_framing.h" | ||
35 | #include "private/crc.h" | ||
36 | #include "FLAC/assert.h" | ||
37 | |||
38 | #ifdef max | ||
39 | #undef max | ||
40 | #endif | ||
41 | #define max(x,y) ((x)>(y)?(x):(y)) | ||
42 | |||
43 | static FLAC__bool add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method); | ||
44 | static FLAC__bool add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order); | ||
45 | |||
46 | FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitBuffer *bb) | ||
47 | { | ||
48 | unsigned i, j; | ||
49 | const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING); | ||
50 | |||
51 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN)) | ||
52 | return false; | ||
53 | |||
54 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN)) | ||
55 | return false; | ||
56 | |||
57 | /* | ||
58 | * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string | ||
59 | */ | ||
60 | i = metadata->length; | ||
61 | if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | ||
62 | FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry); | ||
63 | i -= metadata->data.vorbis_comment.vendor_string.length; | ||
64 | i += vendor_string_length; | ||
65 | } | ||
66 | FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); | ||
67 | if(!FLAC__bitbuffer_write_raw_uint32(bb, i, FLAC__STREAM_METADATA_LENGTH_LEN)) | ||
68 | return false; | ||
69 | |||
70 | switch(metadata->type) { | ||
71 | case FLAC__METADATA_TYPE_STREAMINFO: | ||
72 | FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)); | ||
73 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)) | ||
74 | return false; | ||
75 | FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)); | ||
76 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) | ||
77 | return false; | ||
78 | FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)); | ||
79 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) | ||
80 | return false; | ||
81 | FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)); | ||
82 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) | ||
83 | return false; | ||
84 | FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate)); | ||
85 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) | ||
86 | return false; | ||
87 | FLAC__ASSERT(metadata->data.stream_info.channels > 0); | ||
88 | FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)); | ||
89 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) | ||
90 | return false; | ||
91 | FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0); | ||
92 | FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | ||
93 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) | ||
94 | return false; | ||
95 | if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) | ||
96 | return false; | ||
97 | if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.stream_info.md5sum, 16)) | ||
98 | return false; | ||
99 | break; | ||
100 | case FLAC__METADATA_TYPE_PADDING: | ||
101 | if(!FLAC__bitbuffer_write_zeroes(bb, metadata->length * 8)) | ||
102 | return false; | ||
103 | break; | ||
104 | case FLAC__METADATA_TYPE_APPLICATION: | ||
105 | if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) | ||
106 | return false; | ||
107 | if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))) | ||
108 | return false; | ||
109 | break; | ||
110 | case FLAC__METADATA_TYPE_SEEKTABLE: | ||
111 | for(i = 0; i < metadata->data.seek_table.num_points; i++) { | ||
112 | if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) | ||
113 | return false; | ||
114 | if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) | ||
115 | return false; | ||
116 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) | ||
117 | return false; | ||
118 | } | ||
119 | break; | ||
120 | case FLAC__METADATA_TYPE_VORBIS_COMMENT: | ||
121 | if(!FLAC__bitbuffer_write_raw_uint32_little_endian(bb, vendor_string_length)) | ||
122 | return false; | ||
123 | if(!FLAC__bitbuffer_write_byte_block(bb, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) | ||
124 | return false; | ||
125 | if(!FLAC__bitbuffer_write_raw_uint32_little_endian(bb, metadata->data.vorbis_comment.num_comments)) | ||
126 | return false; | ||
127 | for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { | ||
128 | if(!FLAC__bitbuffer_write_raw_uint32_little_endian(bb, metadata->data.vorbis_comment.comments[i].length)) | ||
129 | return false; | ||
130 | if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length)) | ||
131 | return false; | ||
132 | } | ||
133 | break; | ||
134 | case FLAC__METADATA_TYPE_CUESHEET: | ||
135 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | ||
136 | if(!FLAC__bitbuffer_write_byte_block(bb, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) | ||
137 | return false; | ||
138 | if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) | ||
139 | return false; | ||
140 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) | ||
141 | return false; | ||
142 | if(!FLAC__bitbuffer_write_zeroes(bb, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) | ||
143 | return false; | ||
144 | if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) | ||
145 | return false; | ||
146 | for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) { | ||
147 | const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i; | ||
148 | |||
149 | if(!FLAC__bitbuffer_write_raw_uint64(bb, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) | ||
150 | return false; | ||
151 | if(!FLAC__bitbuffer_write_raw_uint32(bb, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) | ||
152 | return false; | ||
153 | FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | ||
154 | if(!FLAC__bitbuffer_write_byte_block(bb, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) | ||
155 | return false; | ||
156 | if(!FLAC__bitbuffer_write_raw_uint32(bb, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) | ||
157 | return false; | ||
158 | if(!FLAC__bitbuffer_write_raw_uint32(bb, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) | ||
159 | return false; | ||
160 | if(!FLAC__bitbuffer_write_zeroes(bb, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) | ||
161 | return false; | ||
162 | if(!FLAC__bitbuffer_write_raw_uint32(bb, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) | ||
163 | return false; | ||
164 | for(j = 0; j < track->num_indices; j++) { | ||
165 | const FLAC__StreamMetadata_CueSheet_Index *index = track->indices + j; | ||
166 | |||
167 | if(!FLAC__bitbuffer_write_raw_uint64(bb, index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | ||
168 | return false; | ||
169 | if(!FLAC__bitbuffer_write_raw_uint32(bb, index->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | ||
170 | return false; | ||
171 | if(!FLAC__bitbuffer_write_zeroes(bb, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | ||
172 | return false; | ||
173 | } | ||
174 | } | ||
175 | break; | ||
176 | default: | ||
177 | if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.unknown.data, metadata->length)) | ||
178 | return false; | ||
179 | break; | ||
180 | } | ||
181 | |||
182 | FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb)); | ||
183 | return true; | ||
184 | } | ||
185 | |||
186 | FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool streamable_subset, FLAC__BitBuffer *bb) | ||
187 | { | ||
188 | unsigned u, blocksize_hint, sample_rate_hint; | ||
189 | |||
190 | FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb)); | ||
191 | |||
192 | if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN)) | ||
193 | return false; | ||
194 | |||
195 | if(!FLAC__bitbuffer_write_raw_uint32(bb, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) | ||
196 | return false; | ||
197 | |||
198 | FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); | ||
199 | /* when this assertion holds true, any legal blocksize can be expressed in the frame header */ | ||
200 | FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u); | ||
201 | blocksize_hint = 0; | ||
202 | switch(header->blocksize) { | ||
203 | case 192: u = 1; break; | ||
204 | case 576: u = 2; break; | ||
205 | case 1152: u = 3; break; | ||
206 | case 2304: u = 4; break; | ||
207 | case 4608: u = 5; break; | ||
208 | case 256: u = 8; break; | ||
209 | case 512: u = 9; break; | ||
210 | case 1024: u = 10; break; | ||
211 | case 2048: u = 11; break; | ||
212 | case 4096: u = 12; break; | ||
213 | case 8192: u = 13; break; | ||
214 | case 16384: u = 14; break; | ||
215 | case 32768: u = 15; break; | ||
216 | default: | ||
217 | if(header->blocksize <= 0x100) | ||
218 | blocksize_hint = u = 6; | ||
219 | else if(header->blocksize <= 0x10000) | ||
220 | blocksize_hint = u = 7; | ||
221 | else { | ||
222 | FLAC__ASSERT(0); | ||
223 | return false; | ||
224 | } | ||
225 | break; | ||
226 | } | ||
227 | if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) | ||
228 | return false; | ||
229 | |||
230 | FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); | ||
231 | sample_rate_hint = 0; | ||
232 | switch(header->sample_rate) { | ||
233 | case 8000: u = 4; break; | ||
234 | case 16000: u = 5; break; | ||
235 | case 22050: u = 6; break; | ||
236 | case 24000: u = 7; break; | ||
237 | case 32000: u = 8; break; | ||
238 | case 44100: u = 9; break; | ||
239 | case 48000: u = 10; break; | ||
240 | case 96000: u = 11; break; | ||
241 | default: | ||
242 | if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) | ||
243 | sample_rate_hint = u = 12; | ||
244 | else if(header->sample_rate % 10 == 0) | ||
245 | sample_rate_hint = u = 14; | ||
246 | else if(header->sample_rate <= 0xffff) | ||
247 | sample_rate_hint = u = 13; | ||
248 | else if(streamable_subset) { | ||
249 | FLAC__ASSERT(0); | ||
250 | return false; | ||
251 | } | ||
252 | else | ||
253 | u = 0; | ||
254 | break; | ||
255 | } | ||
256 | if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN)) | ||
257 | return false; | ||
258 | |||
259 | FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS); | ||
260 | switch(header->channel_assignment) { | ||
261 | case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | ||
262 | u = header->channels - 1; | ||
263 | break; | ||
264 | case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | ||
265 | FLAC__ASSERT(header->channels == 2); | ||
266 | u = 8; | ||
267 | break; | ||
268 | case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | ||
269 | FLAC__ASSERT(header->channels == 2); | ||
270 | u = 9; | ||
271 | break; | ||
272 | case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | ||
273 | FLAC__ASSERT(header->channels == 2); | ||
274 | u = 10; | ||
275 | break; | ||
276 | default: | ||
277 | FLAC__ASSERT(0); | ||
278 | } | ||
279 | if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN)) | ||
280 | return false; | ||
281 | |||
282 | FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | ||
283 | switch(header->bits_per_sample) { | ||
284 | case 8 : u = 1; break; | ||
285 | case 12: u = 2; break; | ||
286 | case 16: u = 4; break; | ||
287 | case 20: u = 5; break; | ||
288 | case 24: u = 6; break; | ||
289 | default: u = 0; break; | ||
290 | } | ||
291 | if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN)) | ||
292 | return false; | ||
293 | |||
294 | if(!FLAC__bitbuffer_write_raw_uint32(bb, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) | ||
295 | return false; | ||
296 | |||
297 | FLAC__ASSERT(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER); | ||
298 | if(!FLAC__bitbuffer_write_utf8_uint32(bb, header->number.frame_number)) | ||
299 | return false; | ||
300 | |||
301 | if(blocksize_hint) | ||
302 | if(!FLAC__bitbuffer_write_raw_uint32(bb, header->blocksize-1, (blocksize_hint==6)? 8:16)) | ||
303 | return false; | ||
304 | |||
305 | switch(sample_rate_hint) { | ||
306 | case 12: | ||
307 | if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate / 1000, 8)) | ||
308 | return false; | ||
309 | break; | ||
310 | case 13: | ||
311 | if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate, 16)) | ||
312 | return false; | ||
313 | break; | ||
314 | case 14: | ||
315 | if(!FLAC__bitbuffer_write_raw_uint32(bb, header->sample_rate / 10, 16)) | ||
316 | return false; | ||
317 | break; | ||
318 | } | ||
319 | |||
320 | /* write the CRC */ | ||
321 | if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__bitbuffer_get_write_crc8(bb), FLAC__FRAME_HEADER_CRC_LEN)) | ||
322 | return false; | ||
323 | |||
324 | return true; | ||
325 | } | ||
326 | |||
327 | FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb) | ||
328 | { | ||
329 | FLAC__bool ok; | ||
330 | |||
331 | ok = | ||
332 | FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) && | ||
333 | (wasted_bits? FLAC__bitbuffer_write_unary_unsigned(bb, wasted_bits-1) : true) && | ||
334 | FLAC__bitbuffer_write_raw_int32(bb, subframe->value, subframe_bps) | ||
335 | ; | ||
336 | |||
337 | return ok; | ||
338 | } | ||
339 | |||
340 | FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb) | ||
341 | { | ||
342 | unsigned i; | ||
343 | |||
344 | if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | ||
345 | return false; | ||
346 | if(wasted_bits) | ||
347 | if(!FLAC__bitbuffer_write_unary_unsigned(bb, wasted_bits-1)) | ||
348 | return false; | ||
349 | |||
350 | for(i = 0; i < subframe->order; i++) | ||
351 | if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->warmup[i], subframe_bps)) | ||
352 | return false; | ||
353 | |||
354 | if(!add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) | ||
355 | return false; | ||
356 | switch(subframe->entropy_coding_method.type) { | ||
357 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
358 | if(!add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) | ||
359 | return false; | ||
360 | break; | ||
361 | default: | ||
362 | FLAC__ASSERT(0); | ||
363 | } | ||
364 | |||
365 | return true; | ||
366 | } | ||
367 | |||
368 | FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb) | ||
369 | { | ||
370 | unsigned i; | ||
371 | |||
372 | if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | ||
373 | return false; | ||
374 | if(wasted_bits) | ||
375 | if(!FLAC__bitbuffer_write_unary_unsigned(bb, wasted_bits-1)) | ||
376 | return false; | ||
377 | |||
378 | for(i = 0; i < subframe->order; i++) | ||
379 | if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->warmup[i], subframe_bps)) | ||
380 | return false; | ||
381 | |||
382 | if(!FLAC__bitbuffer_write_raw_uint32(bb, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) | ||
383 | return false; | ||
384 | if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) | ||
385 | return false; | ||
386 | for(i = 0; i < subframe->order; i++) | ||
387 | if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->qlp_coeff[i], subframe->qlp_coeff_precision)) | ||
388 | return false; | ||
389 | |||
390 | if(!add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) | ||
391 | return false; | ||
392 | switch(subframe->entropy_coding_method.type) { | ||
393 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
394 | if(!add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) | ||
395 | return false; | ||
396 | break; | ||
397 | default: | ||
398 | FLAC__ASSERT(0); | ||
399 | } | ||
400 | |||
401 | return true; | ||
402 | } | ||
403 | |||
404 | FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb) | ||
405 | { | ||
406 | unsigned i; | ||
407 | const FLAC__int32 *signal = subframe->data; | ||
408 | |||
409 | if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | ||
410 | return false; | ||
411 | if(wasted_bits) | ||
412 | if(!FLAC__bitbuffer_write_unary_unsigned(bb, wasted_bits-1)) | ||
413 | return false; | ||
414 | |||
415 | for(i = 0; i < samples; i++) | ||
416 | if(!FLAC__bitbuffer_write_raw_int32(bb, signal[i], subframe_bps)) | ||
417 | return false; | ||
418 | |||
419 | return true; | ||
420 | } | ||
421 | |||
422 | FLAC__bool add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method) | ||
423 | { | ||
424 | if(!FLAC__bitbuffer_write_raw_uint32(bb, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) | ||
425 | return false; | ||
426 | switch(method->type) { | ||
427 | case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | ||
428 | if(!FLAC__bitbuffer_write_raw_uint32(bb, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) | ||
429 | return false; | ||
430 | break; | ||
431 | default: | ||
432 | FLAC__ASSERT(0); | ||
433 | } | ||
434 | return true; | ||
435 | } | ||
436 | |||
437 | FLAC__bool add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order) | ||
438 | { | ||
439 | if(partition_order == 0) { | ||
440 | unsigned i; | ||
441 | |||
442 | if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)) | ||
443 | return false; | ||
444 | if(rice_parameters[0] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
445 | for(i = 0; i < residual_samples; i++) { | ||
446 | #ifdef FLAC__SYMMETRIC_RICE | ||
447 | if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[i], rice_parameters[0])) | ||
448 | return false; | ||
449 | #else | ||
450 | if(!FLAC__bitbuffer_write_rice_signed(bb, residual[i], rice_parameters[0])) | ||
451 | return false; | ||
452 | #endif | ||
453 | } | ||
454 | } | ||
455 | else { | ||
456 | if(!FLAC__bitbuffer_write_raw_uint32(bb, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | ||
457 | return false; | ||
458 | for(i = 0; i < residual_samples; i++) { | ||
459 | if(!FLAC__bitbuffer_write_raw_int32(bb, residual[i], raw_bits[0])) | ||
460 | return false; | ||
461 | } | ||
462 | } | ||
463 | return true; | ||
464 | } | ||
465 | else { | ||
466 | unsigned i, j, k = 0, k_last = 0; | ||
467 | unsigned partition_samples; | ||
468 | const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; | ||
469 | for(i = 0; i < (1u<<partition_order); i++) { | ||
470 | if(!FLAC__bitbuffer_write_raw_uint32(bb, rice_parameters[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)) | ||
471 | return false; | ||
472 | partition_samples = default_partition_samples; | ||
473 | if(i == 0) | ||
474 | partition_samples -= predictor_order; | ||
475 | k += partition_samples; | ||
476 | if(rice_parameters[i] < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) { | ||
477 | for(j = k_last; j < k; j++) { | ||
478 | #ifdef FLAC__SYMMETRIC_RICE | ||
479 | if(!FLAC__bitbuffer_write_symmetric_rice_signed(bb, residual[j], rice_parameters[i])) | ||
480 | return false; | ||
481 | #else | ||
482 | if(!FLAC__bitbuffer_write_rice_signed(bb, residual[j], rice_parameters[i])) | ||
483 | return false; | ||
484 | #endif | ||
485 | } | ||
486 | } | ||
487 | else { | ||
488 | if(!FLAC__bitbuffer_write_raw_uint32(bb, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | ||
489 | return false; | ||
490 | for(j = k_last; j < k; j++) { | ||
491 | if(!FLAC__bitbuffer_write_raw_int32(bb, residual[j], raw_bits[i])) | ||
492 | return false; | ||
493 | } | ||
494 | } | ||
495 | k_last = k; | ||
496 | } | ||
497 | return true; | ||
498 | } | ||
499 | } | ||