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_WRITER_H
18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define IMG_UTILS_TIFF_WRITER_H
19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
20e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/EndianUtils.h>
214510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#include <img_utils/StripSource.h>
22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffEntryImpl.h>
23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TagDefinitions.h>
244510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#include <img_utils/TiffIfd.h>
25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Log.h>
27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Errors.h>
28e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/StrongPointer.h>
29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/KeyedVector.h>
30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <utils/Vector.h>
31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <cutils/compiler.h>
33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <stdint.h>
34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android {
36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils {
37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass TiffEntry;
39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass TiffIfd;
40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass Output;
41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * This class holds a collection of TIFF IFDs that can be written as a
44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * complete DNG file header.
45e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * This maps to the TIFF header structure that is logically composed of:
47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * - An 8-byte file header containing an endianness indicator, the TIFF
48e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *   file marker, and the offset to the first IFD.
49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * - A list of TIFF IFD structures.
50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkclass ANDROID_API TiffWriter : public LightRefBase<TiffWriter> {
52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    public:
534510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        enum SubIfdType {
544510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk            SUBIFD = 0,
554510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk            GPSINFO
564510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        };
57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
59e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Constructs a TiffWriter with the default tag mappings. This enables
60e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * all of the tags defined in TagDefinitions.h, and uses the following
61e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * mapping precedence to resolve collisions:
62e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * (highest precedence) TIFF/EP > DNG > EXIF 2.3 > TIFF 6.0
63e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
64e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        TiffWriter();
65e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
66e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
67e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Constructs a TiffWriter with the given tag mappings.  The mapping
68e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * precedence will be in the order that the definition maps are given,
69e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * where the lower index map gets precedence.
70e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
71e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * This can be used with user-defined definitions, or definitions form
72e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * TagDefinitions.h
73e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
74e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * The enabledDefinitions mapping object is owned by the caller, and must
75e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * stay alive for the lifespan of the constructed TiffWriter object.
76e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
77e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        TiffWriter(KeyedVector<uint16_t, const TagDefinition_t*>* enabledDefinitions,
78e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                size_t length);
79e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
80e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual ~TiffWriter();
81e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
82e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
83e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Write a TIFF header containing each IFD set.  This will recursively
84e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * write all SubIFDs and tags.
85e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Any StripSources passed in will be written to the output as image strips
874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * at the appropriate offests.  The StripByteCounts, RowsPerStrip, and
884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * StripOffsets tags must be set to use this.  To set these tags in a
894510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * given IFD, use the addStrip method.
904510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
914510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns OK on success, or a negative error code on failure.
924510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
934510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t write(Output* out, StripSource** sources, size_t sourcesCount,
944510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk                Endianness end = LITTLE);
954510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
964510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
974510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Write a TIFF header containing each IFD set.  This will recursively
984510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * write all SubIFDs and tags.
994510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1004510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Image data for strips or tiles must be written separately at the
1014510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * appropriate offsets.  These offsets must not fall within the file
1024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * header written this way.  The size of the header written is given
1034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * by the getTotalSize() method.
1044510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
105e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns OK on success, or a negative error code on failure.
106e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
107e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual status_t write(Output* out, Endianness end = LITTLE);
108e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
109e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
110e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Get the total size in bytes of the TIFF header.  This includes all
111e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * IFDs, tags, and values set for this TiffWriter.
112e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
113e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual uint32_t getTotalSize() const;
114e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
115e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
1164510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Add an entry to the IFD with the given ID.
117e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
118e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns OK on success, or a negative error code on failure. Valid
119e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * error codes for this method are:
120e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_INDEX - The given tag doesn't exist.
121e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_VALUE - The given count doesn't match the required count for
122e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *               this tag.
123e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_TYPE  - The type of the given data isn't compatible with the
124e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *               type required for this tag.
1254510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - NAME_NOT_FOUND - No ifd exists with the given ID.
126e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
1274510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t addEntry(const sp<TiffEntry>& entry, uint32_t ifd);
128e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
1294510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
130e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Build an entry for a known tag and add it to the IFD with the given ID.
131e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * This tag must be defined in one of the definition vectors this TIFF writer
1324510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * was constructed with. The count and type are validated.
133e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *
134e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns OK on success, or a negative error code on failure. Valid
135e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * error codes for this method are:
136e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_INDEX - The given tag doesn't exist.
137e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_VALUE - The given count doesn't match the required count for
138e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *               this tag.
139e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - BAD_TYPE  - The type of the given data isn't compatible with the
140e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         *               type required for this tag.
141e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * - NAME_NOT_FOUND - No ifd exists with the given ID.
142e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
143e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        template<typename T>
144e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        status_t addEntry(uint16_t tag, uint32_t count, const T* data, uint32_t ifd);
145e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
146e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
1474510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Build an entry for a known tag.  This tag must be one of the tags
1484510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * defined in one of the definition vectors this TIFF writer was constructed
1494510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * with. The count and type are validated. If this succeeds, the resulting
1504510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * entry will be placed in the outEntry pointer.
1514510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1524510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns OK on success, or a negative error code on failure. Valid
1534510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * error codes for this method are:
1544510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - BAD_INDEX - The given tag doesn't exist.
1554510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - BAD_VALUE - The given count doesn't match the required count for
1564510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *               this tag.
1574510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - BAD_TYPE  - The type of the given data isn't compatible with the
1584510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *               type required for this tag.
1594510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1604510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        template<typename T>
1614510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        status_t buildEntry(uint16_t tag, uint32_t count, const T* data,
1624510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk                  /*out*/sp<TiffEntry>* outEntry) const;
1634510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1644510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
1654510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Convenience function to set the strip related tags for a given IFD.
1664510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1674510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Call this before using a StripSource as an input to write.
1684510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * The following tags must be set before calling this method:
1694510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - ImageWidth
1704510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - ImageLength
1714510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - SamplesPerPixel
1724510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * - BitsPerSample
1734510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
1744510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns OK on success, or a negative error code.
1754510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
1764510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t addStrip(uint32_t ifd);
1774510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
1784510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
179e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Return the TIFF entry with the given tag ID in the IFD with the given ID,
180e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * or an empty pointer if none exists.
181e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
182e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual sp<TiffEntry> getEntry(uint16_t tag, uint32_t ifd) const;
183e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
184e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
1854510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Remove the TIFF entry with the given tag ID in the given IFD if it exists.
186e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
1874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual void removeEntry(uint16_t tag, uint32_t ifd);
188e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
189e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
190e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Create an empty IFD with the given ID and add it to the end of the
191e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * list of IFDs.
192e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
193e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual status_t addIfd(uint32_t ifd);
194e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
195e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
1964510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Create an empty IFD with the given ID and add it as a SubIfd of the
1974510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * parent IFD.
198e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
1994510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual status_t addSubIfd(uint32_t parentIfd, uint32_t ifd, SubIfdType type = SUBIFD);
200e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
201e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
202e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns the default type for the given tag ID.
203e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
204e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual TagType getDefaultType(uint16_t tag) const;
205e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
206e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
207e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns the default count for a given tag ID, or 0 if this
208e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * tag normally has a variable count.
209e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
210e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual uint32_t getDefaultCount(uint16_t tag) const;
211e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
212e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
2134510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns true if an IFD with the given ID exists.
2144510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
2154510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual bool hasIfd(uint32_t ifd) const;
2164510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
2174510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
218e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Returns true if a definition exist for the given tag ID.
219e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
220e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual bool checkIfDefined(uint16_t tag) const;
221e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
222e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        /**
2234510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns the name of the tag if a definition exists for the given tag
2244510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * ID, or null if no definition exists.
2254510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
2264510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        virtual const char* getTagName(uint16_t tag) const;
2274510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
2284510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
229e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         * Print the currently configured IFDs and entries to logcat.
230e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk         */
231e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        virtual void log() const;
232e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
2334510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
2344510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Build an entry.  No validation is done.
2354510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
2364510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * WARNING: Using this method can result in creating poorly formatted
2374510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * TIFF files.
2384510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         *
2394510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Returns a TiffEntry with the given tag, type, count, endianness,
2404510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * and data.
2414510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
2424510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        template<typename T>
2434510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        static sp<TiffEntry> uncheckedBuildEntry(uint16_t tag, TagType type,
2444510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk                  uint32_t count, Endianness end, const T* data);
2454510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
2464510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        /**
2474510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * Utility function to build atag-to-definition mapping from a given
2484510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         * array of tag definitions.
2494510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk         */
2504510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk        static KeyedVector<uint16_t, const TagDefinition_t*> buildTagMap(
2514510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk                  const TagDefinition_t* definitions, size_t length);
2524510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
253e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    protected:
254e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        enum {
255e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            DEFAULT_NUM_TAG_MAPS = 4,
256e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        };
257e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
258e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        sp<TiffIfd> findLastIfd();
259e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        status_t writeFileHeader(EndianOutput& out);
260e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        const TagDefinition_t* lookupDefinition(uint16_t tag) const;
261e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        status_t calculateOffsets();
262e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
263e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        sp<TiffIfd> mIfd;
264e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        KeyedVector<uint32_t, sp<TiffIfd> > mNamedIfds;
265e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        KeyedVector<uint16_t, const TagDefinition_t*>* mTagMaps;
266e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        size_t mNumTagMaps;
267e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
268e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        static KeyedVector<uint16_t, const TagDefinition_t*> sTagMaps[];
269e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
270e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
271e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
272e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffWriter::buildEntry(uint16_t tag, uint32_t count, const T* data,
273e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                  /*out*/sp<TiffEntry>* outEntry) const {
274e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    const TagDefinition_t* definition = lookupDefinition(tag);
275e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
276e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (definition == NULL) {
277e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: No such tag exists for id %x.", __FUNCTION__, tag);
278e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        return BAD_INDEX;
279e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
280e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
281e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t fixedCount = definition->fixedCount;
282e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (fixedCount > 0 && fixedCount != count) {
283e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: Invalid count %d for tag %x (expects %d).", __FUNCTION__, count, tag,
284e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                fixedCount);
285e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        return BAD_VALUE;
286e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
287e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
288e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TagType fixedType = definition->defaultType;
289e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (TiffEntry::forceValidType(fixedType, data) == NULL) {
290e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: Invalid type used for tag value for tag %x.", __FUNCTION__, tag);
291e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        return BAD_TYPE;
292e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
293e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
294e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    *outEntry = new TiffEntryImpl<T>(tag, fixedType, count,
295e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        definition->fixedEndian, data);
296e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
297e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return OK;
298e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
299e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
300e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
301e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffWriter::addEntry(uint16_t tag, uint32_t count, const T* data, uint32_t ifd) {
302e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    sp<TiffEntry> outEntry;
3034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
304e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    status_t ret = buildEntry<T>(tag, count, data, &outEntry);
305e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (ret != OK) {
306e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: Could not build entry for tag %x.", __FUNCTION__, tag);
307e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        return ret;
308e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
3094510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk
3104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk    return addEntry(outEntry, ifd);
311e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
312e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
313e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunktemplate<typename T>
314e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunksp<TiffEntry> TiffWriter::uncheckedBuildEntry(uint16_t tag, TagType type, uint32_t count,
315e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        Endianness end, const T* data) {
316e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TiffEntryImpl<T>* entry = new TiffEntryImpl<T>(tag, type, count, end, data);
317e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return sp<TiffEntry>(entry);
318e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
319e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
320e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/
321e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/
322e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
323e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
324e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#endif /*IMG_UTILS_TIFF_WRITER_H*/
325