ID3.cpp revision 65997f022fa3f557ba864ecc99a1aa33df54c2db
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 6183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huberbool ID3::parseV2(const sp<DataSource> &source) { 62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber struct id3_header { 63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[3]; 64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t version_major; 65fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t version_minor; 66fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t flags; 67fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t enc_size[4]; 68fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 69fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 70fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id3_header header; 71fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt( 72fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 73fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 74fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 75fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 76fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (memcmp(header.id, "ID3", 3)) { 77fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 78fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 79fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 80fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 0xff || header.version_minor == 0xff) { 81fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 82fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 83fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 84fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x3f) { 86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 2 high bits, if any of the lower bits are 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x40) { 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // No compression scheme has been decided yet, ignore the 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // tag if compression is indicated. 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (header.version_major == 3) { 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x1f) { 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 3 high bits, if any of the lower bits are 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 104fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 105fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 106fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 107fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size = 0; 108fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (int32_t i = 0; i < 4; ++i) { 109fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.enc_size[i] & 0x80) { 110fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 111fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 112fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 113fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size = (size << 7) | header.enc_size[i]; 114fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 115fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 11665997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber if (size > kMaxMetadataSize) { 11765997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber LOGE("skipping huge ID3 metadata of size %d", size); 11865997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber return false; 11965997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber } 12065997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 121fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = (uint8_t *)malloc(size); 122fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 123fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData == NULL) { 124fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 125fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 126fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 127fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize = size; 128fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 129fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { 130fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 131fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 132fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 133fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x80) { 13483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber LOGV("removing unsynchronization"); 135fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber removeUnsynchronization(); 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = 0; 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 3 && (header.flags & 0x40)) { 140fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Version 2.3 has an optional extended header. 141fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 142fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSize < 4) { 14383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 14483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 14583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 146fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 147fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 148fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 149fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t extendedHeaderSize = U32_AT(&mData[0]) + 4; 150fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 151fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize > mSize) { 15283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 15383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 15483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 155fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 156fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 157fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 158fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = extendedHeaderSize; 159fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 160fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint16_t extendedFlags = 0; 161fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 6) { 162fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber extendedFlags = U16_AT(&mData[4]); 163fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 164fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 10) { 165fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t paddingSize = U32_AT(&mData[6]); 166fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 167fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFirstFrameOffset + paddingSize > mSize) { 16883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 16983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 17083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 171fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 172fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 173fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 174fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize -= paddingSize; 175fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 176fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 177fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedFlags & 0x8000) { 17883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber LOGV("have crc"); 179fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 180fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 181fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 182fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 183fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_2; 185fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 186fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber CHECK_EQ(header.version_major, 3); 187fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_3; 188fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 189fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 190fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 191fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 192fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 193fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::removeUnsynchronization() { 194fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i + 1 < mSize; ++i) { 195fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData[i] == 0xff && mData[i + 1] == 0x00) { 196fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2); 197fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber --mSize; 198fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 199fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 200fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 201fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 202fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::Iterator(const ID3 &parent, const char *id) 203fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParent(parent), 204fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID(NULL), 205fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset(mParent.mFirstFrameOffset), 206fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData(NULL), 207fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize(0) { 208fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (id) { 209fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = strdup(id); 210fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 211fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 212fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 213fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 214fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 215fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::~Iterator() { 216fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mID) { 217fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mID); 218fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = NULL; 219fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 220fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 221fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 222fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::Iterator::done() const { 223fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData == NULL; 224fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 225fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 226fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::next() { 227fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 228fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 229fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 230fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 231fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 232fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 233fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 235fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 236fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getID(String8 *id) const { 237fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 238fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 239fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 240fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 241fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 242fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 243fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 244fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 3); 24583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else if (mParent.mVersion == ID3_V2_3) { 246fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 4); 24783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 24883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 24983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 25083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 25183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 25283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TT2"); 25383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 25483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 25583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TP1"); 25683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 25783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 25883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TAL"); 25983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 26083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 26183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TYE"); 26283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 26383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 26483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("COM"); 26583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 26683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 26783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TRK"); 26883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 26983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 27083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TCO"); 27183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 27283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 27383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"should not be here."); 27483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 27583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 276fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 277fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 278fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 279fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic void convertISO8859ToString8( 280fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data, size_t size, 281fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber String8 *s) { 282fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t utf8len = 0; 283fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 2844c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber if (data[i] == '\0') { 285632a7dfdab89ffa79846ad37718d0582fd36affeKenny Root size = i; 2864c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber break; 2874c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber } else if (data[i] < 0x80) { 288fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ++utf8len; 289fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 290fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber utf8len += 2; 291fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 292fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 293fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 294fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (utf8len == size) { 295fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Only ASCII characters present. 296fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 297fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo((const char *)data, size); 298fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 299fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 300fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 301fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *tmp = new char[utf8len]; 302fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *ptr = tmp; 303fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 3044c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber if (data[i] == '\0') { 3054c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber break; 3064c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber } else if (data[i] < 0x80) { 307fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 308fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (data[i] < 0xc0) { 309fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc2; 310fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 311fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 312fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc3; 313fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i] - 64; 314fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 315fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 316fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 317fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo(tmp, utf8len); 318fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 319fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete[] tmp; 320fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber tmp = NULL; 321fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 322fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 323fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getString(String8 *id) const { 324fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 325fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 33083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { 33183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset == 126 || mOffset == 127) { 33283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber // Special treatment for the track number and genre. 33383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber char tmp[16]; 33483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber sprintf(tmp, "%d", (int)*mFrameData); 33583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 33683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo(tmp); 33783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 33883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 33983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 3404c23b7d543cd95250e766cef7558d0f4c941ddcbAndreas Huber convertISO8859ToString8(mFrameData, mFrameSize, id); 34183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 34283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 34383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 344fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = mFrameSize - getHeaderLength() - 1; 345fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 346fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (*mFrameData == 0x00) { 347fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // ISO 8859-1 348fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber convertISO8859ToString8(mFrameData + 1, n, id); 349fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 350fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 35108e7eb983fcb9860a574e964ff905f75aab88d2fAndreas Huber // API wants number of characters, not number of bytes... 3525a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen int len = n / 2; 3535a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen const char16_t *framedata = (const char16_t *) (mFrameData + 1); 3545a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen char16_t *framedatacopy = NULL; 3555a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfffe) { 3565a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // endianness marker doesn't match host endianness, convert 3575a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedatacopy = new char16_t[len]; 3585a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen for (int i = 0; i < len; i++) { 359569e7f1b1444194d1aca5a0b23de154565ba12daMarco Nelissen framedatacopy[i] = bswap_16(framedata[i]); 3605a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 3615a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata = framedatacopy; 3625a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 3635a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // If the string starts with an endianness marker, skip it 3645a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfeff) { 3655a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata++; 3665a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen len--; 3675a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 3685a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen id->setTo(framedata, len); 3695a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (framedatacopy != NULL) { 3705a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen delete[] framedatacopy; 3715a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 372fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 373fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 374fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 375fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst uint8_t *ID3::Iterator::getData(size_t *length) const { 376fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 377fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 378fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 379fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 380fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 381fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 382fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = mFrameSize - getHeaderLength(); 383fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 384fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData; 385fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 386fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 387fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersize_t ID3::Iterator::getHeaderLength() const { 388fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 389fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 6; 39083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else if (mParent.mVersion == ID3_V2_3) { 391fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 10; 39283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 39383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 39483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return 0; 395fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 396fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 397fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 398fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::findFrame() { 399fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (;;) { 400fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = NULL; 401fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 0; 402fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 403fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 404fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 6 > mParent.mSize) { 405fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 406fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 407fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 408fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 409fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 410fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 411fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 412fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 413fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber (mParent.mData[mOffset + 3] << 16) 414fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | (mParent.mData[mOffset + 4] << 8) 415fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | mParent.mData[mOffset + 5]; 416fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 417fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize += 6; 418fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 419fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 420fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 421fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 6); 422fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 423fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 424fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 425fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 6]; 426fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 427fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 428fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 429fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 430fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 431fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[4]; 432fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 3); 433fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[3] = '\0'; 434fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 435fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 436fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 437fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 43883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else if (mParent.mVersion == ID3_V2_3) { 439fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 10 > mParent.mSize) { 440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 441fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 442fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 443fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 444fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 445fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 446fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 447fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 10 + U32_AT(&mParent.mData[mOffset + 4]); 448fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 449fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 450fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 451fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 10); 452fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 453fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 454fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 455fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 10]; 456fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 457fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 458fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 459fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 460fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 461fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[5]; 462fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 4); 463fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[4] = '\0'; 464fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 465fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 466fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 467fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 46883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 46983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 47083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 47183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset >= mParent.mSize) { 47283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 47383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 47483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 47583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameData = &mParent.mData[mOffset]; 47683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 47783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 47883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 47983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 48083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 48183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 48283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 48383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 48483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 4; 48583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 48683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 48783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1) { 48883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 48983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 49083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 29; 49183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 49283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 49483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 49583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 49783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 49883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 50083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"Should not be here, invalid offset."); 50183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 50283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 50383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 50483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (!mID) { 50583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 50683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 50783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 50883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber String8 id; 50983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber getID(&id); 51083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 51183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (id == mID) { 51283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 51383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 514fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 515fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 516fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 517fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 518fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 519fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 520fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic size_t StringSize(const uint8_t *start, uint8_t encoding) { 521fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (encoding== 0x00) { 522fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // ISO 8859-1 523fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return strlen((const char *)start) + 1; 524fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 525fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 526fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 527fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = 0; 528fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (start[n] != '\0' || start[n + 1] != '\0') { 529fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber n += 2; 530fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 531fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 532fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return n; 533fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 534fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 535fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst void * 536fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::getAlbumArt(size_t *length, String8 *mime) const { 537fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 538fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo(""); 539fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 540fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber Iterator it(*this, mVersion == ID3_V2_3 ? "APIC" : "PIC"); 541fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 542fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (!it.done()) { 543fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size; 544fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data = it.getData(&size); 545fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 546fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mVersion == ID3_V2_3) { 547fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 548fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo((const char *)&data[1]); 549fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t mimeLen = strlen((const char *)&data[1]) + 1; 550fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 551fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[1 + mimeLen]; 552fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 553fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 554fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 555fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 556fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 557fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 558fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 559fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 560fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[2 + mimeLen], encoding); 561fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 562fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 2 - mimeLen - descLen; 563fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 564fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[2 + mimeLen + descLen]; 565fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 566fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 567fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 568fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&data[1], "PNG", 3)) { 569fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/png"); 570fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "JPG", 3)) { 571fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/jpeg"); 572fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "-->", 3)) { 573fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("text/plain"); 574fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 575fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 576fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 577fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 578fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 579fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[4]; 580fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 581fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 582fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 583fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 584fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 585fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 586fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 587fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[5], encoding); 588fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 589fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 5 - descLen; 590fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 591fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[5 + descLen]; 592fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 593fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 594fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 595fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 596fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 597fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 59883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huberbool ID3::parseV1(const sp<DataSource> &source) { 59983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber const size_t V1_TAG_SIZE = 128; 60083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 60183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber off_t size; 60283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->getSize(&size) != OK || size < (off_t)V1_TAG_SIZE) { 60383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 60483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 60583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 60683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = (uint8_t *)malloc(V1_TAG_SIZE); 60783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->readAt(size - V1_TAG_SIZE, mData, V1_TAG_SIZE) 60883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber != (ssize_t)V1_TAG_SIZE) { 60983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 61083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 61183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 61283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 61383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 61483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 61583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (memcmp("TAG", mData, 3)) { 61683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 61783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 61883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 61983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 62083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 62183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 62283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mSize = V1_TAG_SIZE; 62383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFirstFrameOffset = 3; 62483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 62583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mData[V1_TAG_SIZE - 3] != 0) { 62683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1; 62783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 62883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1_1; 62983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 63083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 63183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return true; 63283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber} 633fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 634fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} // namespace android 635