1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2000-2009 Josh Coalson
3 * Copyright (C) 2011-2022 Xiph.Org Foundation
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
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.
15 *
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.
19 *
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.
31 */
32
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36
37 #include <stdio.h>
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"
46
47 #if (defined GIT_COMMIT_HASH && defined GIT_COMMIT_DATE)
48 # ifdef GIT_COMMIT_TAG
49 FLAC_API const char *FLAC__VERSION_STRING = GIT_COMMIT_TAG;
50 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " GIT_COMMIT_TAG " " GIT_COMMIT_DATE;
51 # else
52 FLAC_API const char *FLAC__VERSION_STRING = "git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
53 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE;
54 # endif
55 #else
56 /* PACKAGE_VERSION should come from configure */
57 FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION;
58 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20221022";
59 #endif
60
61 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
62 FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143;
63 FLAC_API const uint32_t FLAC__STREAM_SYNC_LEN = 32; /* bits */
64
65 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
66 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
67 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
68 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
69 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
70 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
71 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
72 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
73 FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
74
75 FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
76
77 FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
78 FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
79 FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
80
81 FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
82
83 FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
84 FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
85
86 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
87 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
88 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
89
90 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
91 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
92 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
93 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
94 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
95 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
96 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
97
98 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
99 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
100 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
101 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
102 FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
103
104 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
105 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
106 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
107 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
108 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
109 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
110 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
111 FLAC_API const uint32_t FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
112
113 FLAC_API const uint32_t FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
114 FLAC_API const uint32_t FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
115 FLAC_API const uint32_t FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
116
117 FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC = 0x3ffe;
118 FLAC_API const uint32_t FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
119 FLAC_API const uint32_t FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
120 FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
121 FLAC_API const uint32_t FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
122 FLAC_API const uint32_t FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
123 FLAC_API const uint32_t FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
124 FLAC_API const uint32_t FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
125 FLAC_API const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
126 FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
127
128 FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
129
130 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
131 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
132 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
133 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
134 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
135
136 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
137 FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
138
139 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
140 "PARTITIONED_RICE",
141 "PARTITIONED_RICE2"
142 };
143
144 FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
145 FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
146
147 FLAC_API const uint32_t FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
148 FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
149 FLAC_API const uint32_t FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
150
151 FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
152 FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
153 FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
154 FLAC_API const uint32_t FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
155
156 FLAC_API const char * const FLAC__SubframeTypeString[] = {
157 "CONSTANT",
158 "VERBATIM",
159 "FIXED",
160 "LPC"
161 };
162
163 FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
164 "INDEPENDENT",
165 "LEFT_SIDE",
166 "RIGHT_SIDE",
167 "MID_SIDE"
168 };
169
170 FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
171 "FRAME_NUMBER_TYPE_FRAME_NUMBER",
172 "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
173 };
174
175 FLAC_API const char * const FLAC__MetadataTypeString[] = {
176 "STREAMINFO",
177 "PADDING",
178 "APPLICATION",
179 "SEEKTABLE",
180 "VORBIS_COMMENT",
181 "CUESHEET",
182 "PICTURE"
183 };
184
185 FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
186 "Other",
187 "32x32 pixels 'file icon' (PNG only)",
188 "Other file icon",
189 "Cover (front)",
190 "Cover (back)",
191 "Leaflet page",
192 "Media (e.g. label side of CD)",
193 "Lead artist/lead performer/soloist",
194 "Artist/performer",
195 "Conductor",
196 "Band/Orchestra",
197 "Composer",
198 "Lyricist/text writer",
199 "Recording Location",
200 "During recording",
201 "During performance",
202 "Movie/video screen capture",
203 "A bright coloured fish",
204 "Illustration",
205 "Band/artist logotype",
206 "Publisher/Studio logotype"
207 };
208
FLAC__format_sample_rate_is_valid(uint32_t sample_rate)209 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate)
210 {
211 if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
212 return false;
213 }
214 else
215 return true;
216 }
217
FLAC__format_blocksize_is_subset(uint32_t blocksize,uint32_t sample_rate)218 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_t sample_rate)
219 {
220 if(blocksize > 16384)
221 return false;
222 else if(sample_rate <= 48000 && blocksize > 4608)
223 return false;
224 else
225 return true;
226 }
227
FLAC__format_sample_rate_is_subset(uint32_t sample_rate)228 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate)
229 {
230 if( // sample rate is not subset if
231 !FLAC__format_sample_rate_is_valid(sample_rate) || // sample rate is invalid or
232 sample_rate >= ((1u << 16) * 10) || // sample rate is larger then or equal to 655360 or
233 (sample_rate >= (1u << 16) && sample_rate % 10 != 0) //sample rate is >= 65536 and not divisible by 10
234 ) {
235 return false;
236 }
237 else
238 return true;
239 }
240
241 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable * seek_table)242 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
243 {
244 uint32_t i;
245 FLAC__uint64 prev_sample_number = 0;
246 FLAC__bool got_prev = false;
247
248 FLAC__ASSERT(0 != seek_table);
249
250 for(i = 0; i < seek_table->num_points; i++) {
251 if(got_prev) {
252 if(
253 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
254 seek_table->points[i].sample_number <= prev_sample_number
255 )
256 return false;
257 }
258 prev_sample_number = seek_table->points[i].sample_number;
259 got_prev = true;
260 }
261
262 return true;
263 }
264
265 /* used as the sort predicate for qsort() */
seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint * l,const FLAC__StreamMetadata_SeekPoint * r)266 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
267 {
268 /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
269 if(l->sample_number == r->sample_number)
270 return 0;
271 else if(l->sample_number < r->sample_number)
272 return -1;
273 else
274 return 1;
275 }
276
277 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable * seek_table)278 FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
279 {
280 uint32_t i, j;
281 FLAC__bool first;
282
283 FLAC__ASSERT(0 != seek_table);
284
285 if (seek_table->num_points == 0)
286 return 0;
287
288 /* sort the seekpoints */
289 qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
290
291 /* uniquify the seekpoints */
292 first = true;
293 for(i = j = 0; i < seek_table->num_points; i++) {
294 if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
295 if(!first) {
296 if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
297 continue;
298 }
299 }
300 first = false;
301 seek_table->points[j++] = seek_table->points[i];
302 }
303
304 for(i = j; i < seek_table->num_points; i++) {
305 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
306 seek_table->points[i].stream_offset = 0;
307 seek_table->points[i].frame_samples = 0;
308 }
309
310 return j;
311 }
312
313 /*
314 * also disallows non-shortest-form encodings, c.f.
315 * http://www.unicode.org/versions/corrigendum1.html
316 * and a more clear explanation at the end of this section:
317 * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
318 */
utf8len_(const FLAC__byte * utf8)319 static uint32_t utf8len_(const FLAC__byte *utf8)
320 {
321 FLAC__ASSERT(0 != utf8);
322 if ((utf8[0] & 0x80) == 0) {
323 return 1;
324 }
325 else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
326 if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
327 return 0;
328 return 2;
329 }
330 else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
331 if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
332 return 0;
333 /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
334 if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
335 return 0;
336 if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
337 return 0;
338 return 3;
339 }
340 else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
341 if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
342 return 0;
343 return 4;
344 }
345 else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
346 if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
347 return 0;
348 return 5;
349 }
350 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) {
351 if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
352 return 0;
353 return 6;
354 }
355 else {
356 return 0;
357 }
358 }
359
FLAC__format_vorbiscomment_entry_name_is_legal(const char * name)360 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
361 {
362 char c;
363 for(c = *name; c; c = *(++name))
364 if(c < 0x20 || c == 0x3d || c > 0x7d)
365 return false;
366 return true;
367 }
368
FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte * value,uint32_t length)369 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length)
370 {
371 if(length == (uint32_t)(-1)) {
372 while(*value) {
373 uint32_t n = utf8len_(value);
374 if(n == 0)
375 return false;
376 value += n;
377 }
378 }
379 else {
380 const FLAC__byte *end = value + length;
381 while(value < end) {
382 uint32_t n = utf8len_(value);
383 if(n == 0)
384 return false;
385 value += n;
386 }
387 if(value != end)
388 return false;
389 }
390 return true;
391 }
392
FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte * entry,uint32_t length)393 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length)
394 {
395 const FLAC__byte *s, *end;
396
397 for(s = entry, end = s + length; s < end && *s != '='; s++) {
398 if(*s < 0x20 || *s > 0x7D)
399 return false;
400 }
401 if(s == end)
402 return false;
403
404 s++; /* skip '=' */
405
406 while(s < end) {
407 uint32_t n = utf8len_(s);
408 if(n == 0)
409 return false;
410 s += n;
411 }
412 if(s != end)
413 return false;
414
415 return true;
416 }
417
418 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet * cue_sheet,FLAC__bool check_cd_da_subset,const char ** violation)419 FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
420 {
421 uint32_t i, j;
422
423 if(check_cd_da_subset) {
424 if(cue_sheet->lead_in < 2 * 44100) {
425 if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
426 return false;
427 }
428 if(cue_sheet->lead_in % 588 != 0) {
429 if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
430 return false;
431 }
432 }
433
434 if(cue_sheet->num_tracks == 0) {
435 if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
436 return false;
437 }
438
439 if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
440 if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
441 return false;
442 }
443
444 for(i = 0; i < cue_sheet->num_tracks; i++) {
445 if(cue_sheet->tracks[i].number == 0) {
446 if(violation) *violation = "cue sheet may not have a track number 0";
447 return false;
448 }
449
450 if(check_cd_da_subset) {
451 if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
452 if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
453 return false;
454 }
455 }
456
457 if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
458 if(violation) {
459 if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
460 *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
461 else
462 *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
463 }
464 return false;
465 }
466
467 if(i < cue_sheet->num_tracks - 1) {
468 if(cue_sheet->tracks[i].num_indices == 0) {
469 if(violation) *violation = "cue sheet track must have at least one index point";
470 return false;
471 }
472
473 if(cue_sheet->tracks[i].indices[0].number > 1) {
474 if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
475 return false;
476 }
477 }
478
479 for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
480 if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
481 if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
482 return false;
483 }
484
485 if(j > 0) {
486 if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
487 if(violation) *violation = "cue sheet track index numbers must increase by 1";
488 return false;
489 }
490 }
491 }
492 }
493
494 return true;
495 }
496
497 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture * picture,const char ** violation)498 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
499 {
500 char *p;
501 FLAC__byte *b;
502
503 for(p = picture->mime_type; *p; p++) {
504 if(*p < 0x20 || *p > 0x7e) {
505 if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
506 return false;
507 }
508 }
509
510 for(b = picture->description; *b; ) {
511 uint32_t n = utf8len_(b);
512 if(n == 0) {
513 if(violation) *violation = "description string must be valid UTF-8";
514 return false;
515 }
516 b += n;
517 }
518
519 return true;
520 }
521
522 /*
523 * These routines are private to libFLAC
524 */
525 #if 0 /* UNUSED */
526 uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order)
527 {
528 return
529 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
530 FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
531 blocksize,
532 predictor_order
533 );
534 }
535 #endif
536
FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize)537 uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize)
538 {
539 uint32_t max_rice_partition_order = 0;
540 while(!(blocksize & 1)) {
541 max_rice_partition_order++;
542 blocksize >>= 1;
543 }
544 return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
545 }
546
FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit,uint32_t blocksize,uint32_t predictor_order)547 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)
548 {
549 uint32_t max_rice_partition_order = limit;
550
551 while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
552 max_rice_partition_order--;
553
554 FLAC__ASSERT(
555 (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
556 (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
557 );
558
559 return max_rice_partition_order;
560 }
561
FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents * object)562 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
563 {
564 FLAC__ASSERT(0 != object);
565
566 object->parameters = 0;
567 object->raw_bits = 0;
568 object->capacity_by_order = 0;
569 }
570
FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents * object)571 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
572 {
573 FLAC__ASSERT(0 != object);
574
575 if(0 != object->parameters)
576 free(object->parameters);
577 if(0 != object->raw_bits)
578 free(object->raw_bits);
579 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
580 }
581
582 #if defined(_MSC_VER)
583 // silence three MSVC warnings 'result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)'
584 #pragma warning ( disable : 4334 )
585 #endif
586
FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents * object,uint32_t max_partition_order)587 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order)
588 {
589 FLAC__ASSERT(0 != object);
590
591 if(object->capacity_by_order < max_partition_order || object->parameters == NULL || object->raw_bits == NULL) {
592 if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order))))
593 return false;
594 if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order))))
595 return false;
596 memset(object->raw_bits, 0, sizeof(uint32_t)*(1 << max_partition_order));
597 object->capacity_by_order = max_partition_order;
598 }
599
600 return true;
601 }
602
603 #if defined(_MSC_VER)
604 #pragma warning ( default : 4334 )
605 #endif
606