V2: Use a single definition of MIN and MAX in sources
[flac.git] / src / libFLAC / format.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #if HAVE_CONFIG_H
33 #  include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h> /* for qsort() */
38 #include <string.h> /* for memset() */
39 #include "FLAC/assert.h"
40 #include "FLAC/format.h"
41 #include "private/format.h"
42 #include "private/macros.h"
43
44 /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
45 #ifdef _MSC_VER
46 #define FLAC__U64L(x) x
47 #else
48 #define FLAC__U64L(x) x##LLU
49 #endif
50
51 /* VERSION should come from configure */
52 FLAC_API const char *FLAC__VERSION_STRING = VERSION;
53
54 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
55 /* yet one more hack because of MSVC6: */
56 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.1 20070917";
57 #else
58 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20070917";
59 #endif
60
61 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
62 FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
63 FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
64
65 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
66 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
67 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
68 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
69 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
70 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
71 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
72 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
73 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
74
75 FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
76
77 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
78 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
79 FLAC_API const unsigned 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 unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
84 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
85
86 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
87 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
88 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
89
90 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
91 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
92 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
93 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
94 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
95 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
96 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
97
98 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
99 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
100 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
101 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
102 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
103
104 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
105 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
106 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
107 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
108 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
109 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
110 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
111 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
112
113 FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
114 FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
115 FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
116
117 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
118 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
119 FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
120 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
121 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
122 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
123 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
124 FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
125 FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
126 FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
127
128 FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
129
130 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
131 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
132 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
133 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
134 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
135
136 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
137 FLAC_API const unsigned 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 unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
145 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
146
147 FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
148 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
149 FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
150
151 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
152 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
153 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
154 FLAC_API const unsigned 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
209 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned 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
218 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned 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
228 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
229 {
230         if(
231                 !FLAC__format_sample_rate_is_valid(sample_rate) ||
232                 (
233                         sample_rate >= (1u << 16) &&
234                         !(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
235                 )
236         ) {
237                 return false;
238         }
239         else
240                 return true;
241 }
242
243 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
244 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
245 {
246         unsigned i;
247         FLAC__uint64 prev_sample_number = 0;
248         FLAC__bool got_prev = false;
249
250         FLAC__ASSERT(0 != seek_table);
251
252         for(i = 0; i < seek_table->num_points; i++) {
253                 if(got_prev) {
254                         if(
255                                 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
256                                 seek_table->points[i].sample_number <= prev_sample_number
257                         )
258                                 return false;
259                 }
260                 prev_sample_number = seek_table->points[i].sample_number;
261                 got_prev = true;
262         }
263
264         return true;
265 }
266
267 /* used as the sort predicate for qsort() */
268 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
269 {
270         /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
271         if(l->sample_number == r->sample_number)
272                 return 0;
273         else if(l->sample_number < r->sample_number)
274                 return -1;
275         else
276                 return 1;
277 }
278
279 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
280 FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
281 {
282         unsigned i, j;
283         FLAC__bool first;
284
285         FLAC__ASSERT(0 != seek_table);
286
287         /* sort the seekpoints */
288         qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_);
289
290         /* uniquify the seekpoints */
291         first = true;
292         for(i = j = 0; i < seek_table->num_points; i++) {
293                 if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) {
294                         if(!first) {
295                                 if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number)
296                                         continue;
297                         }
298                 }
299                 first = false;
300                 seek_table->points[j++] = seek_table->points[i];
301         }
302
303         for(i = j; i < seek_table->num_points; i++) {
304                 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
305                 seek_table->points[i].stream_offset = 0;
306                 seek_table->points[i].frame_samples = 0;
307         }
308
309         return j;
310 }
311
312 /*
313  * also disallows non-shortest-form encodings, c.f.
314  *   http://www.unicode.org/versions/corrigendum1.html
315  * and a more clear explanation at the end of this section:
316  *   http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
317  */
318 static unsigned utf8len_(const FLAC__byte *utf8)
319 {
320         FLAC__ASSERT(0 != utf8);
321         if ((utf8[0] & 0x80) == 0) {
322                 return 1;
323         }
324         else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) {
325                 if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */
326                         return 0;
327                 return 2;
328         }
329         else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) {
330                 if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */
331                         return 0;
332                 /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */
333                 if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */
334                         return 0;
335                 if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */
336                         return 0;
337                 return 3;
338         }
339         else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) {
340                 if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */
341                         return 0;
342                 return 4;
343         }
344         else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) {
345                 if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */
346                         return 0;
347                 return 5;
348         }
349         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) {
350                 if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */
351                         return 0;
352                 return 6;
353         }
354         else {
355                 return 0;
356         }
357 }
358
359 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name)
360 {
361         char c;
362         for(c = *name; c; c = *(++name))
363                 if(c < 0x20 || c == 0x3d || c > 0x7d)
364                         return false;
365         return true;
366 }
367
368 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
369 {
370         if(length == (unsigned)(-1)) {
371                 while(*value) {
372                         unsigned n = utf8len_(value);
373                         if(n == 0)
374                                 return false;
375                         value += n;
376                 }
377         }
378         else {
379                 const FLAC__byte *end = value + length;
380                 while(value < end) {
381                         unsigned n = utf8len_(value);
382                         if(n == 0)
383                                 return false;
384                         value += n;
385                 }
386                 if(value != end)
387                         return false;
388         }
389         return true;
390 }
391
392 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length)
393 {
394         const FLAC__byte *s, *end;
395
396         for(s = entry, end = s + length; s < end && *s != '='; s++) {
397                 if(*s < 0x20 || *s > 0x7D)
398                         return false;
399         }
400         if(s == end)
401                 return false;
402
403         s++; /* skip '=' */
404
405         while(s < end) {
406                 unsigned n = utf8len_(s);
407                 if(n == 0)
408                         return false;
409                 s += n;
410         }
411         if(s != end)
412                 return false;
413
414         return true;
415 }
416
417 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
418 FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation)
419 {
420         unsigned i, j;
421
422         if(check_cd_da_subset) {
423                 if(cue_sheet->lead_in < 2 * 44100) {
424                         if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds";
425                         return false;
426                 }
427                 if(cue_sheet->lead_in % 588 != 0) {
428                         if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples";
429                         return false;
430                 }
431         }
432
433         if(cue_sheet->num_tracks == 0) {
434                 if(violation) *violation = "cue sheet must have at least one track (the lead-out)";
435                 return false;
436         }
437
438         if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) {
439                 if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)";
440                 return false;
441         }
442
443         for(i = 0; i < cue_sheet->num_tracks; i++) {
444                 if(cue_sheet->tracks[i].number == 0) {
445                         if(violation) *violation = "cue sheet may not have a track number 0";
446                         return false;
447                 }
448
449                 if(check_cd_da_subset) {
450                         if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) {
451                                 if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170";
452                                 return false;
453                         }
454                 }
455
456                 if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) {
457                         if(violation) {
458                                 if(i == cue_sheet->num_tracks-1) /* the lead-out track... */
459                                         *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples";
460                                 else
461                                         *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples";
462                         }
463                         return false;
464                 }
465
466                 if(i < cue_sheet->num_tracks - 1) {
467                         if(cue_sheet->tracks[i].num_indices == 0) {
468                                 if(violation) *violation = "cue sheet track must have at least one index point";
469                                 return false;
470                         }
471
472                         if(cue_sheet->tracks[i].indices[0].number > 1) {
473                                 if(violation) *violation = "cue sheet track's first index number must be 0 or 1";
474                                 return false;
475                         }
476                 }
477
478                 for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) {
479                         if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) {
480                                 if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples";
481                                 return false;
482                         }
483
484                         if(j > 0) {
485                                 if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) {
486                                         if(violation) *violation = "cue sheet track index numbers must increase by 1";
487                                         return false;
488                                 }
489                         }
490                 }
491         }
492
493         return true;
494 }
495
496 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
497 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation)
498 {
499         char *p;
500         FLAC__byte *b;
501
502         for(p = picture->mime_type; *p; p++) {
503                 if(*p < 0x20 || *p > 0x7e) {
504                         if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)";
505                         return false;
506                 }
507         }
508
509         for(b = picture->description; *b; ) {
510                 unsigned n = utf8len_(b);
511                 if(n == 0) {
512                         if(violation) *violation = "description string must be valid UTF-8";
513                         return false;
514                 }
515                 b += n;
516         }
517
518         return true;
519 }
520
521 /*
522  * These routines are private to libFLAC
523  */
524 unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
525 {
526         return
527                 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
528                         FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
529                         blocksize,
530                         predictor_order
531                 );
532 }
533
534 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
535 {
536         unsigned max_rice_partition_order = 0;
537         while(!(blocksize & 1)) {
538                 max_rice_partition_order++;
539                 blocksize >>= 1;
540         }
541         return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
542 }
543
544 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
545 {
546         unsigned max_rice_partition_order = limit;
547
548         while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
549                 max_rice_partition_order--;
550
551         FLAC__ASSERT(
552                 (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
553                 (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
554         );
555
556         return max_rice_partition_order;
557 }
558
559 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
560 {
561         FLAC__ASSERT(0 != object);
562
563         object->parameters = 0;
564         object->raw_bits = 0;
565         object->capacity_by_order = 0;
566 }
567
568 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
569 {
570         FLAC__ASSERT(0 != object);
571
572         if(0 != object->parameters)
573                 free(object->parameters);
574         if(0 != object->raw_bits)
575                 free(object->raw_bits);
576         FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
577 }
578
579 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
580 {
581         FLAC__ASSERT(0 != object);
582
583         FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
584
585         if(object->capacity_by_order < max_partition_order) {
586                 if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
587                         return false;
588                 if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
589                         return false;
590                 memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
591                 object->capacity_by_order = max_partition_order;
592         }
593
594         return true;
595 }