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 23d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/DataSource.h> 24f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 25607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.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 332a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissenstruct MemorySource : public DataSourceBase { 3414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber MemorySource(const uint8_t *data, size_t size) 3514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber : mData(data), 3614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mSize(size) { 3714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 3814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 3914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber virtual status_t initCheck() const { 4014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return OK; 4114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 4214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 4314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber virtual ssize_t readAt(off64_t offset, void *data, size_t size) { 44b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross off64_t available = (offset >= (off64_t)mSize) ? 0ll : mSize - offset; 4514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 46b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross size_t copy = (available > (off64_t)size) ? size : available; 4714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber memcpy(data, mData + offset, copy); 4814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 4914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber return copy; 5014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 5114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberprivate: 5314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber const uint8_t *mData; 5414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber size_t mSize; 5514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 5614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(MemorySource); 5714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}; 5814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 592a243f08193fe9ff1afe018e9953f01c44ced9deMarco NelissenID3::ID3(DataSourceBase *source, bool ignoreV1, off64_t offset) 60fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mIsValid(false), 61fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData(NULL), 62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize(0), 63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset(0), 6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mVersion(ID3_UNKNOWN), 6514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mRawSize(0) { 66328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mIsValid = parseV2(source, offset); 6714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 6814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (!mIsValid && !ignoreV1) { 6914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mIsValid = parseV1(source); 7014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber } 7114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber} 7214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 7314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas HuberID3::ID3(const uint8_t *data, size_t size, bool ignoreV1) 7414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber : mIsValid(false), 7514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mData(NULL), 7614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mSize(0), 7714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mFirstFrameOffset(0), 7814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mVersion(ID3_UNKNOWN), 7914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mRawSize(0) { 802a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen MemorySource *source = new (std::nothrow) MemorySource(data, size); 81c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick 82c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick if (source == NULL) 83c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick return; 8414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 85328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mIsValid = parseV2(source, 0); 8683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 87ffd6ffc5429c45577fd8e9f8fa90e79bb91b8a84Dylan Powers if (!mIsValid && !ignoreV1) { 8883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mIsValid = parseV1(source); 8983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 902a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen delete source; 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::~ID3() { 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData) { 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mData); 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = NULL; 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::isValid() const { 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mIsValid; 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 104fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Version ID3::version() const { 105fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mVersion; 106fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 107fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 108bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber// static 109bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberbool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) { 110bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = 0; 111bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber for (int32_t i = 0; i < 4; ++i) { 112bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoded[i] & 0x80) { 113bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 114bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 115bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 116bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = ((*x) << 7) | encoded[i]; 117bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 118bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 119bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return true; 120bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber} 121bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 1222a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissenbool ID3::parseV2(DataSourceBase *source, off64_t offset) { 123bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberstruct id3_header { 124bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char id[3]; 125bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_major; 126bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_minor; 127bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t flags; 128bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t enc_size[4]; 129fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 130fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 131fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id3_header header; 132fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt( 133328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 134fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 135fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (memcmp(header.id, "ID3", 3)) { 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 140fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 141fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 0xff || header.version_minor == 0xff) { 142fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 143fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 144fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 145fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 146fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x3f) { 147fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 2 high bits, if any of the lower bits are 148fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 149fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 150fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 151fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 152fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x40) { 153fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // No compression scheme has been decided yet, ignore the 154fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // tag if compression is indicated. 155fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 156fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 157fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 158fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (header.version_major == 3) { 159fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x1f) { 160fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 3 high bits, if any of the lower bits are 161fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 162fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 163fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 164bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4) { 165bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (header.flags & 0x0f) { 166bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // The lower 4 bits are undefined in this spec. 167bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 168bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 169fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 170fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 171fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 172fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 173bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t size; 174bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(header.enc_size, &size)) { 175bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 176fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 177fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 17865997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber if (size > kMaxMetadataSize) { 179b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("skipping huge ID3 metadata of size %zu", size); 18065997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber return false; 18165997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber } 18265997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 183fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = (uint8_t *)malloc(size); 184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 185fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData == NULL) { 186fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 187fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 188fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 189fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize = size; 19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mRawSize = mSize + sizeof(header); 191fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 192328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) { 193ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 194ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 195ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 196fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 197fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 198fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 199ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (header.version_major == 4) { 200428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber void *copy = malloc(size); 201b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (copy == NULL) { 202b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia free(mData); 203b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia mData = NULL; 204b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, no more memory"); 205b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia return false; 206b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 207b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia 208428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber memcpy(copy, mData, size); 209428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 210428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber bool success = removeUnsynchronizationV2_4(false /* iTunesHack */); 211428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (!success) { 212428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber memcpy(mData, copy, size); 213428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber mSize = size; 214428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 215428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber success = removeUnsynchronizationV2_4(true /* iTunesHack */); 216428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 217428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (success) { 2183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Had to apply the iTunes hack to parse this ID3 tag"); 219428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } 220428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } 221428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 222428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber free(copy); 223428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber copy = NULL; 224428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 225428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (!success) { 226ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 227ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 228ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 229ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 230ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 231ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } else if (header.flags & 0x80) { 2323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("removing unsynchronization"); 233ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber removeUnsynchronization(); 235fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 236fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 237fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = 0; 238fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 3 && (header.flags & 0x40)) { 239fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Version 2.3 has an optional extended header. 240fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 241fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSize < 4) { 24283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 24383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 24483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 245fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 246fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 247fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 248b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia size_t extendedHeaderSize = U32_AT(&mData[0]); 249b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (extendedHeaderSize > SIZE_MAX - 4) { 250b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia free(mData); 251b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia mData = NULL; 252b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, extendedHeaderSize is too large"); 253b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia return false; 254b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 255b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia extendedHeaderSize += 4; 256fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 257fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize > mSize) { 25883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 25983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 26083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 261fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 262fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 263fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 264fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = extendedHeaderSize; 265fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 266fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint16_t extendedFlags = 0; 267fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 6) { 268fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber extendedFlags = U16_AT(&mData[4]); 269fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 270fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 10) { 271fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t paddingSize = U32_AT(&mData[6]); 272fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 273b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (paddingSize > SIZE_MAX - mFirstFrameOffset) { 274b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, paddingSize is too large"); 275b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 276b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (paddingSize > mSize - mFirstFrameOffset) { 27783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 27883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 27983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 280fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 281fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 282fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 283fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize -= paddingSize; 284fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 285fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 286fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedFlags & 0x8000) { 2873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("have crc"); 288fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 289fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 290bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4 && (header.flags & 0x40)) { 291bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // Version 2.4 has an optional extended header, that's different 292bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // from Version 2.3's... 293bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 294bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mSize < 4) { 295bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 296bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 297bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 298bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 299bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 300bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 301bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t ext_size; 302bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(mData, &ext_size)) { 303bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 304bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 305bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 306bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 307bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 308bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 309bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (ext_size < 6 || ext_size > mSize) { 310bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 311bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 312bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 313bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 314bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 315bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 316bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mFirstFrameOffset = ext_size; 317fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 318fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 319fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 320fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_2; 321bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 3) { 322fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_3; 323bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 324bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber CHECK_EQ(header.version_major, 4); 325bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mVersion = ID3_V2_4; 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 330fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 331fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::removeUnsynchronization() { 332f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih 333f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih // This file has "unsynchronization", so we have to replace occurrences 334f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih // of 0xff 0x00 with just 0xff in order to get the real data. 335f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih 336f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih size_t writeOffset = 1; 337f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih for (size_t readOffset = 1; readOffset < mSize; ++readOffset) { 338f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) { 339f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih continue; 340fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 341f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih // Only move data if there's actually something to move. 342f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih // This handles the special case of the data being only [0xff, 0x00] 343f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih // which should be converted to just 0xff if unsynchronization is on. 344f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih mData[writeOffset++] = mData[readOffset]; 345fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 346f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih 347f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih if (writeOffset < mSize) { 348f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih mSize = writeOffset; 349f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih } 350f9d87cc850a589b9b0cc3658cf222187822bcc00Robert Shih 351fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 352fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 353ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huberstatic void WriteSyncsafeInteger(uint8_t *dst, size_t x) { 354ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i < 4; ++i) { 355ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dst[3 - i] = (x & 0x7f); 356ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber x >>= 7; 357ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 358ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 359ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 360428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huberbool ID3::removeUnsynchronizationV2_4(bool iTunesHack) { 361ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t oldSize = mSize; 362ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 363ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t offset = 0; 36409da86913ca97d7a818a8917b6601527e5e18a24Wei Jia while (mSize >= 10 && offset <= mSize - 10) { 365ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 366ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber break; 367ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 368ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 369ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t dataSize; 370428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (iTunesHack) { 371428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber dataSize = U32_AT(&mData[offset + 4]); 372428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 373ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 374ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 375ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 37609da86913ca97d7a818a8917b6601527e5e18a24Wei Jia if (dataSize > mSize - 10 - offset) { 377ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 378ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 379ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 380ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t flags = U16_AT(&mData[offset + 8]); 381ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t prevFlags = flags; 382ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 383ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags & 1) { 384ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Strip data length indicator 385ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 386c37f7f6fa0cb7f55cdc5b2d4ccbf2c87c3bc6c3bNeel Mehta if (mSize < 14 || mSize - 14 < offset || dataSize < 4) { 38709da86913ca97d7a818a8917b6601527e5e18a24Wei Jia return false; 38809da86913ca97d7a818a8917b6601527e5e18a24Wei Jia } 389ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); 390ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mSize -= 4; 391ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dataSize -= 4; 392ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 393ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber flags &= ~1; 394ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 395ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 396d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen if ((flags & 2) && (dataSize >= 2)) { 39772a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // This file has "unsynchronization", so we have to replace occurrences 39872a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // of 0xff 0x00 with just 0xff in order to get the real data. 399ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 40072a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen size_t readOffset = offset + 11; 40172a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen size_t writeOffset = offset + 11; 402ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i + 1 < dataSize; ++i) { 40372a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen if (mData[readOffset - 1] == 0xff 40472a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen && mData[readOffset] == 0x00) { 40572a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen ++readOffset; 406ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --mSize; 407ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --dataSize; 408ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 4093e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen if (i + 1 < dataSize) { 4103e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen // Only move data if there's actually something to move. 4113e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen // This handles the special case of the data being only [0xff, 0x00] 4123e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen // which should be converted to just 0xff if unsynchronization is on. 4133e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen mData[writeOffset++] = mData[readOffset++]; 4143e70296461c5f260988ab21854a6f43fdafea764Marco Nelissen } 415ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 41672a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // move the remaining data following this frame 417d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen if (readOffset <= oldSize) { 418d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset); 419d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen } else { 420d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen ALOGE("b/34618607 (%zu %zu %zu %zu)", readOffset, writeOffset, oldSize, mSize); 421d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen android_errorWriteLog(0x534e4554, "34618607"); 422d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen } 423ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 424ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 425d1c19c57f66d91ea8033c8fa6510a8760a6e663bMarco Nelissen flags &= ~2; 426428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (flags != prevFlags || iTunesHack) { 427ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber WriteSyncsafeInteger(&mData[offset + 4], dataSize); 428ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 8] = flags >> 8; 429ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 9] = flags & 0xff; 430ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 431ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 432ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber offset += 10 + dataSize; 433ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 434ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 435ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memset(&mData[mSize], 0, oldSize - mSize); 436ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 437ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return true; 438ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 439ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::Iterator(const ID3 &parent, const char *id) 441fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParent(parent), 442fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID(NULL), 443fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset(mParent.mFirstFrameOffset), 444fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData(NULL), 445fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize(0) { 446fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (id) { 447fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = strdup(id); 448fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 449fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 450fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 451fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 452fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 453fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::~Iterator() { 454fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mID) { 455fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mID); 456fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = NULL; 457fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 458fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 459fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 460fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::Iterator::done() const { 461fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData == NULL; 462fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 463fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 464fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::next() { 465fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 466fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 467fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 468fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 469fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 470fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 471fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 472fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 473fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 474fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getID(String8 *id) const { 475fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 476fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 477fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 478fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 479fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 480fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 481fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 482fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 3); 483bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 484fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 4); 48583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 48683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 48783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 48883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 48983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 49083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TT2"); 49183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 49383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TP1"); 49483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 49683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TAL"); 49783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 49883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 49983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TYE"); 50083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 50183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 50283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("COM"); 50383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 50483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 50583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TRK"); 50683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 50783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 50883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TCO"); 50983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 51083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 51183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"should not be here."); 51283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 51383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 514fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 515fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 516fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 517fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 518b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// the 2nd argument is used to get the data following the \0 in a comment field 519b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissenvoid ID3::Iterator::getString(String8 *id, String8 *comment) const { 520b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen getstring(id, false); 521b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (comment != NULL) { 522b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen getstring(comment, true); 523b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 524b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen} 525b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen 526b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// comment fields (COM/COMM) contain an initial short descriptor, followed by \0, 527b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// followed by more data. The data following the \0 can be retrieved by setting 528b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// "otherdata" to true. 529b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissenvoid ID3::Iterator::getstring(String8 *id, bool otherdata) const { 530fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 531fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 532b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const uint8_t *frameData = mFrameData; 533b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (frameData == NULL) { 534fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 535fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 536fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 537b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen uint8_t encoding = *frameData; 538b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen 53983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { 54083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset == 126 || mOffset == 127) { 54183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber // Special treatment for the track number and genre. 54283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber char tmp[16]; 5432c9cb62d0160fc4353d89fd9d648725794e7995eGeorge Burgess IV snprintf(tmp, sizeof(tmp), "%d", (int)*frameData); 54483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 54583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo(tmp); 54683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 54783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 54883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 549544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // this is supposed to be ISO-8859-1, but pass it up as-is to the caller, who will figure 550544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // out the real encoding 551544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo((const char*)frameData, mFrameSize); 55283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 55383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 55483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 5553bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia if (mFrameSize < getHeaderLength() + 1) { 5563bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia return; 5573bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia } 558fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = mFrameSize - getHeaderLength() - 1; 559b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (otherdata) { 560e1e791727f709c7ab54d47b9cd46d4326a02e913Roger if (n < 5) { 561e1e791727f709c7ab54d47b9cd46d4326a02e913Roger return; 562e1e791727f709c7ab54d47b9cd46d4326a02e913Roger } 563b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen // skip past the encoding, language, and the 0 separator 564b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen frameData += 4; 565b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen int32_t i = n - 4; 566b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen while(--i >= 0 && *++frameData != 0) ; 567b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen int skipped = (frameData - mFrameData); 56814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (skipped >= (int)n) { 569b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen return; 570b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 571b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen n -= skipped; 572b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 573fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 574d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (n <= 0) { 575d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick return; 576d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } 577d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick 578b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (encoding == 0x00) { 579544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly ISO 8859-1 580544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo((const char*)frameData + 1, n); 581b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } else if (encoding == 0x03) { 582544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly UTF-8 583b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen id->setTo((const char *)(frameData + 1), n); 584b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } else if (encoding == 0x02) { 585544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly UTF-16 BE, no byte order mark. 586bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // API wants number of characters, not number of bytes... 587bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber int len = n / 2; 588b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const char16_t *framedata = (const char16_t *) (frameData + 1); 589bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char16_t *framedatacopy = NULL; 590bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#if BYTE_ORDER == LITTLE_ENDIAN 591c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick if (len > 0) { 592c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick framedatacopy = new (std::nothrow) char16_t[len]; 593d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (framedatacopy == NULL) { 594d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick return; 595c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick } 596d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick for (int i = 0; i < len; i++) { 597d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedatacopy[i] = bswap_16(framedata[i]); 598d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } 599d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedata = framedatacopy; 600bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 601bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#endif 602bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber id->setTo(framedata, len); 603bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (framedatacopy != NULL) { 604bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber delete[] framedatacopy; 605bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 606544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } else if (encoding == 0x01) { 607fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 60808e7eb983fcb9860a574e964ff905f75aab88d2fAndreas Huber // API wants number of characters, not number of bytes... 6095a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen int len = n / 2; 6103762e0615273f25b059556d5b5f65102e9c55c35Marco Nelissen if (len == 0) { 6113762e0615273f25b059556d5b5f65102e9c55c35Marco Nelissen return; 6123762e0615273f25b059556d5b5f65102e9c55c35Marco Nelissen } 613b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const char16_t *framedata = (const char16_t *) (frameData + 1); 6145a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen char16_t *framedatacopy = NULL; 6155a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfffe) { 616d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick // endianness marker != host endianness, convert & skip 617d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (len <= 1) { 618d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick return; // nothing after the marker 619d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } 620d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedatacopy = new (std::nothrow) char16_t[len]; 621d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (framedatacopy == NULL) { 622d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick return; 623d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } 624d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick for (int i = 0; i < len; i++) { 625d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedatacopy[i] = bswap_16(framedata[i]); 626d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } 627d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedata = framedatacopy; 628d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick // and skip over the marker 629d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick framedata++; 630d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick len--; 631d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } else if (*framedata == 0xfeff) { 632d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick // endianness marker == host endianness, skip it 633d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (len <= 1) { 634d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick return; // nothing after the marker 6355a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 6365a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata++; 6375a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen len--; 6385a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 639544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen 640544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // check if the resulting data consists entirely of 8-bit values 641544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen bool eightBit = true; 642544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen for (int i = 0; i < len; i++) { 643544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen if (framedata[i] > 0xff) { 644544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen eightBit = false; 645544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen break; 646544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 647544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 648d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick if (eightBit) { 649544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // collapse to 8 bit, then let the media scanner client figure out the real encoding 650c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick char *frame8 = new (std::nothrow) char[len]; 651c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick if (frame8 != NULL) { 652c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick for (int i = 0; i < len; i++) { 653c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick frame8[i] = framedata[i]; 654c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick } 655c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick id->setTo(frame8, len); 656c54432ae4f3627b1003fa251616b0103dad8b5d0Ray Essick delete [] frame8; 657d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick } else { 658d2b126291b7cc302ebcef8249bef7813e0dd77dcRay Essick id->setTo(framedata, len); 659544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 660544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } else { 661544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo(framedata, len); 662544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 663544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen 6645a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (framedatacopy != NULL) { 6655a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen delete[] framedatacopy; 6665a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 667fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 668fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 669fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 670fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst uint8_t *ID3::Iterator::getData(size_t *length) const { 671fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 672fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 673fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 674fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 675fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 676fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 677be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake // Prevent integer underflow 678be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake if (mFrameSize < getHeaderLength()) { 679be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake return NULL; 680be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake } 681be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake 682fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = mFrameSize - getHeaderLength(); 683fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 684fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData; 685fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 686fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 687fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersize_t ID3::Iterator::getHeaderLength() const { 688fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 689fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 6; 690bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 691fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 10; 69283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 69383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 69483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return 0; 695fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 696fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 697fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 698fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::findFrame() { 699fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (;;) { 700fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = NULL; 701fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 0; 702fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 703fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 704fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 6 > mParent.mSize) { 705fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 706fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 707fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 708fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 709fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 710fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 711fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 712fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 713fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber (mParent.mData[mOffset + 3] << 16) 714fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | (mParent.mData[mOffset + 4] << 8) 715fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | mParent.mData[mOffset + 5]; 716fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 717ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen if (mFrameSize == 0) { 718ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen return; 719ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen } 720ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen mFrameSize += 6; // add tag id and size field 721fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 722c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow in validation 723c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - mOffset <= mFrameSize) { 724c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 725c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 726c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake 727fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 728b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)", 729b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)6); 730fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 731fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 732fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 733fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 6]; 734fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 735fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 736fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 737fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 738fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 739fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[4]; 740fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 3); 741fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[3] = '\0'; 742fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 743fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 744fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 745fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 746bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 747bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || mParent.mVersion == ID3_V2_4) { 748fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 10 > mParent.mSize) { 749fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 750fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 751fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 752fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 753fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 754fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 755fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 756c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake size_t baseSize = 0; 757bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mParent.mVersion == ID3_V2_4) { 758bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger( 759bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber &mParent.mData[mOffset + 4], &baseSize)) { 760bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return; 761bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 762bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 763bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber baseSize = U32_AT(&mParent.mData[mOffset + 4]); 764bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 765bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 766ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen if (baseSize == 0) { 767ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen return; 768ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen } 769ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen 770c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow when adding 771c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - 10 <= baseSize) { 772c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 773c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 774c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake 775ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen mFrameSize = 10 + baseSize; // add tag id, size field and flags 776fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 777c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow in validation 778c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - mOffset <= mFrameSize) { 779c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 780c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 781fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 782fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 783b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)", 784b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)10); 785fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 786fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 787fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 788bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); 789bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 790ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) 791bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { 792ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Compression or encryption are not supported at this time. 793ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Per-frame unsynchronization and data-length indicator 794ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // have already been taken care of. 795bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 7963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Skipping unsupported frame (compression, encryption " 797bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber "or per-frame unsynchronization flagged"); 798bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 799bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mOffset += mFrameSize; 800bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber continue; 801bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 802bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 803fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 10]; 804fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 805fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 806fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 807fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 808fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 809fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[5]; 810fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 4); 811fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[4] = '\0'; 812fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 813fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 814fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 815fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 81683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 81783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 81883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 81983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset >= mParent.mSize) { 82083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 82183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 82283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 82383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameData = &mParent.mData[mOffset]; 82483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 82583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 82683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 82783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 82883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 82983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 83083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 83183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 83283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 4; 83383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 83483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 83583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1) { 83683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 83783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 83883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 29; 83983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 84083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 84183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 84283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 84383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 84483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 84583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 84683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 84783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 84883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"Should not be here, invalid offset."); 84983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 85083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 85183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 85283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (!mID) { 85383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 85483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 85583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 85683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber String8 id; 85783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber getID(&id); 85883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 85983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (id == mID) { 86083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 86183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 862fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 863fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 864fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 865fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 866fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 867fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 868ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick// return includes terminator; if unterminated, returns > limit 869ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essickstatic size_t StringSize(const uint8_t *start, size_t limit, uint8_t encoding) { 870ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick 871bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoding == 0x00 || encoding == 0x03) { 872bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // ISO 8859-1 or UTF-8 873ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return strnlen((const char *)start, limit) + 1; 874fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 875fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 876fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 877fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = 0; 878ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick while ((n+1 < limit) && (start[n] != '\0' || start[n + 1] != '\0')) { 879fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber n += 2; 880fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 881ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick n += 2; 882ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return n; 883fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 884fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 885fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst void * 886fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::getAlbumArt(size_t *length, String8 *mime) const { 887fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 888fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo(""); 889fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 890bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber Iterator it( 891bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *this, 892bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) ? "APIC" : "PIC"); 893fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 894fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (!it.done()) { 895fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size; 896fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data = it.getData(&size); 897be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake if (!data) { 898be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake return NULL; 899be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake } 900fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 901bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { 902fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 903ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick size_t consumed = 1; 904ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick 905ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick // *always* in an 8-bit encoding 906ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick size_t mimeLen = StringSize(&data[consumed], size - consumed, 0x00); 907ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick if (mimeLen > size - consumed) { 908ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick ALOGW("bogus album art size: mime"); 909ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return NULL; 910ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick } 911ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick mime->setTo((const char *)&data[consumed]); 912ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick consumed += mimeLen; 913fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 914fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 915ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick uint8_t picType = data[consumed]; 916fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 917fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 918fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 919fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 920fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 921fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 922fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 923ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick consumed++; 924ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick if (consumed >= size) { 925ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick ALOGW("bogus album art size: pic type"); 926ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return NULL; 927ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick } 928ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick 929ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick size_t descLen = StringSize(&data[consumed], size - consumed, encoding); 930ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick consumed += descLen; 931fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 932ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick if (consumed >= size) { 933ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick ALOGW("bogus album art size: description"); 934f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen return NULL; 935f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen } 936fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 937ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick *length = size - consumed; 938ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick 939ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return &data[consumed]; 940fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 941fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 942fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 943ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick if (size <= 5) { 944ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return NULL; 945ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick } 946ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick 947fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&data[1], "PNG", 3)) { 948fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/png"); 949fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "JPG", 3)) { 950fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/jpeg"); 951fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "-->", 3)) { 952fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("text/plain"); 953fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 954fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 955fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 956fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 957fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 958fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[4]; 959fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 960fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 961fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 962fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 963fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 964fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 965fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 966ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick size_t descLen = StringSize(&data[5], size - 5, encoding); 967ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick if (descLen > size - 5) { 968ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick return NULL; 969ebb726f940b29174f8dd4bb74d6de39c3f6eb611Ray Essick } 970fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 971fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 5 - descLen; 972fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 973fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[5 + descLen]; 974fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 975fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 976fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 977fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 978fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 979fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 9802a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissenbool ID3::parseV1(DataSourceBase *source) { 98183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber const size_t V1_TAG_SIZE = 128; 98283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 983c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t size; 984c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (source->getSize(&size) != OK || size < (off64_t)V1_TAG_SIZE) { 98583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 98683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 98783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 98883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = (uint8_t *)malloc(V1_TAG_SIZE); 98983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->readAt(size - V1_TAG_SIZE, mData, V1_TAG_SIZE) 99083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber != (ssize_t)V1_TAG_SIZE) { 99183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 99283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 99383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 99483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 99583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 99683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 99783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (memcmp("TAG", mData, 3)) { 99883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 99983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 100083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 100183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 100283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 100383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 100483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mSize = V1_TAG_SIZE; 100583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFirstFrameOffset = 3; 100683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 100783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mData[V1_TAG_SIZE - 3] != 0) { 100883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1; 100983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 101083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1_1; 101183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 101283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 101383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return true; 101483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber} 1015fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 1016fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} // namespace android 1017