TiffEntryImpl.h revision e507721000647a7d8afe44c63ef7fd04ef8971b1
1d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber/* 2d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * Copyright 2014 The Android Open Source Project 3d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * 4d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * you may not use this file except in compliance with the License. 6d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * You may obtain a copy of the License at 7d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * 8d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * 10d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * Unless required by applicable law or agreed to in writing, software 11d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * See the License for the specific language governing permissions and 14d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * limitations under the License. 15d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber */ 16d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 17d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#ifndef IMG_UTILS_TIFF_ENTRY_IMPL 18d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#define IMG_UTILS_TIFF_ENTRY_IMPL 19d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 20d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <img_utils/TiffEntry.h> 21d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <img_utils/TiffHelpers.h> 22d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <img_utils/Output.h> 23d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <img_utils/EndianUtils.h> 24d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 25d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <utils/Log.h> 26d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <utils/Errors.h> 27d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#include <stdint.h> 28d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 29d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubernamespace android { 30d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubernamespace img_utils { 31d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 32d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 33d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberclass TiffEntryImpl : public TiffEntry { 34d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber public: 35d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // TODO: Copy constructor/equals here. 36d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end, const T* data); 37d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber virtual ~TiffEntryImpl(); 38d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 39d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber status_t writeData(uint32_t offset, /*out*/EndianOutput* out) const; 40d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber status_t writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const; 41d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 42d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t getCount() const; 43d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint16_t getTag() const; 44d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber TagType getType() const; 45d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Endianness getEndianness() const; 46d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t getSize() const; 47d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t getComparableValue() const; 48d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 49d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber protected: 50d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const void* getDataHelper() const; 51d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t getActualSize() const; 52d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 53d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint16_t mTag; 54d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint16_t mType; 55d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t mCount; 56d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Endianness mEnd; 57d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber T* mData; 58d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 59d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber}; 60d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 61d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 62d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberTiffEntryImpl<T>::TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end, 63d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber const T* data) 64d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber : mTag(tag), mType(static_cast<uint16_t>(type)), mCount(count), mEnd(end) { 65d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber count = (type == RATIONAL || type == SRATIONAL) ? count * 2 : count; 66d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber mData = new T[count](); 67d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber for (uint32_t i = 0; i < count; ++i) { 68d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber mData[i] = data[i]; 69d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 70d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 71d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 72d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 73d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberTiffEntryImpl<T>::~TiffEntryImpl() { 74d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (mData) { 75d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber delete[] mData; 76d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 77d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 78d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 79d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 80d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberuint32_t TiffEntryImpl<T>::getCount() const { 81d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return mCount; 82d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 83d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 84d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 85d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberuint16_t TiffEntryImpl<T>::getTag() const { 86d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return mTag; 87d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 88d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 89d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 90d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberTagType TiffEntryImpl<T>::getType() const { 91d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return static_cast<TagType>(mType); 92d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 93d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 94d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 95d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberconst void* TiffEntryImpl<T>::getDataHelper() const { 96d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return reinterpret_cast<const void*>(mData); 97d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 98d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 99d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 100d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberuint32_t TiffEntryImpl<T>::getSize() const { 101d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t total = getActualSize(); 102d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber WORD_ALIGN(total) 103d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return (total <= OFFSET_SIZE) ? 0 : total; 104d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 105d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 106d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 107d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberuint32_t TiffEntryImpl<T>::getActualSize() const { 108d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t total = sizeof(T) * mCount; 109d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (getType() == RATIONAL || getType() == SRATIONAL) { 110d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // 2 ints stored for each rational, multiply by 2 111d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber total <<= 1; 112d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 113d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return total; 114d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 115d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 116d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 117d9618f23226f46c752e56f712bc4b505117d8b4bAndreas HuberEndianness TiffEntryImpl<T>::getEndianness() const { 118d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return mEnd; 119d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 120d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 121d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 122d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberuint32_t TiffEntryImpl<T>::getComparableValue() const { 123d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return mTag; 124d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 125d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 126d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 127d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberstatus_t TiffEntryImpl<T>::writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const { 128d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber assert((offset % TIFF_WORD_SIZE) == 0); 129d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber status_t ret = OK; 130d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(&mTag, 0, 1), ret); 131d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(&mType, 0, 1), ret); 132d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(&mCount, 0, 1), ret); 133d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 134d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t dataSize = getActualSize(); 135d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (dataSize > OFFSET_SIZE) { 136d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(&offset, 0, 1), ret); 137d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } else { 138d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t count = mCount; 139d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (getType() == RATIONAL || getType() == SRATIONAL) { 140d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber /** 141d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * Rationals are stored as an array of ints. Each 142d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * rational is represented by 2 ints. To recover the 143d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * size of the array here, multiply the count by 2. 144d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber */ 145d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber count <<= 1; 146d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 147d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(mData, 0, count), ret); 148d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber ZERO_TILL_WORD(out, dataSize, ret); 149d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 150d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return ret; 151d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 152d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 153d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Hubertemplate<typename T> 154d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huberstatus_t TiffEntryImpl<T>::writeData(uint32_t offset, EndianOutput* out) const { 155d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber status_t ret = OK; 156d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 157d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // Some tags have fixed-endian value output 158d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber Endianness tmp = UNDEFINED_ENDIAN; 159d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (mEnd != UNDEFINED_ENDIAN) { 160d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber tmp = out->getEndianness(); 161d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber out->setEndianness(mEnd); 162d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 163d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 164d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber uint32_t count = mCount; 165d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (getType() == RATIONAL || getType() == SRATIONAL) { 166d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber /** 167d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * Rationals are stored as an array of ints. Each 168d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * rational is represented by 2 ints. To recover the 169d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber * size of the array here, multiply the count by 2. 170d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber */ 171d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber count <<= 1; 172d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 173d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 174d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber BAIL_ON_FAIL(out->write(mData, 0, count), ret); 175d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 176d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber if (mEnd != UNDEFINED_ENDIAN) { 177d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber out->setEndianness(tmp); 178d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber } 179d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 180d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber // Write to next word alignment 181d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber ZERO_TILL_WORD(out, sizeof(T) * count, ret); 182d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber return ret; 183d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} 184d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 185d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} /*namespace img_utils*/ 186d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber} /*namespace android*/ 187d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 188d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber#endif /*IMG_UTILS_TIFF_ENTRY_IMPL*/ 189d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 190d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber 191d9618f23226f46c752e56f712bc4b505117d8b4bAndreas Huber