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_IFD_H
18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define IMG_UTILS_TIFF_IFD_H
19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
20e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffWritable.h>
21e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffEntry.h>
22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/Output.h>
23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/SortedEntryVector.h>
24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <cutils/compiler.h>
26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Errors.h>
27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/String8.h>
28e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/SortedVector.h>
29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/StrongPointer.h>
30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <stdint.h>
31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android {
33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils {
34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * This class holds a single TIFF Image File Directory (IFD) structure.
37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * This maps to the TIFF IFD structure that is logically composed of:
39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * - A 2-byte field listing the number of entries.
40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * - A list of 12-byte TIFF entries.
41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * - A 4-byte offset to the next IFD.
42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass ANDROID_API TiffIfd : public TiffWritable {
44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    public:
45a0b40ae71d251a40161881780bc317c025d7678fChih-Hung Hsieh        explicit TiffIfd(uint32_t ifdId);
46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual ~TiffIfd();
47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
48e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Add a TiffEntry to this IFD or replace an existing entry with the
50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * same tag ID.  No validation is done.
51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns OK on success, or a negative error code on failure.
53e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
54e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual status_t addEntry(const sp<TiffEntry>& entry);
55e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
56e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Set the pointer to the next IFD.  This is used to create a linked
58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * list of IFDs as defined by the TIFF 6.0 spec., and is not included
59e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * when calculating the size of IFD and entries for the getSize()
60e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * method (unlike SubIFDs).
61e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
62e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual void setNextIfd(const sp<TiffIfd>& ifd);
63e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
64e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
65e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get the pointer to the next IFD, or NULL if none exists.
66e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
67e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual sp<TiffIfd> getNextIfd() const;
68e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
69e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
70e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Write the IFD data.  This includes the IFD header, entries, footer,
71e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * and the corresponding values for each entry (recursively including
72e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * sub-IFDs).  The written amount should end on a word boundary, and
73e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * the given offset should be word aligned.
74e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
75e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns OK on success, or a negative error code on failure.
76e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
77e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual status_t writeData(uint32_t offset, /*out*/EndianOutput* out) const;
78e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
79e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
80e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get the size of the IFD. This includes the IFD header, entries, footer,
81e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * and the corresponding values for each entry (recursively including
82e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * any sub-IFDs).
83e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
84272b7f26c300d2029f278cf2af523cf94e513b89Ruben Brunk        virtual size_t getSize() const;
85e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
86e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
87e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get the id of this IFD.
88e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
89e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual uint32_t getId() const;
90e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
91e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
92e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get an entry with the given tag ID.
93e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
94e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns a strong pointer to the entry if it exists, or an empty strong
95e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * pointer.
96e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
97e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual sp<TiffEntry> getEntry(uint16_t tag) const;
98e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
99e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
1004510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Remove the entry with the given tag ID if it exists.
1014510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual void removeEntry(uint16_t tag);
1034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1044510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
1054510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Convenience method to validate and set strip-related image tags.
1064510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1074510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * This sets all strip related tags, but leaves offset values unitialized.
1084510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * setStripOffsets must be called with the desired offset before writing.
1094510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * The strip tag values are calculated from the existing tags for image
1104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * dimensions and pixel type set in the IFD.
1114510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1124510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Does not handle planar image configurations (PlanarConfiguration != 1).
1134510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1144510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns OK on success, or a negative error code.
1154510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1164510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t validateAndSetStripTags();
1174510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1184510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
1194510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns true if validateAndSetStripTags has been called, but not setStripOffsets.
1204510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1214510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual bool uninitializedOffsets() const;
1224510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1234510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
1244510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Convenience method to set beginning offset for strips.
1254510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1264510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Call this to update the strip offsets before calling writeData.
1274510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1284510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns OK on success, or a negative error code.
1294510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1304510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t setStripOffset(uint32_t offset);
1314510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1324510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
1334510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Get the total size of the strips in bytes.
1344510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1354510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * This sums the byte count at each strip offset, and returns
1364510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * the total count of bytes stored in strips for this IFD.
1374510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1384510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual uint32_t getStripSize() const;
1394510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1404510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
141e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get a formatted string representing this IFD.
142e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
1434510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual String8 toString() const;
144e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
145e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
146e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Print a formatted string representing this IFD to logcat.
147e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
148e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        void log() const;
149e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
150e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
151e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get value used to determine sort order.
152e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
153e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual uint32_t getComparableValue() const;
1544510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
155e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    protected:
156e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual uint32_t checkAndGetOffset(uint32_t offset) const;
157e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        SortedEntryVector mEntries;
158e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        sp<TiffIfd> mNextIfd;
159e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        uint32_t mIfdId;
1604510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        bool mStripOffsetsInitialized;
161e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
162e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
163e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/
164e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/
165e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
166e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#endif /*IMG_UTILS_TIFF_IFD_H*/
167