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