diff options
Diffstat (limited to 'media/img_utils/include/img_utils/TiffEntryImpl.h')
-rw-r--r-- | media/img_utils/include/img_utils/TiffEntryImpl.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/media/img_utils/include/img_utils/TiffEntryImpl.h b/media/img_utils/include/img_utils/TiffEntryImpl.h new file mode 100644 index 0000000..0e713dc --- /dev/null +++ b/media/img_utils/include/img_utils/TiffEntryImpl.h @@ -0,0 +1,190 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMG_UTILS_TIFF_ENTRY_IMPL +#define IMG_UTILS_TIFF_ENTRY_IMPL + +#include <img_utils/TiffEntry.h> +#include <img_utils/TiffHelpers.h> +#include <img_utils/Output.h> +#include <img_utils/EndianUtils.h> + +#include <utils/Log.h> +#include <utils/Errors.h> +#include <stdint.h> + +namespace android { +namespace img_utils { + +template<typename T> +class TiffEntryImpl : public TiffEntry { + public: + // TODO: Copy constructor/equals here. + TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end, const T* data); + virtual ~TiffEntryImpl(); + + status_t writeData(uint32_t offset, /*out*/EndianOutput* out) const; + status_t writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const; + + uint32_t getCount() const; + uint16_t getTag() const; + TagType getType() const; + Endianness getEndianness() const; + uint32_t getSize() const; + uint32_t getComparableValue() const; + + protected: + const void* getDataHelper() const; + uint32_t getActualSize() const; + + uint16_t mTag; + uint16_t mType; + uint32_t mCount; + Endianness mEnd; + T* mData; + +}; + +template<typename T> +TiffEntryImpl<T>::TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end, + const T* data) + : mTag(tag), mType(static_cast<uint16_t>(type)), mCount(count), mEnd(end) { + count = (type == RATIONAL || type == SRATIONAL) ? count * 2 : count; + mData = new T[count](); + for (uint32_t i = 0; i < count; ++i) { + mData[i] = data[i]; + } +} + +template<typename T> +TiffEntryImpl<T>::~TiffEntryImpl() { + if (mData) { + delete[] mData; + } +} + +template<typename T> +uint32_t TiffEntryImpl<T>::getCount() const { + return mCount; +} + +template<typename T> +uint16_t TiffEntryImpl<T>::getTag() const { + return mTag; +} + +template<typename T> +TagType TiffEntryImpl<T>::getType() const { + return static_cast<TagType>(mType); +} + +template<typename T> +const void* TiffEntryImpl<T>::getDataHelper() const { + return reinterpret_cast<const void*>(mData); +} + +template<typename T> +uint32_t TiffEntryImpl<T>::getSize() const { + uint32_t total = getActualSize(); + WORD_ALIGN(total) + return (total <= OFFSET_SIZE) ? 0 : total; +} + +template<typename T> +uint32_t TiffEntryImpl<T>::getActualSize() const { + uint32_t total = sizeof(T) * mCount; + if (getType() == RATIONAL || getType() == SRATIONAL) { + // 2 ints stored for each rational, multiply by 2 + total <<= 1; + } + return total; +} + +template<typename T> +Endianness TiffEntryImpl<T>::getEndianness() const { + return mEnd; +} + +template<typename T> +uint32_t TiffEntryImpl<T>::getComparableValue() const { + return mTag; +} + +template<typename T> +status_t TiffEntryImpl<T>::writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const { + assert((offset % TIFF_WORD_SIZE) == 0); + status_t ret = OK; + BAIL_ON_FAIL(out->write(&mTag, 0, 1), ret); + BAIL_ON_FAIL(out->write(&mType, 0, 1), ret); + BAIL_ON_FAIL(out->write(&mCount, 0, 1), ret); + + uint32_t dataSize = getActualSize(); + if (dataSize > OFFSET_SIZE) { + BAIL_ON_FAIL(out->write(&offset, 0, 1), ret); + } else { + uint32_t count = mCount; + if (getType() == RATIONAL || getType() == SRATIONAL) { + /** + * Rationals are stored as an array of ints. Each + * rational is represented by 2 ints. To recover the + * size of the array here, multiply the count by 2. + */ + count <<= 1; + } + BAIL_ON_FAIL(out->write(mData, 0, count), ret); + ZERO_TILL_WORD(out, dataSize, ret); + } + return ret; +} + +template<typename T> +status_t TiffEntryImpl<T>::writeData(uint32_t offset, EndianOutput* out) const { + status_t ret = OK; + + // Some tags have fixed-endian value output + Endianness tmp = UNDEFINED_ENDIAN; + if (mEnd != UNDEFINED_ENDIAN) { + tmp = out->getEndianness(); + out->setEndianness(mEnd); + } + + uint32_t count = mCount; + if (getType() == RATIONAL || getType() == SRATIONAL) { + /** + * Rationals are stored as an array of ints. Each + * rational is represented by 2 ints. To recover the + * size of the array here, multiply the count by 2. + */ + count <<= 1; + } + + BAIL_ON_FAIL(out->write(mData, 0, count), ret); + + if (mEnd != UNDEFINED_ENDIAN) { + out->setEndianness(tmp); + } + + // Write to next word alignment + ZERO_TILL_WORD(out, sizeof(T) * count, ret); + return ret; +} + +} /*namespace img_utils*/ +} /*namespace android*/ + +#endif /*IMG_UTILS_TIFF_ENTRY_IMPL*/ + + |