ID3.cpp revision fc9ba09e3bb368f823d473f5e2bb9aa32dba6289
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> 27fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 28fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubernamespace android { 29fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 30fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::ID3(const sp<DataSource> &source) 31fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mIsValid(false), 32fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData(NULL), 33fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize(0), 34fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset(0), 35fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion(ID3_UNKNOWN) { 36fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mIsValid = parse(source); 37fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 38fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 39fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::~ID3() { 40fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData) { 41fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mData); 42fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = NULL; 43fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 44fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 45fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 46fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::isValid() const { 47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mIsValid; 48fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 49fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 50fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Version ID3::version() const { 51fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mVersion; 52fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 53fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 54fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::parse(const sp<DataSource> &source) { 55fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber struct id3_header { 56fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[3]; 57fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t version_major; 58fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t version_minor; 59fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t flags; 60fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t enc_size[4]; 61fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id3_header header; 64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt( 65fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 66fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 67fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 68fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 69fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (memcmp(header.id, "ID3", 3)) { 70fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 71fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 72fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 73fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 0xff || header.version_minor == 0xff) { 74fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 75fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 76fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 77fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 78fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x3f) { 79fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 2 high bits, if any of the lower bits are 80fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 81fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 82fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 83fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 84fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x40) { 85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // No compression scheme has been decided yet, ignore the 86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // tag if compression is indicated. 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (header.version_major == 3) { 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x1f) { 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 3 high bits, if any of the lower bits are 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size = 0; 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (int32_t i = 0; i < 4; ++i) { 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.enc_size[i] & 0x80) { 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 104fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 105fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 106fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size = (size << 7) | header.enc_size[i]; 107fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 108fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 109fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = (uint8_t *)malloc(size); 110fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 111fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData == NULL) { 112fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 113fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 114fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 115fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize = size; 116fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 117fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { 118fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 119fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 120fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 121fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x80) { 122fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGI("removing unsynchronization"); 123fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber removeUnsynchronization(); 124fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 125fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 126fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = 0; 127fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 3 && (header.flags & 0x40)) { 128fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Version 2.3 has an optional extended header. 129fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 130fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSize < 4) { 131fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 132fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 133fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 134fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t extendedHeaderSize = U32_AT(&mData[0]) + 4; 135fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize > mSize) { 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 140fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = extendedHeaderSize; 141fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 142fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint16_t extendedFlags = 0; 143fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 6) { 144fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber extendedFlags = U16_AT(&mData[4]); 145fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 146fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 10) { 147fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t paddingSize = U32_AT(&mData[6]); 148fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 149fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFirstFrameOffset + paddingSize > mSize) { 150fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 151fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 152fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 153fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize -= paddingSize; 154fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 155fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 156fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedFlags & 0x8000) { 157fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGI("have crc"); 158fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 159fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 160fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 161fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 162fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 163fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_2; 164fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 165fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber CHECK_EQ(header.version_major, 3); 166fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_3; 167fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 168fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 169fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 170fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 171fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 172fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::removeUnsynchronization() { 173fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i + 1 < mSize; ++i) { 174fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData[i] == 0xff && mData[i + 1] == 0x00) { 175fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2); 176fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber --mSize; 177fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 178fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 179fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 180fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 181fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::Iterator(const ID3 &parent, const char *id) 182fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParent(parent), 183fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID(NULL), 184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset(mParent.mFirstFrameOffset), 185fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData(NULL), 186fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize(0) { 187fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (id) { 188fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = strdup(id); 189fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 190fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 191fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 192fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 193fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 194fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::~Iterator() { 195fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mID) { 196fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mID); 197fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = NULL; 198fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 199fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 200fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 201fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::Iterator::done() const { 202fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData == NULL; 203fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 204fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 205fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::next() { 206fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 207fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 208fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 209fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 210fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 211fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 212fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 213fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 214fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 215fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getID(String8 *id) const { 216fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 217fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 218fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 219fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 220fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 221fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 222fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 223fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 3); 224fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 225fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber CHECK_EQ(mParent.mVersion, ID3_V2_3); 226fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 4); 227fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 228fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 229fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 230fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic void convertISO8859ToString8( 231fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data, size_t size, 232fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber String8 *s) { 233fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t utf8len = 0; 234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 235fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (data[i] < 0x80) { 236fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ++utf8len; 237fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 238fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber utf8len += 2; 239fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 240fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 241fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 242fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (utf8len == size) { 243fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Only ASCII characters present. 244fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 245fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo((const char *)data, size); 246fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 247fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 248fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 249fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *tmp = new char[utf8len]; 250fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char *ptr = tmp; 251fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < size; ++i) { 252fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (data[i] < 0x80) { 253fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 254fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (data[i] < 0xc0) { 255fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc2; 256fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i]; 257fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 258fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = 0xc3; 259fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *ptr++ = data[i] - 64; 260fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 261fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 262fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 263fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber s->setTo(tmp, utf8len); 264fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 265fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber delete[] tmp; 266fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber tmp = NULL; 267fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 268fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 269fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getString(String8 *id) const { 270fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 271fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 272fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 273fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 274fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 275fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 276fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = mFrameSize - getHeaderLength() - 1; 277fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 278fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (*mFrameData == 0x00) { 279fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // ISO 8859-1 280fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber convertISO8859ToString8(mFrameData + 1, n, id); 281fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 282fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 283fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char16_t *)(mFrameData + 1), n); 284fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 285fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 286fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 287fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst uint8_t *ID3::Iterator::getData(size_t *length) const { 288fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 289fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 290fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 291fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 292fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 293fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 294fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = mFrameSize - getHeaderLength(); 295fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 296fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData; 297fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 298fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 299fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersize_t ID3::Iterator::getHeaderLength() const { 300fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 301fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 6; 302fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 303fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber CHECK_EQ(mParent.mVersion, ID3_V2_3); 304fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 10; 305fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 306fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 307fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 308fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::findFrame() { 309fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (;;) { 310fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = NULL; 311fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 0; 312fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 313fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 314fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 6 > mParent.mSize) { 315fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 316fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 317fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 318fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 319fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 320fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 321fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 322fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 323fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber (mParent.mData[mOffset + 3] << 16) 324fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | (mParent.mData[mOffset + 4] << 8) 325fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | mParent.mData[mOffset + 5]; 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize += 6; 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 330fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 331fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 6); 332fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 333fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 334fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 335fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 6]; 336fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 337fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 338fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 339fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 340fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 341fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[4]; 342fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 3); 343fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[3] = '\0'; 344fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 345fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 346fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 347fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 348fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 349fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber CHECK_EQ(mParent.mVersion, ID3_V2_3); 350fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 351fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 10 > mParent.mSize) { 352fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 353fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 354fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 355fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 356fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 357fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 358fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 359fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 10 + U32_AT(&mParent.mData[mOffset + 4]); 360fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 361fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 362fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber LOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)", 363fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset, mFrameSize, mParent.mSize - mOffset - 10); 364fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 365fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 366fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 367fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 10]; 368fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 369fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 370fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 371fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 372fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 373fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[5]; 374fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 4); 375fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[4] = '\0'; 376fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 377fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 378fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 379fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 380fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 381fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 382fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 383fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 384fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 385fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 386fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic size_t StringSize(const uint8_t *start, uint8_t encoding) { 387fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (encoding== 0x00) { 388fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // ISO 8859-1 389fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return strlen((const char *)start) + 1; 390fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 391fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 392fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 393fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = 0; 394fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (start[n] != '\0' || start[n + 1] != '\0') { 395fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber n += 2; 396fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 397fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 398fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return n; 399fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 400fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 401fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst void * 402fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::getAlbumArt(size_t *length, String8 *mime) const { 403fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 404fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo(""); 405fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 406fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber Iterator it(*this, mVersion == ID3_V2_3 ? "APIC" : "PIC"); 407fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 408fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (!it.done()) { 409fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size; 410fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data = it.getData(&size); 411fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 412fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mVersion == ID3_V2_3) { 413fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 414fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo((const char *)&data[1]); 415fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t mimeLen = strlen((const char *)&data[1]) + 1; 416fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 417fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[1 + mimeLen]; 418fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 419fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 420fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 421fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 422fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 423fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 424fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 425fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 426fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[2 + mimeLen], encoding); 427fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 428fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 2 - mimeLen - descLen; 429fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 430fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[2 + mimeLen + descLen]; 431fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 432fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 433fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 434fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&data[1], "PNG", 3)) { 435fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/png"); 436fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "JPG", 3)) { 437fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/jpeg"); 438fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "-->", 3)) { 439fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("text/plain"); 440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 441fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 442fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 443fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 444fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 445fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[4]; 446fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 447fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 448fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 449fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 450fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 451fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 452fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 453fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[5], encoding); 454fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 455fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 5 - descLen; 456fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 457fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[5 + descLen]; 458fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 459fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 460fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 461fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 462fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 463fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 464fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 465fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} // namespace android 466