1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ID3" 19 #include <utils/Log.h> 20 21 #include "../include/ID3.h" 22 23 #include <media/stagefright/DataSource.h> 24 #include <media/stagefright/MediaDebug.h> 25 #include <media/stagefright/Utils.h> 26 #include <utils/String8.h> 27 #include <byteswap.h> 28 29 namespace android { 30 31 static const size_t kMaxMetadataSize = 3 * 1024 * 1024; 32 33 ID3::ID3(const sp<DataSource> &source) 34 : mIsValid(false), 35 mData(NULL), 36 mSize(0), 37 mFirstFrameOffset(0), 38 mVersion(ID3_UNKNOWN) { 39 mIsValid = parseV2(source); 40 41 if (!mIsValid) { 42 mIsValid = parseV1(source); 43 } 44 } 45 46 ID3::~ID3() { 47 if (mData) { 48 free(mData); 49 mData = NULL; 50 } 51 } 52 53 bool ID3::isValid() const { 54 return mIsValid; 55 } 56 57 ID3::Version ID3::version() const { 58 return mVersion; 59 } 60 61 // static 62 bool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) { 63 *x = 0; 64 for (int32_t i = 0; i < 4; ++i) { 65 if (encoded[i] & 0x80) { 66 return false; 67 } 68 69 *x = ((*x) << 7) | encoded[i]; 70 } 71 72 return true; 73 } 74 75 bool ID3::parseV2(const sp<DataSource> &source) { 76 struct id3_header { 77 char id[3]; 78 uint8_t version_major; 79 uint8_t version_minor; 80 uint8_t flags; 81 uint8_t enc_size[4]; 82 }; 83 84 id3_header header; 85 if (source->readAt( 86 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 87 return false; 88 } 89 90 if (memcmp(header.id, "ID3", 3)) { 91 return false; 92 } 93 94 if (header.version_major == 0xff || header.version_minor == 0xff) { 95 return false; 96 } 97 98 if (header.version_major == 2) { 99 if (header.flags & 0x3f) { 100 // We only support the 2 high bits, if any of the lower bits are 101 // set, we cannot guarantee to understand the tag format. 102 return false; 103 } 104 105 if (header.flags & 0x40) { 106 // No compression scheme has been decided yet, ignore the 107 // tag if compression is indicated. 108 109 return false; 110 } 111 } else if (header.version_major == 3) { 112 if (header.flags & 0x1f) { 113 // We only support the 3 high bits, if any of the lower bits are 114 // set, we cannot guarantee to understand the tag format. 115 return false; 116 } 117 } else if (header.version_major == 4) { 118 if (header.flags & 0x0f) { 119 // The lower 4 bits are undefined in this spec. 120 return false; 121 } 122 } else { 123 return false; 124 } 125 126 size_t size; 127 if (!ParseSyncsafeInteger(header.enc_size, &size)) { 128 return false; 129 } 130 131 if (size > kMaxMetadataSize) { 132 LOGE("skipping huge ID3 metadata of size %d", size); 133 return false; 134 } 135 136 mData = (uint8_t *)malloc(size); 137 138 if (mData == NULL) { 139 return false; 140 } 141 142 mSize = size; 143 144 if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { 145 free(mData); 146 mData = NULL; 147 148 return false; 149 } 150 151 if (header.version_major == 4) { 152 if (!removeUnsynchronizationV2_4()) { 153 free(mData); 154 mData = NULL; 155 156 return false; 157 } 158 } else if (header.flags & 0x80) { 159 LOGV("removing unsynchronization"); 160 161 removeUnsynchronization(); 162 } 163 164 mFirstFrameOffset = 0; 165 if (header.version_major == 3 && (header.flags & 0x40)) { 166 // Version 2.3 has an optional extended header. 167 168 if (mSize < 4) { 169 free(mData); 170 mData = NULL; 171 172 return false; 173 } 174 175 size_t extendedHeaderSize = U32_AT(&mData[0]) + 4; 176 177 if (extendedHeaderSize > mSize) { 178 free(mData); 179 mData = NULL; 180 181 return false; 182 } 183 184 mFirstFrameOffset = extendedHeaderSize; 185 186 uint16_t extendedFlags = 0; 187 if (extendedHeaderSize >= 6) { 188 extendedFlags = U16_AT(&mData[4]); 189 190 if (extendedHeaderSize >= 10) { 191 size_t paddingSize = U32_AT(&mData[6]); 192 193 if (mFirstFrameOffset + paddingSize > mSize) { 194 free(mData); 195 mData = NULL; 196 197 return false; 198 } 199 200 mSize -= paddingSize; 201 } 202 203 if (extendedFlags & 0x8000) { 204 LOGV("have crc"); 205 } 206 } 207 } else if (header.version_major == 4 && (header.flags & 0x40)) { 208 // Version 2.4 has an optional extended header, that's different 209 // from Version 2.3's... 210 211 if (mSize < 4) { 212 free(mData); 213 mData = NULL; 214 215 return false; 216 } 217 218 size_t ext_size; 219 if (!ParseSyncsafeInteger(mData, &ext_size)) { 220 free(mData); 221 mData = NULL; 222 223 return false; 224 } 225 226 if (ext_size < 6 || ext_size > mSize) { 227 free(mData); 228 mData = NULL; 229 230 return false; 231 } 232 233 mFirstFrameOffset = ext_size; 234 } 235 236 if (header.version_major == 2) { 237 mVersion = ID3_V2_2; 238 } else if (header.version_major == 3) { 239 mVersion = ID3_V2_3; 240 } else { 241 CHECK_EQ(header.version_major, 4); 242 mVersion = ID3_V2_4; 243 } 244 245 return true; 246 } 247 248 void ID3::removeUnsynchronization() { 249 for (size_t i = 0; i + 1 < mSize; ++i) { 250 if (mData[i] == 0xff && mData[i + 1] == 0x00) { 251 memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2); 252 --mSize; 253 } 254 } 255 } 256 257 static void WriteSyncsafeInteger(uint8_t *dst, size_t x) { 258 for (size_t i = 0; i < 4; ++i) { 259 dst[3 - i] = (x & 0x7f); 260 x >>= 7; 261 } 262 } 263 264 bool ID3::removeUnsynchronizationV2_4() { 265 size_t oldSize = mSize; 266 267 size_t offset = 0; 268 while (offset + 10 <= mSize) { 269 if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 270 break; 271 } 272 273 size_t dataSize; 274 if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 275 return false; 276 } 277 278 if (offset + dataSize + 10 > mSize) { 279 return false; 280 } 281 282 uint16_t flags = U16_AT(&mData[offset + 8]); 283 uint16_t prevFlags = flags; 284 285 if (flags & 1) { 286 // Strip data length indicator 287 288 memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); 289 mSize -= 4; 290 dataSize -= 4; 291 292 flags &= ~1; 293 } 294 295 if (flags & 2) { 296 // Unsynchronization added. 297 298 for (size_t i = 0; i + 1 < dataSize; ++i) { 299 if (mData[offset + 10 + i] == 0xff 300 && mData[offset + 11 + i] == 0x00) { 301 memmove(&mData[offset + 11 + i], &mData[offset + 12 + i], 302 mSize - offset - 12 - i); 303 --mSize; 304 --dataSize; 305 } 306 } 307 308 flags &= ~2; 309 } 310 311 if (flags != prevFlags) { 312 WriteSyncsafeInteger(&mData[offset + 4], dataSize); 313 mData[offset + 8] = flags >> 8; 314 mData[offset + 9] = flags & 0xff; 315 } 316 317 offset += 10 + dataSize; 318 } 319 320 memset(&mData[mSize], 0, oldSize - mSize); 321 322 return true; 323 } 324 325 ID3::Iterator::Iterator(const ID3 &parent, const char *id) 326 : mParent(parent), 327 mID(NULL), 328 mOffset(mParent.mFirstFrameOffset), 329 mFrameData(NULL), 330 mFrameSize(0) { 331 if (id) { 332 mID = strdup(id); 333 } 334 335 findFrame(); 336 } 337 338 ID3::Iterator::~Iterator() { 339 if (mID) { 340 free(mID); 341 mID = NULL; 342 } 343 } 344 345 bool ID3::Iterator::done() const { 346 return mFrameData == NULL; 347 } 348 349 void ID3::Iterator::next() { 350 if (mFrameData == NULL) { 351 return; 352 } 353 354 mOffset += mFrameSize; 355 356 findFrame(); 357 } 358 359 void ID3::Iterator::getID(String8 *id) const { 360 id->setTo(""); 361 362 if (mFrameData == NULL) { 363 return; 364 } 365 366 if (mParent.mVersion == ID3_V2_2) { 367 id->setTo((const char *)&mParent.mData[mOffset], 3); 368 } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 369 id->setTo((const char *)&mParent.mData[mOffset], 4); 370 } else { 371 CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 372 373 switch (mOffset) { 374 case 3: 375 id->setTo("TT2"); 376 break; 377 case 33: 378 id->setTo("TP1"); 379 break; 380 case 63: 381 id->setTo("TAL"); 382 break; 383 case 93: 384 id->setTo("TYE"); 385 break; 386 case 97: 387 id->setTo("COM"); 388 break; 389 case 126: 390 id->setTo("TRK"); 391 break; 392 case 127: 393 id->setTo("TCO"); 394 break; 395 default: 396 CHECK(!"should not be here."); 397 break; 398 } 399 } 400 } 401 402 static void convertISO8859ToString8( 403 const uint8_t *data, size_t size, 404 String8 *s) { 405 size_t utf8len = 0; 406 for (size_t i = 0; i < size; ++i) { 407 if (data[i] == '\0') { 408 size = i; 409 break; 410 } else if (data[i] < 0x80) { 411 ++utf8len; 412 } else { 413 utf8len += 2; 414 } 415 } 416 417 if (utf8len == size) { 418 // Only ASCII characters present. 419 420 s->setTo((const char *)data, size); 421 return; 422 } 423 424 char *tmp = new char[utf8len]; 425 char *ptr = tmp; 426 for (size_t i = 0; i < size; ++i) { 427 if (data[i] == '\0') { 428 break; 429 } else if (data[i] < 0x80) { 430 *ptr++ = data[i]; 431 } else if (data[i] < 0xc0) { 432 *ptr++ = 0xc2; 433 *ptr++ = data[i]; 434 } else { 435 *ptr++ = 0xc3; 436 *ptr++ = data[i] - 64; 437 } 438 } 439 440 s->setTo(tmp, utf8len); 441 442 delete[] tmp; 443 tmp = NULL; 444 } 445 446 void ID3::Iterator::getString(String8 *id) const { 447 id->setTo(""); 448 449 if (mFrameData == NULL) { 450 return; 451 } 452 453 if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { 454 if (mOffset == 126 || mOffset == 127) { 455 // Special treatment for the track number and genre. 456 char tmp[16]; 457 sprintf(tmp, "%d", (int)*mFrameData); 458 459 id->setTo(tmp); 460 return; 461 } 462 463 convertISO8859ToString8(mFrameData, mFrameSize, id); 464 return; 465 } 466 467 size_t n = mFrameSize - getHeaderLength() - 1; 468 469 if (*mFrameData == 0x00) { 470 // ISO 8859-1 471 convertISO8859ToString8(mFrameData + 1, n, id); 472 } else if (*mFrameData == 0x03) { 473 // UTF-8 474 id->setTo((const char *)(mFrameData + 1), n); 475 } else if (*mFrameData == 0x02) { 476 // UTF-16 BE, no byte order mark. 477 // API wants number of characters, not number of bytes... 478 int len = n / 2; 479 const char16_t *framedata = (const char16_t *) (mFrameData + 1); 480 char16_t *framedatacopy = NULL; 481 #if BYTE_ORDER == LITTLE_ENDIAN 482 framedatacopy = new char16_t[len]; 483 for (int i = 0; i < len; i++) { 484 framedatacopy[i] = bswap_16(framedata[i]); 485 } 486 framedata = framedatacopy; 487 #endif 488 id->setTo(framedata, len); 489 if (framedatacopy != NULL) { 490 delete[] framedatacopy; 491 } 492 } else { 493 // UCS-2 494 // API wants number of characters, not number of bytes... 495 int len = n / 2; 496 const char16_t *framedata = (const char16_t *) (mFrameData + 1); 497 char16_t *framedatacopy = NULL; 498 if (*framedata == 0xfffe) { 499 // endianness marker doesn't match host endianness, convert 500 framedatacopy = new char16_t[len]; 501 for (int i = 0; i < len; i++) { 502 framedatacopy[i] = bswap_16(framedata[i]); 503 } 504 framedata = framedatacopy; 505 } 506 // If the string starts with an endianness marker, skip it 507 if (*framedata == 0xfeff) { 508 framedata++; 509 len--; 510 } 511 id->setTo(framedata, len); 512 if (framedatacopy != NULL) { 513 delete[] framedatacopy; 514 } 515 } 516 } 517 518 const uint8_t *ID3::Iterator::getData(size_t *length) const { 519 *length = 0; 520 521 if (mFrameData == NULL) { 522 return NULL; 523 } 524 525 *length = mFrameSize - getHeaderLength(); 526 527 return mFrameData; 528 } 529 530 size_t ID3::Iterator::getHeaderLength() const { 531 if (mParent.mVersion == ID3_V2_2) { 532 return 6; 533 } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 534 return 10; 535 } else { 536 CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 537 return 0; 538 } 539 } 540 541 void ID3::Iterator::findFrame() { 542 for (;;) { 543 mFrameData = NULL; 544 mFrameSize = 0; 545 546 if (mParent.mVersion == ID3_V2_2) { 547 if (mOffset + 6 > mParent.mSize) { 548 return; 549 } 550 551 if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 552 return; 553 } 554 555 mFrameSize = 556 (mParent.mData[mOffset + 3] << 16) 557 | (mParent.mData[mOffset + 4] << 8) 558 | mParent.mData[mOffset + 5]; 559 560 mFrameSize += 6; 561 562 if (mOffset + mFrameSize > mParent.mSize) { 563 LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 564 mOffset, mFrameSize, mParent.mSize - mOffset - 6); 565 return; 566 } 567 568 mFrameData = &mParent.mData[mOffset + 6]; 569 570 if (!mID) { 571 break; 572 } 573 574 char id[4]; 575 memcpy(id, &mParent.mData[mOffset], 3); 576 id[3] = '\0'; 577 578 if (!strcmp(id, mID)) { 579 break; 580 } 581 } else if (mParent.mVersion == ID3_V2_3 582 || mParent.mVersion == ID3_V2_4) { 583 if (mOffset + 10 > mParent.mSize) { 584 return; 585 } 586 587 if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 588 return; 589 } 590 591 size_t baseSize; 592 if (mParent.mVersion == ID3_V2_4) { 593 if (!ParseSyncsafeInteger( 594 &mParent.mData[mOffset + 4], &baseSize)) { 595 return; 596 } 597 } else { 598 baseSize = U32_AT(&mParent.mData[mOffset + 4]); 599 } 600 601 mFrameSize = 10 + baseSize; 602 603 if (mOffset + mFrameSize > mParent.mSize) { 604 LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 605 mOffset, mFrameSize, mParent.mSize - mOffset - 10); 606 return; 607 } 608 609 uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); 610 611 if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) 612 || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { 613 // Compression or encryption are not supported at this time. 614 // Per-frame unsynchronization and data-length indicator 615 // have already been taken care of. 616 617 LOGV("Skipping unsupported frame (compression, encryption " 618 "or per-frame unsynchronization flagged"); 619 620 mOffset += mFrameSize; 621 continue; 622 } 623 624 mFrameData = &mParent.mData[mOffset + 10]; 625 626 if (!mID) { 627 break; 628 } 629 630 char id[5]; 631 memcpy(id, &mParent.mData[mOffset], 4); 632 id[4] = '\0'; 633 634 if (!strcmp(id, mID)) { 635 break; 636 } 637 } else { 638 CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 639 640 if (mOffset >= mParent.mSize) { 641 return; 642 } 643 644 mFrameData = &mParent.mData[mOffset]; 645 646 switch (mOffset) { 647 case 3: 648 case 33: 649 case 63: 650 mFrameSize = 30; 651 break; 652 case 93: 653 mFrameSize = 4; 654 break; 655 case 97: 656 if (mParent.mVersion == ID3_V1) { 657 mFrameSize = 30; 658 } else { 659 mFrameSize = 29; 660 } 661 break; 662 case 126: 663 mFrameSize = 1; 664 break; 665 case 127: 666 mFrameSize = 1; 667 break; 668 default: 669 CHECK(!"Should not be here, invalid offset."); 670 break; 671 } 672 673 if (!mID) { 674 break; 675 } 676 677 String8 id; 678 getID(&id); 679 680 if (id == mID) { 681 break; 682 } 683 } 684 685 mOffset += mFrameSize; 686 } 687 } 688 689 static size_t StringSize(const uint8_t *start, uint8_t encoding) { 690 if (encoding == 0x00 || encoding == 0x03) { 691 // ISO 8859-1 or UTF-8 692 return strlen((const char *)start) + 1; 693 } 694 695 // UCS-2 696 size_t n = 0; 697 while (start[n] != '\0' || start[n + 1] != '\0') { 698 n += 2; 699 } 700 701 return n; 702 } 703 704 const void * 705 ID3::getAlbumArt(size_t *length, String8 *mime) const { 706 *length = 0; 707 mime->setTo(""); 708 709 Iterator it( 710 *this, 711 (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) ? "APIC" : "PIC"); 712 713 while (!it.done()) { 714 size_t size; 715 const uint8_t *data = it.getData(&size); 716 717 if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { 718 uint8_t encoding = data[0]; 719 mime->setTo((const char *)&data[1]); 720 size_t mimeLen = strlen((const char *)&data[1]) + 1; 721 722 uint8_t picType = data[1 + mimeLen]; 723 #if 0 724 if (picType != 0x03) { 725 // Front Cover Art 726 it.next(); 727 continue; 728 } 729 #endif 730 731 size_t descLen = StringSize(&data[2 + mimeLen], encoding); 732 733 *length = size - 2 - mimeLen - descLen; 734 735 return &data[2 + mimeLen + descLen]; 736 } else { 737 uint8_t encoding = data[0]; 738 739 if (!memcmp(&data[1], "PNG", 3)) { 740 mime->setTo("image/png"); 741 } else if (!memcmp(&data[1], "JPG", 3)) { 742 mime->setTo("image/jpeg"); 743 } else if (!memcmp(&data[1], "-->", 3)) { 744 mime->setTo("text/plain"); 745 } else { 746 return NULL; 747 } 748 749 #if 0 750 uint8_t picType = data[4]; 751 if (picType != 0x03) { 752 // Front Cover Art 753 it.next(); 754 continue; 755 } 756 #endif 757 758 size_t descLen = StringSize(&data[5], encoding); 759 760 *length = size - 5 - descLen; 761 762 return &data[5 + descLen]; 763 } 764 } 765 766 return NULL; 767 } 768 769 bool ID3::parseV1(const sp<DataSource> &source) { 770 const size_t V1_TAG_SIZE = 128; 771 772 off_t size; 773 if (source->getSize(&size) != OK || size < (off_t)V1_TAG_SIZE) { 774 return false; 775 } 776 777 mData = (uint8_t *)malloc(V1_TAG_SIZE); 778 if (source->readAt(size - V1_TAG_SIZE, mData, V1_TAG_SIZE) 779 != (ssize_t)V1_TAG_SIZE) { 780 free(mData); 781 mData = NULL; 782 783 return false; 784 } 785 786 if (memcmp("TAG", mData, 3)) { 787 free(mData); 788 mData = NULL; 789 790 return false; 791 } 792 793 mSize = V1_TAG_SIZE; 794 mFirstFrameOffset = 3; 795 796 if (mData[V1_TAG_SIZE - 3] != 0) { 797 mVersion = ID3_V1; 798 } else { 799 mVersion = ID3_V1_1; 800 } 801 802 return true; 803 } 804 805 } // namespace android 806