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