1e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/*
2e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Copyright 2014 The Android Open Source Project
3e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
4e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * you may not use this file except in compliance with the License.
6e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * You may obtain a copy of the License at
7e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
8e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
10e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * See the License for the specific language governing permissions and
14e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * limitations under the License.
15e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
16e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
17e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#ifndef IMG_UTILS_TIFF_ENTRY_IMPL
18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define IMG_UTILS_TIFF_ENTRY_IMPL
19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
204510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#include <img_utils/TiffIfd.h>
21e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffEntry.h>
22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffHelpers.h>
23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/Output.h>
24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/EndianUtils.h>
25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Log.h>
27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Errors.h>
284510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#include <utils/Vector.h>
294510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#include <utils/StrongPointer.h>
30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <stdint.h>
31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android {
33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils {
34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass TiffEntryImpl : public TiffEntry {
37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    public:
38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end, const T* data);
39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual ~TiffEntryImpl();
40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        status_t writeData(uint32_t offset, /*out*/EndianOutput* out) const;
42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        status_t writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const;
43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t getCount() const;
45e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint16_t getTag() const;
46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        TagType getType() const;
47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        Endianness getEndianness() const;
48272b7f26c300d2029f278cf2af523cf94e513b89Ruben Brunk        size_t getSize() const;
49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t getComparableValue() const;
50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    protected:
52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        const void* getDataHelper() const;
53e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t getActualSize() const;
54e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
55e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint16_t mTag;
56e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint16_t mType;
57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t mCount;
58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        Endianness mEnd;
594510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        Vector<T> mData;
60e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
61e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
62e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
63e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
64e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTiffEntryImpl<T>::TiffEntryImpl(uint16_t tag, TagType type, uint32_t count, Endianness end,
65e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        const T* data)
66e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        : mTag(tag), mType(static_cast<uint16_t>(type)), mCount(count), mEnd(end) {
67e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    count = (type == RATIONAL || type == SRATIONAL) ? count * 2 : count;
684510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    ssize_t index = mData.appendArray(data, count);
694510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    LOG_ALWAYS_FATAL_IF(index < 0, "%s: Could not allocate vector for data.", __FUNCTION__);
70e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
71e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
72e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
734510de26e5361f3a9f07057ec6f26483c888c1faRuben BrunkTiffEntryImpl<T>::~TiffEntryImpl() {}
74e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
75e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
76e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t TiffEntryImpl<T>::getCount() const {
77e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mCount;
78e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
79e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
80e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
81e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint16_t TiffEntryImpl<T>::getTag() const {
82e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mTag;
83e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
84e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
85e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
86e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTagType TiffEntryImpl<T>::getType() const {
87e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return static_cast<TagType>(mType);
88e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
89e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
90e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
91e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkconst void* TiffEntryImpl<T>::getDataHelper() const {
924510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    return reinterpret_cast<const void*>(mData.array());
93e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
94e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
95e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
96272b7f26c300d2029f278cf2af523cf94e513b89Ruben Brunksize_t TiffEntryImpl<T>::getSize() const {
97e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t total = getActualSize();
98e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    WORD_ALIGN(total)
99e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return (total <= OFFSET_SIZE) ? 0 : total;
100e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
101e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
102e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
103e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t TiffEntryImpl<T>::getActualSize() const {
104e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t total = sizeof(T) * mCount;
105e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (getType() == RATIONAL || getType() == SRATIONAL) {
106e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        // 2 ints stored for each rational, multiply by 2
107e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        total <<= 1;
108e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
109e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return total;
110e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
111e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
112e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
113e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkEndianness TiffEntryImpl<T>::getEndianness() const {
114e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mEnd;
115e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
116e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
117e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
118e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t TiffEntryImpl<T>::getComparableValue() const {
119e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mTag;
120e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
121e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
122e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
123e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffEntryImpl<T>::writeTagInfo(uint32_t offset, /*out*/EndianOutput* out) const {
124e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    assert((offset % TIFF_WORD_SIZE) == 0);
125e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    status_t ret = OK;
126e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BAIL_ON_FAIL(out->write(&mTag, 0, 1), ret);
127e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BAIL_ON_FAIL(out->write(&mType, 0, 1), ret);
128e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BAIL_ON_FAIL(out->write(&mCount, 0, 1), ret);
129e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
130e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t dataSize = getActualSize();
131e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (dataSize > OFFSET_SIZE) {
132e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        BAIL_ON_FAIL(out->write(&offset, 0, 1), ret);
133e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    } else {
134e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t count = mCount;
135e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        if (getType() == RATIONAL || getType() == SRATIONAL) {
136e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            /**
137e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk             * Rationals are stored as an array of ints.  Each
138e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk             * rational is represented by 2 ints.  To recover the
139e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk             * size of the array here, multiply the count by 2.
140e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk             */
141e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            count <<= 1;
142e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        }
1434510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        BAIL_ON_FAIL(out->write(mData.array(), 0, count), ret);
144e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ZERO_TILL_WORD(out, dataSize, ret);
145e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
146e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return ret;
147e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
148e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
149e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
150d7f903ac579b550eb1ec40844e30567f61044a64Bernhard Rosenkränzerstatus_t TiffEntryImpl<T>::writeData(uint32_t /*offset*/, EndianOutput* out) const {
151e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    status_t ret = OK;
152e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
153e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    // Some tags have fixed-endian value output
154e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    Endianness tmp = UNDEFINED_ENDIAN;
155e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (mEnd != UNDEFINED_ENDIAN) {
156e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        tmp = out->getEndianness();
157e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        out->setEndianness(mEnd);
158e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
159e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
160e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t count = mCount;
161e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (getType() == RATIONAL || getType() == SRATIONAL) {
162e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
163e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Rationals are stored as an array of ints.  Each
164e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * rational is represented by 2 ints.  To recover the
165e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * size of the array here, multiply the count by 2.
166e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
167e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        count <<= 1;
168e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
169e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
1704510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    BAIL_ON_FAIL(out->write(mData.array(), 0, count), ret);
171e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
172e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (mEnd != UNDEFINED_ENDIAN) {
173e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        out->setEndianness(tmp);
174e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
175e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
176e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    // Write to next word alignment
177e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    ZERO_TILL_WORD(out, sizeof(T) * count, ret);
178e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return ret;
179e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
180e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
1814510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunktemplate<>
1824510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkinline status_t TiffEntryImpl<sp<TiffIfd> >::writeTagInfo(uint32_t offset,
1834510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /*out*/EndianOutput* out) const {
1844510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    assert((offset % TIFF_WORD_SIZE) == 0);
1854510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    status_t ret = OK;
1864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    BAIL_ON_FAIL(out->write(&mTag, 0, 1), ret);
1874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    BAIL_ON_FAIL(out->write(&mType, 0, 1), ret);
1884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    BAIL_ON_FAIL(out->write(&mCount, 0, 1), ret);
1894510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1904510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    BAIL_ON_FAIL(out->write(&offset, 0, 1), ret);
1914510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    return ret;
1924510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk}
1934510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1944510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunktemplate<>
1954510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkinline uint32_t TiffEntryImpl<sp<TiffIfd> >::getActualSize() const {
1964510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    uint32_t total = 0;
1974510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    for (size_t i = 0; i < mData.size(); ++i) {
1984510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        total += mData[i]->getSize();
1994510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    }
2004510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    return total;
2014510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk}
2024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
2034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunktemplate<>
2044510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkinline status_t TiffEntryImpl<sp<TiffIfd> >::writeData(uint32_t offset, EndianOutput* out) const {
2054510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    status_t ret = OK;
2064510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    for (uint32_t i = 0; i < mCount; ++i) {
2074510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        BAIL_ON_FAIL(mData[i]->writeData(offset, out), ret);
2084510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        offset += mData[i]->getSize();
2094510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    }
2104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    return ret;
2114510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk}
2124510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
213e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/
214e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/
215e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
216e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#endif /*IMG_UTILS_TIFF_ENTRY_IMPL*/
217e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
218e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
219