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