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