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