ID3.cpp revision e1e791727f709c7ab54d47b9cd46d4326a02e913
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 23f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 24fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/DataSource.h> 25fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <media/stagefright/Utils.h> 26fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <utils/String8.h> 27569e7f1b1444194d1aca5a0b23de154565ba12daMarco Nelissen#include <byteswap.h> 28fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 29fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubernamespace android { 30fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 3165997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huberstatic const size_t kMaxMetadataSize = 3 * 1024 * 1024; 3265997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 3314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct MemorySource : public DataSource { 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 59328abde67f57c026ac44e927f9244c40832499c8Oscar RydhéID3::ID3(const sp<DataSource> &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) { 8014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber sp<MemorySource> source = new MemorySource(data, size); 8114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 82328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé mIsValid = parseV2(source, 0); 8383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 84ffd6ffc5429c45577fd8e9f8fa90e79bb91b8a84Dylan Powers if (!mIsValid && !ignoreV1) { 8583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mIsValid = parseV1(source); 8683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::~ID3() { 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData) { 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mData); 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = NULL; 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 96fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::isValid() const { 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mIsValid; 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Version ID3::version() const { 101fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mVersion; 102fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 103fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 104bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber// static 105bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberbool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) { 106bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = 0; 107bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber for (int32_t i = 0; i < 4; ++i) { 108bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoded[i] & 0x80) { 109bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 110bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 111bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 112bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *x = ((*x) << 7) | encoded[i]; 113bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 114bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 115bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return true; 116bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber} 117bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 118328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhébool ID3::parseV2(const sp<DataSource> &source, off64_t offset) { 119bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huberstruct id3_header { 120bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char id[3]; 121bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_major; 122bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t version_minor; 123bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t flags; 124bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint8_t enc_size[4]; 125fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 126fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 127fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id3_header header; 128fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (source->readAt( 129328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) { 130fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 131fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 132fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 133fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (memcmp(header.id, "ID3", 3)) { 134fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 135fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 0xff || header.version_minor == 0xff) { 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 140fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 141fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 142fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x3f) { 143fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 2 high bits, if any of the lower bits are 144fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 145fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 146fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 147fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 148fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x40) { 149fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // No compression scheme has been decided yet, ignore the 150fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // tag if compression is indicated. 151fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 152fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 153fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 154fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (header.version_major == 3) { 155fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.flags & 0x1f) { 156fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // We only support the 3 high bits, if any of the lower bits are 157fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // set, we cannot guarantee to understand the tag format. 158fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 159fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 160bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4) { 161bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (header.flags & 0x0f) { 162bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // The lower 4 bits are undefined in this spec. 163bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 164bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 165fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 166fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 167fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 168fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 169bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t size; 170bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(header.enc_size, &size)) { 171bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 172fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 173fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 17465997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber if (size > kMaxMetadataSize) { 175b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGE("skipping huge ID3 metadata of size %zu", size); 17665997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber return false; 17765997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber } 17865997f022fa3f557ba864ecc99a1aa33df54c2dbAndreas Huber 179fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mData = (uint8_t *)malloc(size); 180fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 181fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData == NULL) { 182fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 183fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 184fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 185fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize = size; 18614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber mRawSize = mSize + sizeof(header); 187fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 188328abde67f57c026ac44e927f9244c40832499c8Oscar Rydhé if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) { 189ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 190ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 191ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 192fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 193fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 194fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 195ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (header.version_major == 4) { 196428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber void *copy = malloc(size); 197b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (copy == NULL) { 198b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia free(mData); 199b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia mData = NULL; 200b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, no more memory"); 201b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia return false; 202b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 203b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia 204428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber memcpy(copy, mData, size); 205428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 206428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber bool success = removeUnsynchronizationV2_4(false /* iTunesHack */); 207428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (!success) { 208428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber memcpy(mData, copy, size); 209428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber mSize = size; 210428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 211428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber success = removeUnsynchronizationV2_4(true /* iTunesHack */); 212428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 213428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (success) { 2143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Had to apply the iTunes hack to parse this ID3 tag"); 215428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } 216428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } 217428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 218428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber free(copy); 219428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber copy = NULL; 220428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber 221428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (!success) { 222ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber free(mData); 223ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData = NULL; 224ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 225ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 226ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 227ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } else if (header.flags & 0x80) { 2283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("removing unsynchronization"); 229ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 230fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber removeUnsynchronization(); 231fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 232fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 233fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = 0; 234fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 3 && (header.flags & 0x40)) { 235fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Version 2.3 has an optional extended header. 236fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 237fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mSize < 4) { 23883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 23983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 24083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 241fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 242fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 243fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 244b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia size_t extendedHeaderSize = U32_AT(&mData[0]); 245b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (extendedHeaderSize > SIZE_MAX - 4) { 246b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia free(mData); 247b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia mData = NULL; 248b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, extendedHeaderSize is too large"); 249b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia return false; 250b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 251b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia extendedHeaderSize += 4; 252fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 253fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize > mSize) { 25483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 25583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 25683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 257fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 258fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 259fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 260fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFirstFrameOffset = extendedHeaderSize; 261fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 262fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint16_t extendedFlags = 0; 263fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 6) { 264fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber extendedFlags = U16_AT(&mData[4]); 265fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 266fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedHeaderSize >= 10) { 267fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t paddingSize = U32_AT(&mData[6]); 268fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 269b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (paddingSize > SIZE_MAX - mFirstFrameOffset) { 270b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia ALOGE("b/24623447, paddingSize is too large"); 271b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia } 272b3694ff5a5bcecd4b6cedca156f6effb55bbf4caWei Jia if (paddingSize > mSize - mFirstFrameOffset) { 27383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 27483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 27583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 276fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 277fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 278fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 279fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mSize -= paddingSize; 280fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 281fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 282fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (extendedFlags & 0x8000) { 2833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("have crc"); 284fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 285fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 286bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 4 && (header.flags & 0x40)) { 287bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // Version 2.4 has an optional extended header, that's different 288bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // from Version 2.3's... 289bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 290bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mSize < 4) { 291bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 292bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 293bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 294bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 295bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 296bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 297bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber size_t ext_size; 298bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger(mData, &ext_size)) { 299bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 300bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 301bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 302bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 303bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 304bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 305bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (ext_size < 6 || ext_size > mSize) { 306bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber free(mData); 307bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mData = NULL; 308bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 309bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return false; 310bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 311bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 312bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mFirstFrameOffset = ext_size; 313fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 314fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 315fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (header.version_major == 2) { 316fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_2; 317bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (header.version_major == 3) { 318fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mVersion = ID3_V2_3; 319bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 320bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber CHECK_EQ(header.version_major, 4); 321bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mVersion = ID3_V2_4; 322fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 323fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 324fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 325fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 326fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 327fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::removeUnsynchronization() { 328fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i + 1 < mSize; ++i) { 329fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mData[i] == 0xff && mData[i + 1] == 0x00) { 330fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2); 331fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber --mSize; 332fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 333fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 334fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 335fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 336ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huberstatic void WriteSyncsafeInteger(uint8_t *dst, size_t x) { 337ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i < 4; ++i) { 338ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dst[3 - i] = (x & 0x7f); 339ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber x >>= 7; 340ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 341ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 342ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 343428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huberbool ID3::removeUnsynchronizationV2_4(bool iTunesHack) { 344ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t oldSize = mSize; 345ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 346ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t offset = 0; 34709da86913ca97d7a818a8917b6601527e5e18a24Wei Jia while (mSize >= 10 && offset <= mSize - 10) { 348ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 349ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber break; 350ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 351ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 352ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber size_t dataSize; 353428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (iTunesHack) { 354428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber dataSize = U32_AT(&mData[offset + 4]); 355428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 356ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 357ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 358ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 35909da86913ca97d7a818a8917b6601527e5e18a24Wei Jia if (dataSize > mSize - 10 - offset) { 360ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return false; 361ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 362ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 363ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t flags = U16_AT(&mData[offset + 8]); 364ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber uint16_t prevFlags = flags; 365ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 366ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags & 1) { 367ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Strip data length indicator 368ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 369c37f7f6fa0cb7f55cdc5b2d4ccbf2c87c3bc6c3bNeel Mehta if (mSize < 14 || mSize - 14 < offset || dataSize < 4) { 37009da86913ca97d7a818a8917b6601527e5e18a24Wei Jia return false; 37109da86913ca97d7a818a8917b6601527e5e18a24Wei Jia } 372ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14); 373ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mSize -= 4; 374ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber dataSize -= 4; 375ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 376ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber flags &= ~1; 377ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 378ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 379ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if (flags & 2) { 38072a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // This file has "unsynchronization", so we have to replace occurrences 38172a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // of 0xff 0x00 with just 0xff in order to get the real data. 382ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 38372a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen size_t readOffset = offset + 11; 38472a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen size_t writeOffset = offset + 11; 385ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber for (size_t i = 0; i + 1 < dataSize; ++i) { 38672a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen if (mData[readOffset - 1] == 0xff 38772a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen && mData[readOffset] == 0x00) { 38872a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen ++readOffset; 389ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --mSize; 390ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber --dataSize; 391ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 39272a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen mData[writeOffset++] = mData[readOffset++]; 393ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 39472a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen // move the remaining data following this frame 39572a43b68da48890273508cb1c9d646b7d75fc101Marco Nelissen memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset); 396ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 397ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber flags &= ~2; 398ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 399ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 400428d96d5f882d01acb0abb7e1ceb51d4ccc48efaAndreas Huber if (flags != prevFlags || iTunesHack) { 401ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber WriteSyncsafeInteger(&mData[offset + 4], dataSize); 402ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 8] = flags >> 8; 403ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber mData[offset + 9] = flags & 0xff; 404ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 405ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 406ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber offset += 10 + dataSize; 407ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber } 408ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 409ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber memset(&mData[mSize], 0, oldSize - mSize); 410ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 411ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber return true; 412ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber} 413ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber 414fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::Iterator(const ID3 &parent, const char *id) 415fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber : mParent(parent), 416fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID(NULL), 417fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset(mParent.mFirstFrameOffset), 418fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData(NULL), 419fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize(0) { 420fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (id) { 421fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = strdup(id); 422fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 423fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 424fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 425fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 426fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 427fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::Iterator::~Iterator() { 428fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mID) { 429fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber free(mID); 430fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mID = NULL; 431fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 432fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 433fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 434fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberbool ID3::Iterator::done() const { 435fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData == NULL; 436fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 437fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 438fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::next() { 439fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 440fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 441fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 442fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 443fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 444fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 445fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber findFrame(); 446fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 447fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 448fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::getID(String8 *id) const { 449fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 450fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 451fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 452fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 453fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 454fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 455fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 456fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 3); 457bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 458fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo((const char *)&mParent.mData[mOffset], 4); 45983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 46083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 46183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 46283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 46383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 46483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TT2"); 46583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 46683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 46783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TP1"); 46883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 46983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 47083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TAL"); 47183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 47283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 47383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TYE"); 47483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 47583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 47683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("COM"); 47783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 47883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 47983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TRK"); 48083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 48183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 48283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo("TCO"); 48383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 48483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 48583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"should not be here."); 48683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 48783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 488fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 489fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 490fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 491fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 492b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// the 2nd argument is used to get the data following the \0 in a comment field 493b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissenvoid ID3::Iterator::getString(String8 *id, String8 *comment) const { 494b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen getstring(id, false); 495b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (comment != NULL) { 496b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen getstring(comment, true); 497b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 498b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen} 499b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen 500b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// comment fields (COM/COMM) contain an initial short descriptor, followed by \0, 501b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// followed by more data. The data following the \0 can be retrieved by setting 502b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen// "otherdata" to true. 503b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissenvoid ID3::Iterator::getstring(String8 *id, bool otherdata) const { 504fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id->setTo(""); 505fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 506b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const uint8_t *frameData = mFrameData; 507b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (frameData == NULL) { 508fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 509fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 510fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 511b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen uint8_t encoding = *frameData; 512b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen 51383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) { 51483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset == 126 || mOffset == 127) { 51583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber // Special treatment for the track number and genre. 51683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber char tmp[16]; 517b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen sprintf(tmp, "%d", (int)*frameData); 51883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 51983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber id->setTo(tmp); 52083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 52183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 52283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 523544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // this is supposed to be ISO-8859-1, but pass it up as-is to the caller, who will figure 524544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // out the real encoding 525544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo((const char*)frameData, mFrameSize); 52683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 52783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 52883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 5293bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia if (mFrameSize < getHeaderLength() + 1) { 5303bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia return; 5313bf1e0fdf27e1188b8d3574ed073595b8eacb114Wei Jia } 532fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = mFrameSize - getHeaderLength() - 1; 533b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (otherdata) { 534e1e791727f709c7ab54d47b9cd46d4326a02e913Roger if (n < 5) { 535e1e791727f709c7ab54d47b9cd46d4326a02e913Roger return; 536e1e791727f709c7ab54d47b9cd46d4326a02e913Roger } 537b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen // skip past the encoding, language, and the 0 separator 538b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen frameData += 4; 539b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen int32_t i = n - 4; 540b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen while(--i >= 0 && *++frameData != 0) ; 541b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen int skipped = (frameData - mFrameData); 54214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber if (skipped >= (int)n) { 543b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen return; 544b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 545b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen n -= skipped; 546b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } 547fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 548b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen if (encoding == 0x00) { 549544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly ISO 8859-1 550544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo((const char*)frameData + 1, n); 551b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } else if (encoding == 0x03) { 552544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly UTF-8 553b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen id->setTo((const char *)(frameData + 1), n); 554b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen } else if (encoding == 0x02) { 555544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // supposedly UTF-16 BE, no byte order mark. 556bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // API wants number of characters, not number of bytes... 557bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber int len = n / 2; 558b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const char16_t *framedata = (const char16_t *) (frameData + 1); 559bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber char16_t *framedatacopy = NULL; 560bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#if BYTE_ORDER == LITTLE_ENDIAN 561bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedatacopy = new char16_t[len]; 562bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber for (int i = 0; i < len; i++) { 563bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedatacopy[i] = bswap_16(framedata[i]); 564bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 565bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber framedata = framedatacopy; 566bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber#endif 567bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber id->setTo(framedata, len); 568bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (framedatacopy != NULL) { 569bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber delete[] framedatacopy; 570bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 571544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } else if (encoding == 0x01) { 572fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 57308e7eb983fcb9860a574e964ff905f75aab88d2fAndreas Huber // API wants number of characters, not number of bytes... 5745a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen int len = n / 2; 575b636abde14f2612ea236257846b9ab15d87d4623Marco Nelissen const char16_t *framedata = (const char16_t *) (frameData + 1); 5765a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen char16_t *framedatacopy = NULL; 5775a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfffe) { 5785a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // endianness marker doesn't match host endianness, convert 5795a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedatacopy = new char16_t[len]; 5805a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen for (int i = 0; i < len; i++) { 581569e7f1b1444194d1aca5a0b23de154565ba12daMarco Nelissen framedatacopy[i] = bswap_16(framedata[i]); 5825a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 5835a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata = framedatacopy; 5845a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 5855a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen // If the string starts with an endianness marker, skip it 5865a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (*framedata == 0xfeff) { 5875a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen framedata++; 5885a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen len--; 5895a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 590544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen 591544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // check if the resulting data consists entirely of 8-bit values 592544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen bool eightBit = true; 593544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen for (int i = 0; i < len; i++) { 594544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen if (framedata[i] > 0xff) { 595544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen eightBit = false; 596544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen break; 597544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 598544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 599544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen if (eightBit) { 600544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen // collapse to 8 bit, then let the media scanner client figure out the real encoding 601544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen char *frame8 = new char[len]; 602544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen for (int i = 0; i < len; i++) { 603544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen frame8[i] = framedata[i]; 604544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 605544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo(frame8, len); 606544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen delete [] frame8; 607544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } else { 608544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen id->setTo(framedata, len); 609544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen } 610544ad2be674423238c47650d2c8588ba7dfc9ed2Marco Nelissen 6115a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen if (framedatacopy != NULL) { 6125a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen delete[] framedatacopy; 6135a2621a64de196cbdb9a2a50357dee1c32fcf11bMarco Nelissen } 614fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 615fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 616fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 617fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst uint8_t *ID3::Iterator::getData(size_t *length) const { 618fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 619fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 620fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mFrameData == NULL) { 621fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 622fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 623fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 624be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake // Prevent integer underflow 625be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake if (mFrameSize < getHeaderLength()) { 626be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake return NULL; 627be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake } 628be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake 629fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = mFrameSize - getHeaderLength(); 630fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 631fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return mFrameData; 632fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 633fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 634fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubersize_t ID3::Iterator::getHeaderLength() const { 635fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 636fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 6; 637bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 || mParent.mVersion == ID3_V2_4) { 638fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return 10; 63983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 64083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 64183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return 0; 642fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 643fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 644fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 645fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Hubervoid ID3::Iterator::findFrame() { 646fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (;;) { 647fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = NULL; 648fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 0; 649fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 650fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mParent.mVersion == ID3_V2_2) { 651fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 6 > mParent.mSize) { 652fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 653fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 654fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 655fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 656fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 657fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 658fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 659fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameSize = 660fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber (mParent.mData[mOffset + 3] << 16) 661fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | (mParent.mData[mOffset + 4] << 8) 662fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber | mParent.mData[mOffset + 5]; 663fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 664ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen if (mFrameSize == 0) { 665ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen return; 666ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen } 667ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen mFrameSize += 6; // add tag id and size field 668fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 669c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow in validation 670c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - mOffset <= mFrameSize) { 671c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 672c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 673c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake 674fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 675b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)", 676b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)6); 677fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 678fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 679fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 680fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 6]; 681fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 682fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 683fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 684fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 685fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 686fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[4]; 687fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 3); 688fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[3] = '\0'; 689fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 690fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 691fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 692fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 693bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else if (mParent.mVersion == ID3_V2_3 694bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || mParent.mVersion == ID3_V2_4) { 695fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + 10 > mParent.mSize) { 696fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 697fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 698fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 699fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&mParent.mData[mOffset], "\0\0\0\0", 4)) { 700fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 701fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 702fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 703c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake size_t baseSize = 0; 704bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mParent.mVersion == ID3_V2_4) { 705bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (!ParseSyncsafeInteger( 706bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber &mParent.mData[mOffset + 4], &baseSize)) { 707bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber return; 708bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 709bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } else { 710bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber baseSize = U32_AT(&mParent.mData[mOffset + 4]); 711bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 712bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 713ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen if (baseSize == 0) { 714ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen return; 715ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen } 716ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen 717c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow when adding 718c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - 10 <= baseSize) { 719c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 720c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 721c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake 722ba6e982635f11bced34897f4317cbe8ff1c89483Marco Nelissen mFrameSize = 10 + baseSize; // add tag id, size field and flags 723fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 724c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake // Prevent integer overflow in validation 725c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake if (SIZE_MAX - mOffset <= mFrameSize) { 726c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake return; 727c580c836c1941fb4912e1dd4e08626caf98a62c7Joshua J. Drake } 728fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 729fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (mOffset + mFrameSize > mParent.mSize) { 730b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)", 731b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)10); 732fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return; 733fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 734fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 735bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber uint16_t flags = U16_AT(&mParent.mData[mOffset + 8]); 736bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 737ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber if ((mParent.mVersion == ID3_V2_4 && (flags & 0x000c)) 738bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber || (mParent.mVersion == ID3_V2_3 && (flags & 0x00c0))) { 739ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Compression or encryption are not supported at this time. 740ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // Per-frame unsynchronization and data-length indicator 741ac994dfb88d414aeedf5998aa1c6015c5b47ec01Andreas Huber // have already been taken care of. 742bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 7433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Skipping unsupported frame (compression, encryption " 744bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber "or per-frame unsynchronization flagged"); 745bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 746bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber mOffset += mFrameSize; 747bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber continue; 748bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber } 749bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber 750fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mFrameData = &mParent.mData[mOffset + 10]; 751fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 752fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!mID) { 753fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 754fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 755fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 756fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char id[5]; 757fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber memcpy(id, &mParent.mData[mOffset], 4); 758fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber id[4] = '\0'; 759fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 760fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcmp(id, mID)) { 761fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber break; 762fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 76383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 76483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1); 76583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 76683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mOffset >= mParent.mSize) { 76783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return; 76883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 76983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 77083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameData = &mParent.mData[mOffset]; 77183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 77283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber switch (mOffset) { 77383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 3: 77483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 33: 77583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 63: 77683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 77783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 77883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 93: 77983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 4; 78083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 78183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 97: 78283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mParent.mVersion == ID3_V1) { 78383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 30; 78483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 78583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 29; 78683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 78783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 78883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 126: 78983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 79083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 79183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber case 127: 79283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFrameSize = 1; 79383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 79483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber default: 79583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber CHECK(!"Should not be here, invalid offset."); 79683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 79783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 79883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 79983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (!mID) { 80083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 80183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 80283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 80383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber String8 id; 80483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber getID(&id); 80583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 80683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (id == mID) { 80783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber break; 80883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 809fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 810fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 811fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mOffset += mFrameSize; 812fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 813fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 814fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 815fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic size_t StringSize(const uint8_t *start, uint8_t encoding) { 816bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (encoding == 0x00 || encoding == 0x03) { 817bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber // ISO 8859-1 or UTF-8 818fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return strlen((const char *)start) + 1; 819fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 820fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 821fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // UCS-2 822fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t n = 0; 823fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (start[n] != '\0' || start[n + 1] != '\0') { 824fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber n += 2; 825fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 826fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 827be5016bac5c1b422d850e299d3cb11fecf0ac19dJesper Tragardh // Add size of null termination. 828be5016bac5c1b422d850e299d3cb11fecf0ac19dJesper Tragardh return n + 2; 829fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 830fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 831fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberconst void * 832fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas HuberID3::getAlbumArt(size_t *length, String8 *mime) const { 833fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = 0; 834fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo(""); 835fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 836bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber Iterator it( 837bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber *this, 838bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) ? "APIC" : "PIC"); 839fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 840fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber while (!it.done()) { 841fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t size; 842fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const uint8_t *data = it.getData(&size); 843be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake if (!data) { 844be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake return NULL; 845be7b5e253f85132683826f305e5dcdaf83f0b300Joshua J. Drake } 846fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 847bebd11b5a406bc4243cb7bd55f6849841bf911a7Andreas Huber if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { 848fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 849fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo((const char *)&data[1]); 850fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t mimeLen = strlen((const char *)&data[1]) + 1; 851fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 852fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 853b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe uint8_t picType = data[1 + mimeLen]; 854fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 855fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 856fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 857fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 858fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 859fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 860fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 861fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[2 + mimeLen], encoding); 862fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 863f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen if (size < 2 || 864f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen size - 2 < mimeLen || 865f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen size - 2 - mimeLen < descLen) { 866f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen ALOGW("bogus album art sizes"); 867f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen return NULL; 868f26400c9d01a0e2f71690d5ebc644270f098d590Marco Nelissen } 869fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 2 - mimeLen - descLen; 870fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 871fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[2 + mimeLen + descLen]; 872fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 873fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t encoding = data[0]; 874fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 875fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!memcmp(&data[1], "PNG", 3)) { 876fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/png"); 877fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "JPG", 3)) { 878fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("image/jpeg"); 879fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else if (!memcmp(&data[1], "-->", 3)) { 880fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber mime->setTo("text/plain"); 881fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } else { 882fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 883fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 884fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 885fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#if 0 886fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber uint8_t picType = data[4]; 887fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (picType != 0x03) { 888fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // Front Cover Art 889fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber it.next(); 890fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber continue; 891fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 892fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#endif 893fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 894fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber size_t descLen = StringSize(&data[5], encoding); 895fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 896fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber *length = size - 5 - descLen; 897fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 898fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return &data[5 + descLen]; 899fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 900fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 901fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 902fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 903fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 904fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 90583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huberbool ID3::parseV1(const sp<DataSource> &source) { 90683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber const size_t V1_TAG_SIZE = 128; 90783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 908c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t size; 909c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong if (source->getSize(&size) != OK || size < (off64_t)V1_TAG_SIZE) { 91083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 91183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 91283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 91383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = (uint8_t *)malloc(V1_TAG_SIZE); 91483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (source->readAt(size - V1_TAG_SIZE, mData, V1_TAG_SIZE) 91583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber != (ssize_t)V1_TAG_SIZE) { 91683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 91783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 91883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 91983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 92083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 92183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 92283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (memcmp("TAG", mData, 3)) { 92383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber free(mData); 92483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mData = NULL; 92583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 92683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return false; 92783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 92883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 92983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mSize = V1_TAG_SIZE; 93083e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mFirstFrameOffset = 3; 93183e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 93283e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber if (mData[V1_TAG_SIZE - 3] != 0) { 93383e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1; 93483e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } else { 93583e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber mVersion = ID3_V1_1; 93683e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber } 93783e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber 93883e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber return true; 93983e5850bdf9c8b5c36c364b367b039674eb827adAndreas Huber} 940fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 941fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} // namespace android 942