xref: /aosp_15_r20/external/flac/src/libFLAC/format.c (revision 600f14f40d737144c998e2ec7a483122d3776fbc)
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000-2009  Josh Coalson
3  * Copyright (C) 2011-2023  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 " 20230623";
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 > 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 	if((FLAC__uint64)(seek_table->num_points) * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN))
251 		return false;
252 
253 	for(i = 0; i < seek_table->num_points; i++) {
254 		if(got_prev) {
255 			if(
256 				seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
257 				seek_table->points[i].sample_number <= prev_sample_number
258 			)
259 				return false;
260 		}
261 		prev_sample_number = seek_table->points[i].sample_number;
262 		got_prev = true;
263 	}
264 
265 	return true;
266 }
267 
268 /* used as the sort predicate for qsort() */
seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint * l,const FLAC__StreamMetadata_SeekPoint * r)269 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
270 {
271 	/* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
272 	if(l->sample_number == r->sample_number)
273 		return 0;
274 	else if(l->sample_number < r->sample_number)
275 		return -1;
276 	else
277 		return 1;
278 }
279 
280 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable * seek_table)281 FLAC_API uint32_t FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
282 {
283 	uint32_t i, j;
284 	FLAC__bool first;
285 
286 	FLAC__ASSERT(0 != seek_table);
287 
288 	if (seek_table->num_points == 0)
289 		return 0;
290 
291 	/* sort the seekpoints */
292 	qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
293 
294 	/* uniquify the seekpoints */
295 	first = true;
296 	for(i = j = 0; i < seek_table->num_points; i++) {
297 		if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
298 			if(!first) {
299 				if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
300 					continue;
301 			}
302 		}
303 		first = false;
304 		seek_table->points[j++] = seek_table->points[i];
305 	}
306 
307 	for(i = j; i < seek_table->num_points; i++) {
308 		seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
309 		seek_table->points[i].stream_offset = 0;
310 		seek_table->points[i].frame_samples = 0;
311 	}
312 
313 	return j;
314 }
315 
316 /*
317  * also disallows non-shortest-form encodings, c.f.
318  *   http://www.unicode.org/versions/corrigendum1.html
319  * and a more clear explanation at the end of this section:
320  *   http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
321  */
utf8len_(const FLAC__byte * utf8)322 static uint32_t utf8len_(const FLAC__byte *utf8)
323 {
324 	FLAC__ASSERT(0 != utf8);
325 	if ((utf8[0] & 0x80) == 0) {
326 		return 1;
327 	}
328 	else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
329 		if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
330 			return 0;
331 		return 2;
332 	}
333 	else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
334 		if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
335 			return 0;
336 		/* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
337 		if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
338 			return 0;
339 		if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
340 			return 0;
341 		return 3;
342 	}
343 	else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
344 		if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
345 			return 0;
346 		return 4;
347 	}
348 	else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
349 		if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
350 			return 0;
351 		return 5;
352 	}
353 	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) {
354 		if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
355 			return 0;
356 		return 6;
357 	}
358 	else {
359 		return 0;
360 	}
361 }
362 
FLAC__format_vorbiscomment_entry_name_is_legal(const char * name)363 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
364 {
365 	char c;
366 	for(c = *name; c; c = *(++name))
367 		if(c < 0x20 || c == 0x3d || c > 0x7d)
368 			return false;
369 	return true;
370 }
371 
FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte * value,uint32_t length)372 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, uint32_t length)
373 {
374 	if(length == (uint32_t)(-1)) {
375 		while(*value) {
376 			uint32_t n = utf8len_(value);
377 			if(n == 0)
378 				return false;
379 			value += n;
380 		}
381 	}
382 	else {
383 		const FLAC__byte *end = value + length;
384 		while(value < end) {
385 			uint32_t n = utf8len_(value);
386 			if(n == 0)
387 				return false;
388 			value += n;
389 		}
390 		if(value != end)
391 			return false;
392 	}
393 	return true;
394 }
395 
FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte * entry,uint32_t length)396 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, uint32_t length)
397 {
398 	const FLAC__byte *s, *end;
399 
400 	for(s = entry, end = s + length; s < end && *s != '='; s++) {
401 		if(*s < 0x20 || *s > 0x7D)
402 			return false;
403 	}
404 	if(s == end)
405 		return false;
406 
407 	s++; /* skip '=' */
408 
409 	while(s < end) {
410 		uint32_t n = utf8len_(s);
411 		if(n == 0)
412 			return false;
413 		s += n;
414 	}
415 	if(s != end)
416 		return false;
417 
418 	return true;
419 }
420 
421 /* @@@@ 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)422 FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
423 {
424 	uint32_t i, j;
425 
426 	if(check_cd_da_subset) {
427 		if(cue_sheet->lead_in < 2 * 44100) {
428 			if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
429 			return false;
430 		}
431 		if(cue_sheet->lead_in % 588 != 0) {
432 			if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
433 			return false;
434 		}
435 	}
436 
437 	if(cue_sheet->num_tracks == 0) {
438 		if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
439 		return false;
440 	}
441 
442 	if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
443 		if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
444 		return false;
445 	}
446 
447 	for(i = 0; i < cue_sheet->num_tracks; i++) {
448 		if(cue_sheet->tracks[i].number == 0) {
449 			if(violation) *violation = "cue sheet may not have a track number 0";
450 			return false;
451 		}
452 
453 		if(check_cd_da_subset) {
454 			if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
455 				if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
456 				return false;
457 			}
458 		}
459 
460 		if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
461 			if(violation) {
462 				if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
463 					*violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
464 				else
465 					*violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
466 			}
467 			return false;
468 		}
469 
470 		if(i < cue_sheet->num_tracks - 1) {
471 			if(cue_sheet->tracks[i].num_indices == 0) {
472 				if(violation) *violation = "cue sheet track must have at least one index point";
473 				return false;
474 			}
475 
476 			if(cue_sheet->tracks[i].indices[0].number > 1) {
477 				if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
478 				return false;
479 			}
480 		}
481 
482 		for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
483 			if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
484 				if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
485 				return false;
486 			}
487 
488 			if(j > 0) {
489 				if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
490 					if(violation) *violation = "cue sheet track index numbers must increase by 1";
491 					return false;
492 				}
493 			}
494 		}
495 	}
496 
497 	return true;
498 }
499 
500 /* @@@@ 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)501 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
502 {
503 	char *p;
504 	FLAC__byte *b;
505 
506 	for(p = picture->mime_type; *p; p++) {
507 		if(*p < 0x20 || *p > 0x7e) {
508 			if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
509 			return false;
510 		}
511 	}
512 
513 	for(b = picture->description; *b; ) {
514 		uint32_t n = utf8len_(b);
515 		if(n == 0) {
516 			if(violation) *violation = "description string must be valid UTF-8";
517 			return false;
518 		}
519 		b += n;
520 	}
521 
522 	return true;
523 }
524 
525 /*
526  * These routines are private to libFLAC
527  */
528 #if 0 /* UNUSED */
529 uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order)
530 {
531 	return
532 		FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
533 			FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
534 			blocksize,
535 			predictor_order
536 		);
537 }
538 #endif
539 
FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize)540 uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize)
541 {
542 	uint32_t max_rice_partition_order = 0;
543 	while(!(blocksize & 1)) {
544 		max_rice_partition_order++;
545 		blocksize >>= 1;
546 	}
547 	return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
548 }
549 
FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit,uint32_t blocksize,uint32_t predictor_order)550 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)
551 {
552 	uint32_t max_rice_partition_order = limit;
553 
554 	while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
555 		max_rice_partition_order--;
556 
557 	FLAC__ASSERT(
558 		(max_rice_partition_order == 0 && blocksize >= predictor_order) ||
559 		(max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
560 	);
561 
562 	return max_rice_partition_order;
563 }
564 
FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents * object)565 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
566 {
567 	FLAC__ASSERT(0 != object);
568 
569 	object->parameters = 0;
570 	object->raw_bits = 0;
571 	object->capacity_by_order = 0;
572 }
573 
FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents * object)574 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
575 {
576 	FLAC__ASSERT(0 != object);
577 
578 	if(0 != object->parameters)
579 		free(object->parameters);
580 	if(0 != object->raw_bits)
581 		free(object->raw_bits);
582 	FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
583 }
584 
585 #if defined(_MSC_VER)
586 // silence three MSVC warnings 'result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)'
587 #pragma warning ( disable : 4334 )
588 #endif
589 
FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents * object,uint32_t max_partition_order)590 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order)
591 {
592 	FLAC__ASSERT(0 != object);
593 
594 	if(object->capacity_by_order < max_partition_order || object->parameters == NULL || object->raw_bits == NULL) {
595 		if(0 == (object->parameters = safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order))))
596 			return false;
597 		if(0 == (object->raw_bits = safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order))))
598 			return false;
599 		memset(object->raw_bits, 0, sizeof(uint32_t)*(1 << max_partition_order));
600 		object->capacity_by_order = max_partition_order;
601 	}
602 
603 	return true;
604 }
605 
606 #if defined(_MSC_VER)
607 #pragma warning ( default : 4334 )
608 #endif
609