summaryrefslogtreecommitdiffstats
path: root/media/img_utils/include/img_utils/TiffWriter.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/img_utils/include/img_utils/TiffWriter.h')
-rw-r--r--media/img_utils/include/img_utils/TiffWriter.h267
1 files changed, 267 insertions, 0 deletions
diff --git a/media/img_utils/include/img_utils/TiffWriter.h b/media/img_utils/include/img_utils/TiffWriter.h
new file mode 100644
index 0000000..ec27fc3
--- /dev/null
+++ b/media/img_utils/include/img_utils/TiffWriter.h
@@ -0,0 +1,267 @@
+/*
+ * 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_WRITER_H
+#define IMG_UTILS_TIFF_WRITER_H
+
+#include <img_utils/EndianUtils.h>
+#include <img_utils/TiffEntryImpl.h>
+#include <img_utils/TagDefinitions.h>
+
+#include <utils/Log.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
+
+#include <cutils/compiler.h>
+#include <stdint.h>
+
+namespace android {
+namespace img_utils {
+
+class TiffEntry;
+class TiffIfd;
+class Output;
+
+/**
+ * This class holds a collection of TIFF IFDs that can be written as a
+ * complete DNG file header.
+ *
+ * This maps to the TIFF header structure that is logically composed of:
+ * - An 8-byte file header containing an endianness indicator, the TIFF
+ * file marker, and the offset to the first IFD.
+ * - A list of TIFF IFD structures.
+ */
+class ANDROID_API TiffWriter : public LightRefBase<TiffWriter> {
+ public:
+
+ /**
+ * Constructs a TiffWriter with the default tag mappings. This enables
+ * all of the tags defined in TagDefinitions.h, and uses the following
+ * mapping precedence to resolve collisions:
+ * (highest precedence) TIFF/EP > DNG > EXIF 2.3 > TIFF 6.0
+ */
+ TiffWriter();
+
+ /**
+ * Constructs a TiffWriter with the given tag mappings. The mapping
+ * precedence will be in the order that the definition maps are given,
+ * where the lower index map gets precedence.
+ *
+ * This can be used with user-defined definitions, or definitions form
+ * TagDefinitions.h
+ *
+ * The enabledDefinitions mapping object is owned by the caller, and must
+ * stay alive for the lifespan of the constructed TiffWriter object.
+ */
+ TiffWriter(KeyedVector<uint16_t, const TagDefinition_t*>* enabledDefinitions,
+ size_t length);
+
+ virtual ~TiffWriter();
+
+ /**
+ * Write a TIFF header containing each IFD set. This will recursively
+ * write all SubIFDs and tags.
+ *
+ * Returns OK on success, or a negative error code on failure.
+ */
+ virtual status_t write(Output* out, Endianness end = LITTLE);
+
+ /**
+ * Get the total size in bytes of the TIFF header. This includes all
+ * IFDs, tags, and values set for this TiffWriter.
+ */
+ virtual uint32_t getTotalSize() const;
+
+ /**
+ * Add the given entry to its default IFD. If that IFD does not
+ * exist, it will be created.
+ */
+ virtual status_t addEntry(const sp<TiffEntry>& entry);
+
+ /**
+ * Build an entry for a known tag. This tag must be one of the tags
+ * defined in one of the definition vectors this TIFF writer was constructed
+ * with. The count and type are validated. If this succeeds, the resulting
+ * entry will be placed in the outEntry pointer.
+ *
+ * Returns OK on success, or a negative error code on failure. Valid
+ * error codes for this method are:
+ * - BAD_INDEX - The given tag doesn't exist.
+ * - BAD_VALUE - The given count doesn't match the required count for
+ * this tag.
+ * - BAD_TYPE - The type of the given data isn't compatible with the
+ * type required for this tag.
+ */
+ template<typename T>
+ status_t buildEntry(uint16_t tag, uint32_t count, const T* data,
+ /*out*/sp<TiffEntry>* outEntry) const;
+
+ /**
+ * Build an entry for a known tag and add it to the IFD with the given ID.
+ * This tag must be defined in one of the definition vectors this TIFF writer
+ * was constructed with. The count and type are validated. If this succeeds,
+ * the resulting entry will be placed in the outEntry pointer.
+ *
+ * Returns OK on success, or a negative error code on failure. Valid
+ * error codes for this method are:
+ * - BAD_INDEX - The given tag doesn't exist.
+ * - BAD_VALUE - The given count doesn't match the required count for
+ * this tag.
+ * - BAD_TYPE - The type of the given data isn't compatible with the
+ * type required for this tag.
+ * - NAME_NOT_FOUND - No ifd exists with the given ID.
+ */
+ template<typename T>
+ status_t addEntry(uint16_t tag, uint32_t count, const T* data, uint32_t ifd);
+
+ /**
+ * Return the TIFF entry with the given tag ID in the IFD with the given ID,
+ * or an empty pointer if none exists.
+ */
+ virtual sp<TiffEntry> getEntry(uint16_t tag, uint32_t ifd) const;
+
+ /**
+ * Add the given IFD to the end of the top-level IFD chain. No
+ * validation is done.
+ *
+ * Returns OK on success, or a negative error code on failure.
+ */
+ virtual status_t uncheckedAddIfd(const sp<TiffIfd>& ifd);
+
+ /**
+ * Create an empty IFD with the given ID and add it to the end of the
+ * list of IFDs.
+ */
+ virtual status_t addIfd(uint32_t ifd);
+
+ /**
+ * Build an entry. No validation is done.
+ *
+ * WARNING: Using this method can result in creating poorly formatted
+ * TIFF files.
+ *
+ * Returns a TiffEntry with the given tag, type, count, endianness,
+ * and data.
+ */
+ template<typename T>
+ static sp<TiffEntry> uncheckedBuildEntry(uint16_t tag, TagType type,
+ uint32_t count, Endianness end, const T* data);
+
+ /**
+ * Utility function to build atag-to-definition mapping from a given
+ * array of tag definitions.
+ */
+ static KeyedVector<uint16_t, const TagDefinition_t*> buildTagMap(
+ const TagDefinition_t* definitions, size_t length);
+
+ /**
+ * Returns the default type for the given tag ID.
+ */
+ virtual TagType getDefaultType(uint16_t tag) const;
+
+ /**
+ * Returns the default count for a given tag ID, or 0 if this
+ * tag normally has a variable count.
+ */
+ virtual uint32_t getDefaultCount(uint16_t tag) const;
+
+ /**
+ * Returns true if a definition exist for the given tag ID.
+ */
+ virtual bool checkIfDefined(uint16_t tag) const;
+
+ /**
+ * Print the currently configured IFDs and entries to logcat.
+ */
+ virtual void log() const;
+
+ protected:
+ enum {
+ DEFAULT_NUM_TAG_MAPS = 4,
+ };
+
+ sp<TiffIfd> findLastIfd();
+ status_t writeFileHeader(EndianOutput& out);
+ const TagDefinition_t* lookupDefinition(uint16_t tag) const;
+ status_t calculateOffsets();
+
+ sp<TiffIfd> mIfd;
+ KeyedVector<uint32_t, sp<TiffIfd> > mNamedIfds;
+ KeyedVector<uint16_t, const TagDefinition_t*>* mTagMaps;
+ size_t mNumTagMaps;
+
+ static KeyedVector<uint16_t, const TagDefinition_t*> sTagMaps[];
+};
+
+template<typename T>
+status_t TiffWriter::buildEntry(uint16_t tag, uint32_t count, const T* data,
+ /*out*/sp<TiffEntry>* outEntry) const {
+ const TagDefinition_t* definition = lookupDefinition(tag);
+
+ if (definition == NULL) {
+ ALOGE("%s: No such tag exists for id %x.", __FUNCTION__, tag);
+ return BAD_INDEX;
+ }
+
+ uint32_t fixedCount = definition->fixedCount;
+ if (fixedCount > 0 && fixedCount != count) {
+ ALOGE("%s: Invalid count %d for tag %x (expects %d).", __FUNCTION__, count, tag,
+ fixedCount);
+ return BAD_VALUE;
+ }
+
+ TagType fixedType = definition->defaultType;
+ if (TiffEntry::forceValidType(fixedType, data) == NULL) {
+ ALOGE("%s: Invalid type used for tag value for tag %x.", __FUNCTION__, tag);
+ return BAD_TYPE;
+ }
+
+ *outEntry = new TiffEntryImpl<T>(tag, fixedType, count,
+ definition->fixedEndian, data);
+
+ return OK;
+}
+
+template<typename T>
+status_t TiffWriter::addEntry(uint16_t tag, uint32_t count, const T* data, uint32_t ifd) {
+ sp<TiffEntry> outEntry;
+ status_t ret = buildEntry<T>(tag, count, data, &outEntry);
+ if (ret != OK) {
+ ALOGE("%s: Could not build entry for tag %x.", __FUNCTION__, tag);
+ return ret;
+ }
+ ssize_t index = mNamedIfds.indexOfKey(ifd);
+ if (index < 0) {
+ ALOGE("%s: No IFD %d set for this writer.", __FUNCTION__, ifd);
+ return NAME_NOT_FOUND;
+ }
+ return mNamedIfds[index]->addEntry(outEntry);
+}
+
+template<typename T>
+sp<TiffEntry> TiffWriter::uncheckedBuildEntry(uint16_t tag, TagType type, uint32_t count,
+ Endianness end, const T* data) {
+ TiffEntryImpl<T>* entry = new TiffEntryImpl<T>(tag, type, count, end, data);
+ return sp<TiffEntry>(entry);
+}
+
+} /*namespace img_utils*/
+} /*namespace android*/
+
+
+#endif /*IMG_UTILS_TIFF_WRITER_H*/