1 /* libFLAC - Free Lossless Audio Codec library 2 * Copyright (C) 2000-2009 Josh Coalson 3 * Copyright (C) 2011-2014 Xiph.Org Foundation 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of the Xiph.org Foundation nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifdef HAVE_CONFIG_H 34 # include <config.h> 35 #endif 36 37 #include <stdio.h> 38 #include <stdlib.h> /* for qsort() */ 39 #include <string.h> /* for memset() */ 40 #include "FLAC/assert.h" 41 #include "FLAC/format.h" 42 #include "share/compat.h" 43 #include "private/format.h" 44 #include "private/macros.h" 45 46 /* VERSION should come from configure */ 47 FLAC_API const char *FLAC__VERSION_STRING = VERSION; 48 49 FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125"; 50 51 FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; 52 FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; 53 FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */ 54 55 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ 56 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ 57 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ 58 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ 59 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ 60 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ 61 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ 62 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ 63 FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ 64 65 FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ 66 67 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ 68 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ 69 FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ 70 71 FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); 72 73 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ 74 FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ 75 76 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ 77 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ 78 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ 79 80 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ 81 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ 82 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ 83 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ 84 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ 85 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ 86 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ 87 88 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ 89 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ 90 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ 91 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ 92 FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ 93 94 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ 95 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */ 96 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */ 97 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */ 98 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */ 99 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */ 100 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */ 101 FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */ 102 103 FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ 104 FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ 105 FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ 106 107 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe; 108 FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ 109 FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */ 110 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */ 111 FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ 112 FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ 113 FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ 114 FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ 115 FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ 116 FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ 117 118 FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ 119 120 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ 121 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ 122 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ 123 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */ 124 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ 125 126 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ 127 FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ 128 129 FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { 130 "PARTITIONED_RICE", 131 "PARTITIONED_RICE2" 132 }; 133 134 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ 135 FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ 136 137 FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ 138 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ 139 FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ 140 141 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; 142 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; 143 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; 144 FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; 145 146 FLAC_API const char * const FLAC__SubframeTypeString[] = { 147 "CONSTANT", 148 "VERBATIM", 149 "FIXED", 150 "LPC" 151 }; 152 153 FLAC_API const char * const FLAC__ChannelAssignmentString[] = { 154 "INDEPENDENT", 155 "LEFT_SIDE", 156 "RIGHT_SIDE", 157 "MID_SIDE" 158 }; 159 160 FLAC_API const char * const FLAC__FrameNumberTypeString[] = { 161 "FRAME_NUMBER_TYPE_FRAME_NUMBER", 162 "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" 163 }; 164 165 FLAC_API const char * const FLAC__MetadataTypeString[] = { 166 "STREAMINFO", 167 "PADDING", 168 "APPLICATION", 169 "SEEKTABLE", 170 "VORBIS_COMMENT", 171 "CUESHEET", 172 "PICTURE" 173 }; 174 175 FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { 176 "Other", 177 "32x32 pixels 'file icon' (PNG only)", 178 "Other file icon", 179 "Cover (front)", 180 "Cover (back)", 181 "Leaflet page", 182 "Media (e.g. label side of CD)", 183 "Lead artist/lead performer/soloist", 184 "Artist/performer", 185 "Conductor", 186 "Band/Orchestra", 187 "Composer", 188 "Lyricist/text writer", 189 "Recording Location", 190 "During recording", 191 "During performance", 192 "Movie/video screen capture", 193 "A bright coloured fish", 194 "Illustration", 195 "Band/artist logotype", 196 "Publisher/Studio logotype" 197 }; 198 199 FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) 200 { 201 if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { 202 return false; 203 } 204 else 205 return true; 206 } 207 208 FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate) 209 { 210 if(blocksize > 16384) 211 return false; 212 else if(sample_rate <= 48000 && blocksize > 4608) 213 return false; 214 else 215 return true; 216 } 217 218 FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) 219 { 220 if( 221 !FLAC__format_sample_rate_is_valid(sample_rate) || 222 ( 223 sample_rate >= (1u << 16) && 224 !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) 225 ) 226 ) { 227 return false; 228 } 229 else 230 return true; 231 } 232 233 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 234 FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) 235 { 236 unsigned i; 237 FLAC__uint64 prev_sample_number = 0; 238 FLAC__bool got_prev = false; 239 240 FLAC__ASSERT(0 != seek_table); 241 242 for(i = 0; i < seek_table->num_points; i++) { 243 if(got_prev) { 244 if( 245 seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && 246 seek_table->points[i].sample_number <= prev_sample_number 247 ) 248 return false; 249 } 250 prev_sample_number = seek_table->points[i].sample_number; 251 got_prev = true; 252 } 253 254 return true; 255 } 256 257 /* used as the sort predicate for qsort() */ 258 static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) 259 { 260 /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ 261 if(l->sample_number == r->sample_number) 262 return 0; 263 else if(l->sample_number < r->sample_number) 264 return -1; 265 else 266 return 1; 267 } 268 269 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 270 FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) 271 { 272 unsigned i, j; 273 FLAC__bool first; 274 275 FLAC__ASSERT(0 != seek_table); 276 277 /* sort the seekpoints */ 278 qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); 279 280 /* uniquify the seekpoints */ 281 first = true; 282 for(i = j = 0; i < seek_table->num_points; i++) { 283 if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { 284 if(!first) { 285 if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) 286 continue; 287 } 288 } 289 first = false; 290 seek_table->points[j++] = seek_table->points[i]; 291 } 292 293 for(i = j; i < seek_table->num_points; i++) { 294 seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; 295 seek_table->points[i].stream_offset = 0; 296 seek_table->points[i].frame_samples = 0; 297 } 298 299 return j; 300 } 301 302 /* 303 * also disallows non-shortest-form encodings, c.f. 304 * http://www.unicode.org/versions/corrigendum1.html 305 * and a more clear explanation at the end of this section: 306 * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 307 */ 308 static unsigned utf8len_(const FLAC__byte *utf8) 309 { 310 FLAC__ASSERT(0 != utf8); 311 if ((utf8[0] & 0x80) == 0) { 312 return 1; 313 } 314 else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { 315 if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ 316 return 0; 317 return 2; 318 } 319 else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { 320 if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ 321 return 0; 322 /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ 323 if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ 324 return 0; 325 if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ 326 return 0; 327 return 3; 328 } 329 else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { 330 if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ 331 return 0; 332 return 4; 333 } 334 else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { 335 if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ 336 return 0; 337 return 5; 338 } 339 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) { 340 if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ 341 return 0; 342 return 6; 343 } 344 else { 345 return 0; 346 } 347 } 348 349 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) 350 { 351 char c; 352 for(c = *name; c; c = *(++name)) 353 if(c < 0x20 || c == 0x3d || c > 0x7d) 354 return false; 355 return true; 356 } 357 358 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length) 359 { 360 if(length == (unsigned)(-1)) { 361 while(*value) { 362 unsigned n = utf8len_(value); 363 if(n == 0) 364 return false; 365 value += n; 366 } 367 } 368 else { 369 const FLAC__byte *end = value + length; 370 while(value < end) { 371 unsigned n = utf8len_(value); 372 if(n == 0) 373 return false; 374 value += n; 375 } 376 if(value != end) 377 return false; 378 } 379 return true; 380 } 381 382 FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length) 383 { 384 const FLAC__byte *s, *end; 385 386 for(s = entry, end = s + length; s < end && *s != '='; s++) { 387 if(*s < 0x20 || *s > 0x7D) 388 return false; 389 } 390 if(s == end) 391 return false; 392 393 s++; /* skip '=' */ 394 395 while(s < end) { 396 unsigned n = utf8len_(s); 397 if(n == 0) 398 return false; 399 s += n; 400 } 401 if(s != end) 402 return false; 403 404 return true; 405 } 406 407 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 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 /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ 487 FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) 488 { 489 char *p; 490 FLAC__byte *b; 491 492 for(p = picture->mime_type; *p; p++) { 493 if(*p < 0x20 || *p > 0x7e) { 494 if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; 495 return false; 496 } 497 } 498 499 for(b = picture->description; *b; ) { 500 unsigned n = utf8len_(b); 501 if(n == 0) { 502 if(violation) *violation = "description string must be valid UTF-8"; 503 return false; 504 } 505 b += n; 506 } 507 508 return true; 509 } 510 511 /* 512 * These routines are private to libFLAC 513 */ 514 unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) 515 { 516 return 517 FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( 518 FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), 519 blocksize, 520 predictor_order 521 ); 522 } 523 524 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) 525 { 526 unsigned max_rice_partition_order = 0; 527 while(!(blocksize & 1)) { 528 max_rice_partition_order++; 529 blocksize >>= 1; 530 } 531 return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); 532 } 533 534 unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) 535 { 536 unsigned max_rice_partition_order = limit; 537 538 while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) 539 max_rice_partition_order--; 540 541 FLAC__ASSERT( 542 (max_rice_partition_order == 0 && blocksize >= predictor_order) || 543 (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) 544 ); 545 546 return max_rice_partition_order; 547 } 548 549 void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) 550 { 551 FLAC__ASSERT(0 != object); 552 553 object->parameters = 0; 554 object->raw_bits = 0; 555 object->capacity_by_order = 0; 556 } 557 558 void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) 559 { 560 FLAC__ASSERT(0 != object); 561 562 if(0 != object->parameters) 563 free(object->parameters); 564 if(0 != object->raw_bits) 565 free(object->raw_bits); 566 FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); 567 } 568 569 FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order) 570 { 571 FLAC__ASSERT(0 != object); 572 573 FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); 574 575 if(object->capacity_by_order < max_partition_order) { 576 if(0 == (object->parameters = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) 577 return false; 578 if(0 == (object->raw_bits = realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) 579 return false; 580 memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); 581 object->capacity_by_order = max_partition_order; 582 } 583 584 return true; 585 } 586