1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000-2009 Josh Coalson
3 * Copyright (C) 2011-2016 Xiph.Org Foundation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * - Neither the name of the Xiph.org Foundation nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <stdlib.h> /* for qsort() */
39 #include <string.h> /* for memset() */
40 #include "FLAC/assert.h"
41 #include "FLAC/format.h"
42 #include "share/alloc.h"
43 #include "share/compat.h"
44 #include "private/format.h"
45 #include "private/macros.h"
47 /* PACKAGE_VERSION should come from configure */
48 FLAC_API
const char *FLAC__VERSION_STRING
= PACKAGE_VERSION
;
50 FLAC_API
const char *FLAC__VENDOR_STRING
= "reference libFLAC " PACKAGE_VERSION
" 20190804";
52 FLAC_API
const FLAC__byte FLAC__STREAM_SYNC_STRING
[4] = { 'f','L','a','C' };
53 FLAC_API
const uint32_t FLAC__STREAM_SYNC
= 0x664C6143;
54 FLAC_API
const uint32_t FLAC__STREAM_SYNC_LEN
= 32; /* bits */
56 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN
= 16; /* bits */
57 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
= 16; /* bits */
58 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN
= 24; /* bits */
59 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN
= 24; /* bits */
60 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN
= 20; /* bits */
61 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN
= 3; /* bits */
62 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
= 5; /* bits */
63 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
= 36; /* bits */
64 FLAC_API
const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN
= 128; /* bits */
66 FLAC_API
const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN
= 32; /* bits */
68 FLAC_API
const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN
= 64; /* bits */
69 FLAC_API
const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN
= 64; /* bits */
70 FLAC_API
const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN
= 16; /* bits */
72 FLAC_API
const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER
= FLAC__U64L(0xffffffffffffffff);
74 FLAC_API
const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN
= 32; /* bits */
75 FLAC_API
const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN
= 32; /* bits */
77 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN
= 64; /* bits */
78 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN
= 8; /* bits */
79 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN
= 3*8; /* bits */
81 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN
= 64; /* bits */
82 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN
= 8; /* bits */
83 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN
= 12*8; /* bits */
84 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN
= 1; /* bit */
85 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN
= 1; /* bit */
86 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN
= 6+13*8; /* bits */
87 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN
= 8; /* bits */
89 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN
= 128*8; /* bits */
90 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN
= 64; /* bits */
91 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN
= 1; /* bit */
92 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN
= 7+258*8; /* bits */
93 FLAC_API
const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
= 8; /* bits */
95 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_TYPE_LEN
= 32; /* bits */
96 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN
= 32; /* bits */
97 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN
= 32; /* bits */
98 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN
= 32; /* bits */
99 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN
= 32; /* bits */
100 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN
= 32; /* bits */
101 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_COLORS_LEN
= 32; /* bits */
102 FLAC_API
const uint32_t FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN
= 32; /* bits */
104 FLAC_API
const uint32_t FLAC__STREAM_METADATA_IS_LAST_LEN
= 1; /* bits */
105 FLAC_API
const uint32_t FLAC__STREAM_METADATA_TYPE_LEN
= 7; /* bits */
106 FLAC_API
const uint32_t FLAC__STREAM_METADATA_LENGTH_LEN
= 24; /* bits */
108 FLAC_API
const uint32_t FLAC__FRAME_HEADER_SYNC
= 0x3ffe;
109 FLAC_API
const uint32_t FLAC__FRAME_HEADER_SYNC_LEN
= 14; /* bits */
110 FLAC_API
const uint32_t FLAC__FRAME_HEADER_RESERVED_LEN
= 1; /* bits */
111 FLAC_API
const uint32_t FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN
= 1; /* bits */
112 FLAC_API
const uint32_t FLAC__FRAME_HEADER_BLOCK_SIZE_LEN
= 4; /* bits */
113 FLAC_API
const uint32_t FLAC__FRAME_HEADER_SAMPLE_RATE_LEN
= 4; /* bits */
114 FLAC_API
const uint32_t FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN
= 4; /* bits */
115 FLAC_API
const uint32_t FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN
= 3; /* bits */
116 FLAC_API
const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN
= 1; /* bits */
117 FLAC_API
const uint32_t FLAC__FRAME_HEADER_CRC_LEN
= 8; /* bits */
119 FLAC_API
const uint32_t FLAC__FRAME_FOOTER_CRC_LEN
= 16; /* bits */
121 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN
= 2; /* bits */
122 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN
= 4; /* bits */
123 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN
= 4; /* bits */
124 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN
= 5; /* bits */
125 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN
= 5; /* bits */
127 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER
= 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
128 FLAC_API
const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER
= 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
130 FLAC_API
const char * const FLAC__EntropyCodingMethodTypeString
[] = {
135 FLAC_API
const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN
= 4; /* bits */
136 FLAC_API
const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN
= 5; /* bits */
138 FLAC_API
const uint32_t FLAC__SUBFRAME_ZERO_PAD_LEN
= 1; /* bits */
139 FLAC_API
const uint32_t FLAC__SUBFRAME_TYPE_LEN
= 6; /* bits */
140 FLAC_API
const uint32_t FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN
= 1; /* bits */
142 FLAC_API
const uint32_t FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK
= 0x00;
143 FLAC_API
const uint32_t FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK
= 0x02;
144 FLAC_API
const uint32_t FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK
= 0x10;
145 FLAC_API
const uint32_t FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK
= 0x40;
147 FLAC_API
const char * const FLAC__SubframeTypeString
[] = {
154 FLAC_API
const char * const FLAC__ChannelAssignmentString
[] = {
161 FLAC_API
const char * const FLAC__FrameNumberTypeString
[] = {
162 "FRAME_NUMBER_TYPE_FRAME_NUMBER",
163 "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
166 FLAC_API
const char * const FLAC__MetadataTypeString
[] = {
176 FLAC_API
const char * const FLAC__StreamMetadata_Picture_TypeString
[] = {
178 "32x32 pixels 'file icon' (PNG only)",
183 "Media (e.g. label side of CD)",
184 "Lead artist/lead performer/soloist",
189 "Lyricist/text writer",
190 "Recording Location",
192 "During performance",
193 "Movie/video screen capture",
194 "A bright coloured fish",
196 "Band/artist logotype",
197 "Publisher/Studio logotype"
200 FLAC_API FLAC__bool
FLAC__format_sample_rate_is_valid(uint32_t sample_rate
)
202 if(sample_rate
== 0 || sample_rate
> FLAC__MAX_SAMPLE_RATE
) {
209 FLAC_API FLAC__bool
FLAC__format_blocksize_is_subset(uint32_t blocksize
, uint32_t sample_rate
)
211 if(blocksize
> 16384)
213 else if(sample_rate
<= 48000 && blocksize
> 4608)
219 FLAC_API FLAC__bool
FLAC__format_sample_rate_is_subset(uint32_t sample_rate
)
222 !FLAC__format_sample_rate_is_valid(sample_rate
) ||
224 sample_rate
>= (1u << 16) &&
225 !(sample_rate
% 1000 == 0 || sample_rate
% 10 == 0)
234 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
235 FLAC_API FLAC__bool
FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable
*seek_table
)
238 FLAC__uint64 prev_sample_number
= 0;
239 FLAC__bool got_prev
= false;
241 FLAC__ASSERT(0 != seek_table
);
243 for(i
= 0; i
< seek_table
->num_points
; i
++) {
246 seek_table
->points
[i
].sample_number
!= FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER
&&
247 seek_table
->points
[i
].sample_number
<= prev_sample_number
251 prev_sample_number
= seek_table
->points
[i
].sample_number
;
258 /* used as the sort predicate for qsort() */
259 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint
*l
, const FLAC__StreamMetadata_SeekPoint
*r
)
261 /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
262 if(l
->sample_number
== r
->sample_number
)
264 else if(l
->sample_number
< r
->sample_number
)
270 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
271 FLAC_API
uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable
*seek_table
)
276 FLAC__ASSERT(0 != seek_table
);
278 if (seek_table
->num_points
== 0)
281 /* sort the seekpoints */
282 qsort(seek_table
->points
, seek_table
->num_points
, sizeof(FLAC__StreamMetadata_SeekPoint
), (int (*)(const void *, const void *))seekpoint_compare_
);
284 /* uniquify the seekpoints */
286 for(i
= j
= 0; i
< seek_table
->num_points
; i
++) {
287 if(seek_table
->points
[i
].sample_number
!= FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER
) {
289 if(seek_table
->points
[i
].sample_number
== seek_table
->points
[j
-1].sample_number
)
294 seek_table
->points
[j
++] = seek_table
->points
[i
];
297 for(i
= j
; i
< seek_table
->num_points
; i
++) {
298 seek_table
->points
[i
].sample_number
= FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER
;
299 seek_table
->points
[i
].stream_offset
= 0;
300 seek_table
->points
[i
].frame_samples
= 0;
307 * also disallows non-shortest-form encodings, c.f.
308 * http://www.unicode.org/versions/corrigendum1.html
309 * and a more clear explanation at the end of this section:
310 * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
312 static uint32_t utf8len_(const FLAC__byte
*utf8
)
314 FLAC__ASSERT(0 != utf8
);
315 if ((utf8
[0] & 0x80) == 0) {
318 else if ((utf8
[0] & 0xE0) == 0xC0 && (utf8
[1] & 0xC0) == 0x80) {
319 if ((utf8
[0] & 0xFE) == 0xC0) /* overlong sequence check */
323 else if ((utf8
[0] & 0xF0) == 0xE0 && (utf8
[1] & 0xC0) == 0x80 && (utf8
[2] & 0xC0) == 0x80) {
324 if (utf8
[0] == 0xE0 && (utf8
[1] & 0xE0) == 0x80) /* overlong sequence check */
326 /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
327 if (utf8
[0] == 0xED && (utf8
[1] & 0xE0) == 0xA0) /* D800-DFFF */
329 if (utf8
[0] == 0xEF && utf8
[1] == 0xBF && (utf8
[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
333 else if ((utf8
[0] & 0xF8) == 0xF0 && (utf8
[1] & 0xC0) == 0x80 && (utf8
[2] & 0xC0) == 0x80 && (utf8
[3] & 0xC0) == 0x80) {
334 if (utf8
[0] == 0xF0 && (utf8
[1] & 0xF0) == 0x80) /* overlong sequence check */
338 else if ((utf8
[0] & 0xFC) == 0xF8 && (utf8
[1] & 0xC0) == 0x80 && (utf8
[2] & 0xC0) == 0x80 && (utf8
[3] & 0xC0) == 0x80 && (utf8
[4] & 0xC0) == 0x80) {
339 if (utf8
[0] == 0xF8 && (utf8
[1] & 0xF8) == 0x80) /* overlong sequence check */
343 else if ((utf8
[0] & 0xFE) == 0xFC && (utf8
[1] & 0xC0) == 0x80 && (utf8
[2] & 0xC0) == 0x80 && (utf8
[3] & 0xC0) == 0x80 && (utf8
[4] & 0xC0) == 0x80 && (utf8
[5] & 0xC0) == 0x80) {
344 if (utf8
[0] == 0xFC && (utf8
[1] & 0xFC) == 0x80) /* overlong sequence check */
353 FLAC_API FLAC__bool
FLAC__format_vorbiscomment_entry_name_is_legal(const char *name
)
356 for(c
= *name
; c
; c
= *(++name
))
357 if(c
< 0x20 || c
== 0x3d || c
> 0x7d)
362 FLAC_API FLAC__bool
FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte
*value
, uint32_t length
)
364 if(length
== (uint32_t)(-1)) {
366 uint32_t n
= utf8len_(value
);
373 const FLAC__byte
*end
= value
+ length
;
375 uint32_t n
= utf8len_(value
);
386 FLAC_API FLAC__bool
FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte
*entry
, uint32_t length
)
388 const FLAC__byte
*s
, *end
;
390 for(s
= entry
, end
= s
+ length
; s
< end
&& *s
!= '='; s
++) {
391 if(*s
< 0x20 || *s
> 0x7D)
400 uint32_t n
= utf8len_(s
);
411 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
412 FLAC_API FLAC__bool
FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet
*cue_sheet
, FLAC__bool check_cd_da_subset
, const char **violation
)
416 if(check_cd_da_subset
) {
417 if(cue_sheet
->lead_in
< 2 * 44100) {
418 if(violation
) *violation
= "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
421 if(cue_sheet
->lead_in
% 588 != 0) {
422 if(violation
) *violation
= "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
427 if(cue_sheet
->num_tracks
== 0) {
428 if(violation
) *violation
= "cue sheet must have at least one track (the lead-out)";
432 if(check_cd_da_subset
&& cue_sheet
->tracks
[cue_sheet
->num_tracks
-1].number
!= 170) {
433 if(violation
) *violation
= "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
437 for(i
= 0; i
< cue_sheet
->num_tracks
; i
++) {
438 if(cue_sheet
->tracks
[i
].number
== 0) {
439 if(violation
) *violation
= "cue sheet may not have a track number 0";
443 if(check_cd_da_subset
) {
444 if(!((cue_sheet
->tracks
[i
].number
>= 1 && cue_sheet
->tracks
[i
].number
<= 99) || cue_sheet
->tracks
[i
].number
== 170)) {
445 if(violation
) *violation
= "CD-DA cue sheet track number must be 1-99 or 170";
450 if(check_cd_da_subset
&& cue_sheet
->tracks
[i
].offset
% 588 != 0) {
452 if(i
== cue_sheet
->num_tracks
-1) /* the lead-out track... */
453 *violation
= "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
455 *violation
= "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
460 if(i
< cue_sheet
->num_tracks
- 1) {
461 if(cue_sheet
->tracks
[i
].num_indices
== 0) {
462 if(violation
) *violation
= "cue sheet track must have at least one index point";
466 if(cue_sheet
->tracks
[i
].indices
[0].number
> 1) {
467 if(violation
) *violation
= "cue sheet track's first index number must be 0 or 1";
472 for(j
= 0; j
< cue_sheet
->tracks
[i
].num_indices
; j
++) {
473 if(check_cd_da_subset
&& cue_sheet
->tracks
[i
].indices
[j
].offset
% 588 != 0) {
474 if(violation
) *violation
= "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
479 if(cue_sheet
->tracks
[i
].indices
[j
].number
!= cue_sheet
->tracks
[i
].indices
[j
-1].number
+ 1) {
480 if(violation
) *violation
= "cue sheet track index numbers must increase by 1";
490 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
491 FLAC_API FLAC__bool
FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture
*picture
, const char **violation
)
496 for(p
= picture
->mime_type
; *p
; p
++) {
497 if(*p
< 0x20 || *p
> 0x7e) {
498 if(violation
) *violation
= "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
503 for(b
= picture
->description
; *b
; ) {
504 uint32_t n
= utf8len_(b
);
506 if(violation
) *violation
= "description string must be valid UTF-8";
516 * These routines are private to libFLAC
518 uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize
, uint32_t predictor_order
)
521 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
522 FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize
),
528 uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize
)
530 uint32_t max_rice_partition_order
= 0;
531 while(!(blocksize
& 1)) {
532 max_rice_partition_order
++;
535 return flac_min(FLAC__MAX_RICE_PARTITION_ORDER
, max_rice_partition_order
);
538 uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit
, uint32_t blocksize
, uint32_t predictor_order
)
540 uint32_t max_rice_partition_order
= limit
;
542 while(max_rice_partition_order
> 0 && (blocksize
>> max_rice_partition_order
) <= predictor_order
)
543 max_rice_partition_order
--;
546 (max_rice_partition_order
== 0 && blocksize
>= predictor_order
) ||
547 (max_rice_partition_order
> 0 && blocksize
>> max_rice_partition_order
> predictor_order
)
550 return max_rice_partition_order
;
553 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents
*object
)
555 FLAC__ASSERT(0 != object
);
557 object
->parameters
= 0;
558 object
->raw_bits
= 0;
559 object
->capacity_by_order
= 0;
562 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents
*object
)
564 FLAC__ASSERT(0 != object
);
566 if(0 != object
->parameters
)
567 free(object
->parameters
);
568 if(0 != object
->raw_bits
)
569 free(object
->raw_bits
);
570 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object
);
573 FLAC__bool
FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents
*object
, uint32_t max_partition_order
)
575 FLAC__ASSERT(0 != object
);
577 FLAC__ASSERT(object
->capacity_by_order
> 0 || (0 == object
->parameters
&& 0 == object
->raw_bits
));
579 if(object
->capacity_by_order
< max_partition_order
) {
580 if(0 == (object
->parameters
= safe_realloc_(object
->parameters
, sizeof(uint32_t)*(1 << max_partition_order
))))
582 if(0 == (object
->raw_bits
= safe_realloc_(object
->raw_bits
, sizeof(uint32_t)*(1 << max_partition_order
))))
584 memset(object
->raw_bits
, 0, sizeof(uint32_t)*(1 << max_partition_order
));
585 object
->capacity_by_order
= max_partition_order
;