diff options
Diffstat (limited to 'apps/codecs/libFLAC/include/FLAC/format.h')
-rw-r--r-- | apps/codecs/libFLAC/include/FLAC/format.h | 861 |
1 files changed, 861 insertions, 0 deletions
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 | ||