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