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