a.out format does not support many .section directives
[platform/upstream/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
43 #ifdef min
44 #undef min
45 #endif
46 #define min(a,b) ((a)<(b)?(a):(b))
47
48 /* adjust for compilers that can't understand using LLU suffix for uint64_t literals */
49 #ifdef _MSC_VER
50 #define FLAC__U64L(x) x
51 #else
52 #define FLAC__U64L(x) x##LLU
53 #endif
54
55 /* VERSION should come from configure */
56 FLAC_API const char *FLAC__VERSION_STRING = VERSION;
57
58 #if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__
59 /* yet one more hack because of MSVC6: */
60 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.2.1 20070917";
61 #else
62 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20070917";
63 #endif
64
65 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
66 FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
67 FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */
68
69 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */
70 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */
71 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */
72 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */
73 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */
74 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */
75 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */
76 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */
77 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */
78
79 FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */
80
81 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
82 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
83 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
84
85 FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff);
86
87 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */
88 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */
89
90 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */
91 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */
92 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */
93
94 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */
95 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */
96 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */
97 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */
98 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */
99 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */
100 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */
101
102 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */
103 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */
104 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */
105 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */
106 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */
107
108 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */
109 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */
110 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */
111 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */
112 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */
113 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */
114 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */
115 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */
116
117 FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
118 FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
119 FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
120
121 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
122 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
123 FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */
124 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */
125 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
126 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
127 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
128 FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
129 FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
130 FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
131
132 FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
133
134 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
135 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
136 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */
137 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */
138 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */
139
140 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */
141 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */
142
143 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = {
144         "PARTITIONED_RICE",
145         "PARTITIONED_RICE2"
146 };
147
148 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
149 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
150
151 FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
152 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
153 FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
154
155 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
156 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
157 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
158 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
159
160 FLAC_API const char * const FLAC__SubframeTypeString[] = {
161         "CONSTANT",
162         "VERBATIM",
163         "FIXED",
164         "LPC"
165 };
166
167 FLAC_API const char * const FLAC__ChannelAssignmentString[] = {
168         "INDEPENDENT",
169         "LEFT_SIDE",
170         "RIGHT_SIDE",
171         "MID_SIDE"
172 };
173
174 FLAC_API const char * const FLAC__FrameNumberTypeString[] = {
175         "FRAME_NUMBER_TYPE_FRAME_NUMBER",
176         "FRAME_NUMBER_TYPE_SAMPLE_NUMBER"
177 };
178
179 FLAC_API const char * const FLAC__MetadataTypeString[] = {
180         "STREAMINFO",
181         "PADDING",
182         "APPLICATION",
183         "SEEKTABLE",
184         "VORBIS_COMMENT",
185         "CUESHEET",
186         "PICTURE"
187 };
188
189 FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
190         "Other",
191         "32x32 pixels 'file icon' (PNG only)",
192         "Other file icon",
193         "Cover (front)",
194         "Cover (back)",
195         "Leaflet page",
196         "Media (e.g. label side of CD)",
197         "Lead artist/lead performer/soloist",
198         "Artist/performer",
199         "Conductor",
200         "Band/Orchestra",
201         "Composer",
202         "Lyricist/text writer",
203         "Recording Location",
204         "During recording",
205         "During performance",
206         "Movie/video screen capture",
207         "A bright coloured fish",
208         "Illustration",
209         "Band/artist logotype",
210         "Publisher/Studio logotype"
211 };
212
213 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
214 {
215         if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
216                 return false;
217         }
218         else
219                 return true;
220 }
221
222 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate)
223 {
224         if(blocksize > 16384)
225                 return false;
226         else if(sample_rate <= 48000 && blocksize > 4608)
227                 return false;
228         else
229                 return true;
230 }
231
232 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
233 {
234         if(
235                 !FLAC__format_sample_rate_is_valid(sample_rate) ||
236                 (
237                         sample_rate >= (1u << 16) &&
238                         !(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
239                 )
240         ) {
241                 return false;
242         }
243         else
244                 return true;
245 }
246
247 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
248 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table)
249 {
250         unsigned i;
251         FLAC__uint64 prev_sample_number = 0;
252         FLAC__bool got_prev = false;
253
254         FLAC__ASSERT(0 != seek_table);
255
256         for(i = 0; i < seek_table->num_points; i++) {
257                 if(got_prev) {
258                         if(
259                                 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER &&
260                                 seek_table->points[i].sample_number <= prev_sample_number
261                         )
262                                 return false;
263                 }
264                 prev_sample_number = seek_table->points[i].sample_number;
265                 got_prev = true;
266         }
267
268         return true;
269 }
270
271 /* used as the sort predicate for qsort() */
272 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r)
273 {
274         /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */
275         if(l->sample_number == r->sample_number)
276                 return 0;
277         else if(l->sample_number < r->sample_number)
278                 return -1;
279         else
280                 return 1;
281 }
282
283 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */
284 FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table)
285 {
286         unsigned i, j;
287         FLAC__bool first;
288
289         FLAC__ASSERT(0 != seek_table);
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  */
322 static unsigned 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
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
372 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length)
373 {
374         if(length == (unsigned)(-1)) {
375                 while(*value) {
376                         unsigned 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                         unsigned 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
396 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned 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                 unsigned 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 */
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         unsigned 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 */
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                 unsigned 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 unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order)
529 {
530         return
531                 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(
532                         FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize),
533                         blocksize,
534                         predictor_order
535                 );
536 }
537
538 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize)
539 {
540         unsigned max_rice_partition_order = 0;
541         while(!(blocksize & 1)) {
542                 max_rice_partition_order++;
543                 blocksize >>= 1;
544         }
545         return min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order);
546 }
547
548 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order)
549 {
550         unsigned max_rice_partition_order = limit;
551
552         while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order)
553                 max_rice_partition_order--;
554
555         FLAC__ASSERT(
556                 (max_rice_partition_order == 0 && blocksize >= predictor_order) ||
557                 (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order)
558         );
559
560         return max_rice_partition_order;
561 }
562
563 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
564 {
565         FLAC__ASSERT(0 != object);
566
567         object->parameters = 0;
568         object->raw_bits = 0;
569         object->capacity_by_order = 0;
570 }
571
572 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object)
573 {
574         FLAC__ASSERT(0 != object);
575
576         if(0 != object->parameters)
577                 free(object->parameters);
578         if(0 != object->raw_bits)
579                 free(object->raw_bits);
580         FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object);
581 }
582
583 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order)
584 {
585         FLAC__ASSERT(0 != object);
586
587         FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits));
588
589         if(object->capacity_by_order < max_partition_order) {
590                 if(0 == (object->parameters = (unsigned*)realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
591                         return false;
592                 if(0 == (object->raw_bits = (unsigned*)realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order))))
593                         return false;
594                 memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order));
595                 object->capacity_by_order = max_partition_order;
596         }
597
598         return true;
599 }