ID3.cpp revision ac994dfb88d414aeedf5998aa1c6015c5b47ec01
1fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber/* 2fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * 4fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * you may not use this file except in compliance with the License. 6fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * You may obtain a copy of the License at 7fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * 8fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * 10fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * Unless required by applicable law or agreed to in writing, software 11fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * See the License for the specific language governing permissions and 14fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber * limitations under the License. 15fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber */ 16fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 17fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber//#define LOG_NDEBUG 0 18fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#define LOG_TAG "ID3" 19fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <utils/Log.h> 20fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 21fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include "../include/ID3.h" 22fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 23fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/DataSource.h> 24fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/MediaDebug.h> 25fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/Utils.h> 26fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <utils/String8.h> 27569e7f1b1444194d1aca5a0b23de154565ba12daMarco Nelissen#include <byteswap.h> 28fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 29fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubernamespace android { 30fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 3165997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huberstatic const size_t kMaxMetadataSize = 3 * 1024 * 1024; 3265997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 33fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::ID3(const sp<DataSource> &source) 34fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mIsValid(false), 35fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData(NULL), 36fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize(0), 37fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset(0), 38fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion(ID3_UNKNOWN) { 3983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mIsValid = parseV2(source); 4083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 4183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (!mIsValid) { 4283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mIsValid = parseV1(source); 4383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 44fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 45fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 46fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::~ID3() { 47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData) { 48fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mData); 49fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = NULL; 50fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 51fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 52fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 53fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::isValid() const { 54fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mIsValid; 55fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 56fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 57fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Version ID3::version() const { 58fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mVersion; 59fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 60fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 61bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber// static 62bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberbool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) { 63bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = 0; 64bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber for (int32_t i = 0; i < 4; ++i) { 65bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoded[i] & 0x80) { 66bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 67bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 68bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 69bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = ((*x) << 7) | encoded[i]; 70bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 71bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 72bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return true; 73bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber} 74bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 7583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huberbool ID3::parseV2(const sp<DataSource> &source) { 76bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberstruct id3_header { 77bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char id[3]; 78bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_major; 79bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_minor; 80bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t flags; 81bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t enc_size[4]; 82fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 83fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 84fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id3_header header; 85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt( 86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (memcmp(header.id, "ID3", 3)) { 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 0xff || header.version_minor == 0xff) { 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x3f) { 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 2 high bits, if any of the lower bits are 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 104fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 105fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x40) { 106fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // No compression scheme has been decided yet, ignore the 107fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // tag if compression is indicated. 108fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 109fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 110fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 111fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (header.version_major == 3) { 112fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x1f) { 113fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 3 high bits, if any of the lower bits are 114fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 115fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 116fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 117bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4) { 118bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (header.flags & 0x0f) { 119bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // The lower 4 bits are undefined in this spec. 120bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 121bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 122fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 123fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 124fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 125fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 126bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t size; 127bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(header.enc_size, &size)) { 128bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 129fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 130fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 13165997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber if (size > kMaxMetadataSize) { 13265997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber LOGE("skipping huge ID3 metadata of size %d", size); 13365997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber return false; 13465997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber } 13565997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = (uint8_t *)malloc(size); 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData == NULL) { 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 140fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 141fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 142fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize = size; 143fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 144fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { 145ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 146ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 147ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 148fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 149fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 150fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 151ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (header.version_major == 4) { 152ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (!removeUnsynchronizationV2_4()) { 153ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 154ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 155ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 156ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 157ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 158ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } else if (header.flags & 0x80) { 15983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber LOGV("removing unsynchronization"); 160ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 161fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber removeUnsynchronization(); 162fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 163fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 164fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = 0; 165fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 3 && (header.flags & 0x40)) { 166fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Version 2.3 has an optional extended header. 167fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 168fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSize < 4) { 16983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 17083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 17183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 172fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 173fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 174fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 175fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t extendedHeaderSize = U32_AT(&mData[0]) + 4; 176fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 177fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize > mSize) { 17883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 17983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 18083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 181fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 182fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 183fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = extendedHeaderSize; 185fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 186fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint16_t extendedFlags = 0; 187fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 6) { 188fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber extendedFlags = U16_AT(&mData[4]); 189fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 190fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 10) { 191fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t paddingSize = U32_AT(&mData[6]); 192fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 193fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFirstFrameOffset + paddingSize > mSize) { 19483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 19583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 19683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 197fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 198fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 199fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 200fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize -= paddingSize; 201fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 202fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 203fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedFlags & 0x8000) { 20483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber LOGV("have crc"); 205fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 206fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 207bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4 && (header.flags & 0x40)) { 208bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // Version 2.4 has an optional extended header, that's different 209bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // from Version 2.3's... 210bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 211bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mSize < 4) { 212bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 213bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 214bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 215bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 216bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 217bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 218bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t ext_size; 219bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(mData, &ext_size)) { 220bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 221bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 222bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 223bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 224bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 225bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 226bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (ext_size < 6 || ext_size > mSize) { 227bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 228bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 229bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 230bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 231bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 232bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 233bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mFirstFrameOffset = ext_size; 234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 235fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 236fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 237fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_2; 238bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 3) { 239fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_3; 240bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 241bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber CHECK_EQ(header.version_major, 4); 242bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mVersion = ID3_V2_4; 243fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 244fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 245fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 246fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 247fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 248fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::removeUnsynchronization() { 249fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i + 1 < mSize; ++i) { 250fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData[i] == 0xff && mData[i + 1] == 0x00) { 251fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2); 252fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber --mSize; 253fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 254fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 255fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 256fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 257ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huberstatic void WriteSyncsafeInteger(uint8_t *dst, size_t x) { 258ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i < 4; ++i) { 259ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dst[3 - i] = (x & 0x7f); 260ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber x >>= 7; 261ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 262ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 263ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 264ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huberbool ID3::removeUnsynchronizationV2_4() { 265ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t oldSize = mSize; 266ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 267ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t offset = 0; 268ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber while (offset + 10 <= mSize) { 269ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 270ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber break; 271ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 272ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 273ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t dataSize; 274ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 275ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 276ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 277ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 278ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (offset + dataSize + 10 > mSize) { 279ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 280ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 281ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 282ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t flags = U16_AT(&mData[offset + 8]); 283ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t prevFlags = flags; 284ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 285ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags & 1) { 286ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Strip data length indicator 287ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 288ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); 289ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mSize -= 4; 290ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dataSize -= 4; 291ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 292ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber flags &= ~1; 293ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 294ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 295ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags & 2) { 296ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Unsynchronization added. 297ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 298ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i + 1 < dataSize; ++i) { 299ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (mData[offset + 10 + i] == 0xff 300ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber && mData[offset + 11 + i] == 0x00) { 301ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memmove(&mData[offset + 11 + i], &mData[offset + 12 + i], 302ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mSize - offset - 12 - i); 303ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --mSize; 304ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --dataSize; 305ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 306ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 307ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 308ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber flags &= ~2; 309ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 310ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 311ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags != prevFlags) { 312ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber WriteSyncsafeInteger(&mData[offset + 4], dataSize); 313ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 8] = flags >> 8; 314ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 9] = flags & 0xff; 315ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 316ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 317ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber offset += 10 + dataSize; 318ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 319ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 320ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memset(&mData[mSize], 0, oldSize - mSize); 321ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 322ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return true; 323ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 324ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 325fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::Iterator(const ID3 &parent, const char *id) 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParent(parent), 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID(NULL), 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset(mParent.mFirstFrameOffset), 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData(NULL), 330fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize(0) { 331fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (id) { 332fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = strdup(id); 333fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 334fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 335fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 336fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 337fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 338fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::~Iterator() { 339fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mID) { 340fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mID); 341fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = NULL; 342fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 343fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 344fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 345fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::Iterator::done() const { 346fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData == NULL; 347fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 348fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 349fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::next() { 350fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 351fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 352fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 353fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 354fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 355fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 356fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 357fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 358fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 359fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getID(String8 *id) const { 360fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 361fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 362fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 363fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 364fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 365fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 366fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 367fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 3); 368bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 369fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 4); 37083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 37183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 37283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 37383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 37483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 37583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TT2"); 37683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 37783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 37883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TP1"); 37983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 38083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 38183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TAL"); 38283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 38383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 38483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TYE"); 38583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 38683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 38783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("COM"); 38883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 38983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 39083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TRK"); 39183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 39283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 39383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TCO"); 39483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 39583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 39683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"should not be here."); 39783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 39883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 399fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 400fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 401fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 402fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic void convertISO8859ToString8( 403fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data, size_t size, 404fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber String8 *s) { 405fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t utf8len = 0; 406fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 4074c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber if (data[i] == '\0') { 408632a7dfdab89ffa79846ad37718d0582fd36affeKenny Root size = i; 4094c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber break; 4104c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber } else if (data[i] < 0x80) { 411fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ++utf8len; 412fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 413fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber utf8len += 2; 414fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 415fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 416fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 417fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (utf8len == size) { 418fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Only ASCII characters present. 419fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 420fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo((const char *)data, size); 421fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 422fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 423fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 424fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *tmp = new char[utf8len]; 425fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *ptr = tmp; 426fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 4274c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber if (data[i] == '\0') { 4284c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber break; 4294c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber } else if (data[i] < 0x80) { 430fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 431fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (data[i] < 0xc0) { 432fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc2; 433fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 434fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 435fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc3; 436fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i] - 64; 437fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 438fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 439fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo(tmp, utf8len); 441fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 442fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete[] tmp; 443fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber tmp = NULL; 444fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 445fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 446fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getString(String8 *id) const { 447fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 448fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 449fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 450fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 451fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 452fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 45383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { 45483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset == 126 || mOffset == 127) { 45583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber // Special treatment for the track number and genre. 45683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber char tmp[16]; 45783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber sprintf(tmp, "%d", (int)*mFrameData); 45883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 45983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo(tmp); 46083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 46183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 46283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 4634c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber convertISO8859ToString8(mFrameData, mFrameSize, id); 46483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 46583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 46683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 467fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = mFrameSize - getHeaderLength() - 1; 468fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 469fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (*mFrameData == 0x00) { 470fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // ISO 8859-1 471fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber convertISO8859ToString8(mFrameData + 1, n, id); 472bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (*mFrameData == 0x03) { 473bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // UTF-8 474bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber id->setTo((const char *)(mFrameData + 1), n); 475bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (*mFrameData == 0x02) { 476bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // UTF-16 BE, no byte order mark. 477bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // API wants number of characters, not number of bytes... 478bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber int len = n / 2; 479bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber const char16_t *framedata = (const char16_t *) (mFrameData + 1); 480bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char16_t *framedatacopy = NULL; 481bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#if BYTE_ORDER == LITTLE_ENDIAN 482bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedatacopy = new char16_t[len]; 483bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber for (int i = 0; i < len; i++) { 484bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedatacopy[i] = bswap_16(framedata[i]); 485bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 486bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedata = framedatacopy; 487bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#endif 488bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber id->setTo(framedata, len); 489bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (framedatacopy != NULL) { 490bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber delete[] framedatacopy; 491bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 492fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 493fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 49408e7eb983fcb9860a574e964ff905f75aab88d2fAndreas Huber // API wants number of characters, not number of bytes... 4955a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen int len = n / 2; 4965a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen const char16_t *framedata = (const char16_t *) (mFrameData + 1); 4975a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen char16_t *framedatacopy = NULL; 4985a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfffe) { 4995a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // endianness marker doesn't match host endianness, convert 5005a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedatacopy = new char16_t[len]; 5015a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen for (int i = 0; i < len; i++) { 502569e7f1b1444194d1aca5a0b23de154565ba12daMarco Nelissen framedatacopy[i] = bswap_16(framedata[i]); 5035a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 5045a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata = framedatacopy; 5055a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 5065a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // If the string starts with an endianness marker, skip it 5075a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfeff) { 5085a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata++; 5095a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen len--; 5105a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 5115a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen id->setTo(framedata, len); 5125a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (framedatacopy != NULL) { 5135a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen delete[] framedatacopy; 5145a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 515fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 516fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 517fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 518fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst uint8_t *ID3::Iterator::getData(size_t *length) const { 519fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 520fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 521fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 522fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 523fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 524fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 525fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = mFrameSize - getHeaderLength(); 526fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 527fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData; 528fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 529fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 530fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersize_t ID3::Iterator::getHeaderLength() const { 531fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 532fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 6; 533bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 534fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 10; 53583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 53683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 53783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return 0; 538fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 539fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 540fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 541fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::findFrame() { 542fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (;;) { 543fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = NULL; 544fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 0; 545fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 546fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 547fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 6 > mParent.mSize) { 548fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 549fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 550fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 551fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 552fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 553fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 554fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 555fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 556fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber (mParent.mData[mOffset + 3] << 16) 557fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | (mParent.mData[mOffset + 4] << 8) 558fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | mParent.mData[mOffset + 5]; 559fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 560fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize += 6; 561fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 562fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 563fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 564fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 6); 565fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 566fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 567fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 568fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 6]; 569fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 570fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 571fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 572fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 573fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 574fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[4]; 575fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 3); 576fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[3] = '\0'; 577fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 578fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 579fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 580fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 581bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 582bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || mParent.mVersion == ID3_V2_4) { 583fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 10 > mParent.mSize) { 584fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 585fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 586fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 587fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 588fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 589fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 590fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 591bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t baseSize; 592bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mParent.mVersion == ID3_V2_4) { 593bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger( 594bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber &mParent.mData[mOffset + 4], &baseSize)) { 595bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return; 596bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 597bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 598bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber baseSize = U32_AT(&mParent.mData[mOffset + 4]); 599bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 600bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 601bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mFrameSize = 10 + baseSize; 602fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 603fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 604fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 605fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 10); 606fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 607fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 608fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 609bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); 610bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 611ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) 612bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { 613ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Compression or encryption are not supported at this time. 614ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Per-frame unsynchronization and data-length indicator 615ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // have already been taken care of. 616bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 617bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber LOGV("Skipping unsupported frame (compression, encryption " 618bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber "or per-frame unsynchronization flagged"); 619bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 620bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mOffset += mFrameSize; 621bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber continue; 622bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 623bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 624fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 10]; 625fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 626fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 627fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 628fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 629fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 630fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[5]; 631fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 4); 632fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[4] = '\0'; 633fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 634fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 635fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 636fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 63783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 63883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 63983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 64083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset >= mParent.mSize) { 64183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 64283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 64383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 64483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameData = &mParent.mData[mOffset]; 64583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 64683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 64783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 64883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 64983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 65083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 65183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 65283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 65383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 4; 65483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 65583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 65683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1) { 65783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 65883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 65983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 29; 66083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 66183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 66283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 66383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 66483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 66583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 66683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 66783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 66883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 66983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"Should not be here, invalid offset."); 67083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 67183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 67283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 67383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (!mID) { 67483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 67583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 67683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 67783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber String8 id; 67883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber getID(&id); 67983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 68083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (id == mID) { 68183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 68283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 683fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 684fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 685fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 686fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 687fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 688fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 689fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic size_t StringSize(const uint8_t *start, uint8_t encoding) { 690bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoding == 0x00 || encoding == 0x03) { 691bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // ISO 8859-1 or UTF-8 692fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return strlen((const char *)start) + 1; 693fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 694fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 695fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 696fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = 0; 697fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (start[n] != '\0' || start[n + 1] != '\0') { 698fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber n += 2; 699fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 700fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 701fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return n; 702fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 703fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 704fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst void * 705fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::getAlbumArt(size_t *length, String8 *mime) const { 706fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 707fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo(""); 708fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 709bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber Iterator it( 710bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *this, 711bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) ? "APIC" : "PIC"); 712fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 713fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (!it.done()) { 714fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size; 715fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data = it.getData(&size); 716fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 717bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { 718fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 719fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo((const char *)&data[1]); 720fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t mimeLen = strlen((const char *)&data[1]) + 1; 721fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 722fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[1 + mimeLen]; 723fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 724fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 725fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 726fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 727fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 728fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 729fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 730fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 731fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[2 + mimeLen], encoding); 732fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 733fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 2 - mimeLen - descLen; 734fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 735fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[2 + mimeLen + descLen]; 736fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 737fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 738fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 739fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&data[1], "PNG", 3)) { 740fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/png"); 741fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "JPG", 3)) { 742fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/jpeg"); 743fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "-->", 3)) { 744fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("text/plain"); 745fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 746fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 747fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 748fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 749fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 750fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[4]; 751fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 752fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 753fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 754fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 755fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 756fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 757fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 758fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[5], encoding); 759fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 760fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 5 - descLen; 761fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 762fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[5 + descLen]; 763fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 764fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 765fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 766fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 767fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 768fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 76983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huberbool ID3::parseV1(const sp<DataSource> &source) { 77083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber const size_t V1_TAG_SIZE = 128; 77183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 77283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber off_t size; 77383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->getSize(&size) != OK || size < (off_t)V1_TAG_SIZE) { 77483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 77583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 77683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 77783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = (uint8_t *)malloc(V1_TAG_SIZE); 77883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->readAt(size - V1_TAG_SIZE, mData, V1_TAG_SIZE) 77983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber != (ssize_t)V1_TAG_SIZE) { 78083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 78183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 78283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 78383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 78483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 78583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 78683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (memcmp("TAG", mData, 3)) { 78783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 78883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 78983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 79083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 79183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 79283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 79383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mSize = V1_TAG_SIZE; 79483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFirstFrameOffset = 3; 79583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 79683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mData[V1_TAG_SIZE - 3] != 0) { 79783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1; 79883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 79983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1_1; 80083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 80183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 80283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return true; 80383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber} 804fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 805fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} // namespace android 806