TiffWriter.cpp revision 4510de26e5361f3a9f07057ec6f26483c888c1fa
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 174510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk#define LOG_TAG "TiffWriter" 184510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffHelpers.h> 20e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TiffWriter.h> 21e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/TagDefinitions.h> 22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <assert.h> 24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android { 26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils { 27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 28e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkKeyedVector<uint16_t, const TagDefinition_t*> TiffWriter::buildTagMap( 29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk const TagDefinition_t* definitions, size_t length) { 30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk KeyedVector<uint16_t, const TagDefinition_t*> map; 31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk for(size_t i = 0; i < length; ++i) { 32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk map.add(definitions[i].tagId, definitions + i); 33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return map; 35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define COMPARE(op) \ 38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkbool Orderable::operator op (const Orderable& orderable) const { \ 39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return getComparableValue() op orderable.getComparableValue(); \ 40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define ARRAY_SIZE(array) \ 43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk (sizeof(array) / sizeof(array[0])) 44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 45e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkKeyedVector<uint16_t, const TagDefinition_t*> TiffWriter::sTagMaps[] = { 46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk buildTagMap(TIFF_EP_TAG_DEFINITIONS, ARRAY_SIZE(TIFF_EP_TAG_DEFINITIONS)), 47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk buildTagMap(DNG_TAG_DEFINITIONS, ARRAY_SIZE(DNG_TAG_DEFINITIONS)), 48e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk buildTagMap(EXIF_2_3_TAG_DEFINITIONS, ARRAY_SIZE(EXIF_2_3_TAG_DEFINITIONS)), 49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk buildTagMap(TIFF_6_TAG_DEFINITIONS, ARRAY_SIZE(TIFF_6_TAG_DEFINITIONS)) 50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}; 51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTiffWriter::TiffWriter() : mTagMaps(sTagMaps), mNumTagMaps(DEFAULT_NUM_TAG_MAPS) {} 53e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 54e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTiffWriter::TiffWriter(KeyedVector<uint16_t, const TagDefinition_t*>* enabledDefinitions, 55e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk size_t length) : mTagMaps(enabledDefinitions), mNumTagMaps(length) {} 56e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTiffWriter::~TiffWriter() {} 58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 594510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkstatus_t TiffWriter::write(Output* out, StripSource** sources, size_t sourcesCount, 604510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk Endianness end) { 614510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk status_t ret = OK; 624510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk EndianOutput endOut(out, end); 634510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 644510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (mIfd == NULL) { 654510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Tiff header is empty.", __FUNCTION__); 664510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 674510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 684510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 694510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (LOG_NDEBUG == 0) { 704510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk log(); 714510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 724510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 734510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t totalSize = getTotalSize(); 744510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 754510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk KeyedVector<uint32_t, uint32_t> offsetVector; 764510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 774510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk for (size_t i = 0; i < mNamedIfds.size(); ++i) { 784510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (mNamedIfds[i]->uninitializedOffsets()) { 794510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t stripSize = mNamedIfds[i]->getStripSize(); 804510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (mNamedIfds[i]->setStripOffset(totalSize) != OK) { 814510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Could not set strip offsets.", __FUNCTION__); 824510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 834510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 844510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk totalSize += stripSize; 854510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk WORD_ALIGN(totalSize); 864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk offsetVector.add(mNamedIfds.keyAt(i), totalSize); 874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 894510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 904510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk size_t offVecSize = offsetVector.size(); 914510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (offVecSize != sourcesCount) { 924510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Mismatch between number of IFDs with uninitialized strips (%zu) and" 934510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk " sources (%zu).", __FUNCTION__, offVecSize, sourcesCount); 944510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 954510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 964510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 974510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk BAIL_ON_FAIL(writeFileHeader(endOut), ret); 984510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 994510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t offset = FILE_HEADER_SIZE; 1004510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk sp<TiffIfd> ifd = mIfd; 1014510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk while(ifd != NULL) { 1024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk BAIL_ON_FAIL(ifd->writeData(offset, &endOut), ret); 1034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk offset += ifd->getSize(); 1044510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ifd = ifd->getNextIfd(); 1054510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1064510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 1074510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk log(); 1084510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 1094510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk for (size_t i = 0; i < offVecSize; ++i) { 1104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t ifdKey = offsetVector.keyAt(i); 1114510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t nextOffset = offsetVector[i]; 1124510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t sizeToWrite = mNamedIfds[ifdKey]->getStripSize(); 1134510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk bool found = false; 1144510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk for (size_t j = 0; j < sourcesCount; ++j) { 1154510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (sources[j]->getIfd() == ifdKey) { 1164510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if ((ret = sources[i]->writeToStream(endOut, sizeToWrite)) != OK) { 1174510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Could not write to stream, received %d.", __FUNCTION__, ret); 1184510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return ret; 1194510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1204510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ZERO_TILL_WORD(&endOut, sizeToWrite, ret); 1214510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk found = true; 1224510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk break; 1234510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1244510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1254510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (!found) { 1264510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: No stream for byte strips for IFD %u", __FUNCTION__, ifdKey); 1274510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 1284510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1294510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk assert(nextOffset == endOut.getCurrentOffset()); 1304510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1314510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 1324510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return ret; 1334510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk} 1344510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 135e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffWriter::write(Output* out, Endianness end) { 136e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk status_t ret = OK; 137e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk EndianOutput endOut(out, end); 138e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 139e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (mIfd == NULL) { 140e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: Tiff header is empty.", __FUNCTION__); 141e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return BAD_VALUE; 142e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 143e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk BAIL_ON_FAIL(writeFileHeader(endOut), ret); 144e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 145e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint32_t offset = FILE_HEADER_SIZE; 146e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> ifd = mIfd; 147e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk while(ifd != NULL) { 148e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk BAIL_ON_FAIL(ifd->writeData(offset, &endOut), ret); 149e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk offset += ifd->getSize(); 150e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ifd = ifd->getNextIfd(); 151e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 152e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return ret; 153e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 154e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 155e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 156e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkconst TagDefinition_t* TiffWriter::lookupDefinition(uint16_t tag) const { 157e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk const TagDefinition_t* definition = NULL; 158e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk for (size_t i = 0; i < mNumTagMaps; ++i) { 159e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ssize_t index = mTagMaps[i].indexOfKey(tag); 160e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (index >= 0) { 161e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk definition = mTagMaps[i][index]; 162e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk break; 163e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 164e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 165e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 166e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (definition == NULL) { 167e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: No definition exists for tag with id %x.", __FUNCTION__, tag); 168e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 169e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return definition; 170e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 171e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 172e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunksp<TiffEntry> TiffWriter::getEntry(uint16_t tag, uint32_t ifd) const { 173e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 174e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (index < 0) { 175e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: No IFD %d set for this writer.", __FUNCTION__, ifd); 176e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return NULL; 177e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 178e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return mNamedIfds[index]->getEntry(tag); 179e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 180e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 1814510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkvoid TiffWriter::removeEntry(uint16_t tag, uint32_t ifd) { 1824510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 1834510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (index >= 0) { 1844510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk mNamedIfds[index]->removeEntry(tag); 1854510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 1864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk} 187e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 1884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkstatus_t TiffWriter::addEntry(const sp<TiffEntry>& entry, uint32_t ifd) { 189e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint16_t tag = entry->getTag(); 190e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 191e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk const TagDefinition_t* definition = lookupDefinition(tag); 192e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 193e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (definition == NULL) { 1944510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: No definition exists for tag 0x%x.", __FUNCTION__, tag); 195e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return BAD_INDEX; 196e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 197e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 1984510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 199e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 200e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk // Add a new IFD if necessary 201e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (index < 0) { 2024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: No IFD %u exists.", __FUNCTION__, ifd); 2034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return NAME_NOT_FOUND; 204e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 205e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 206e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> selectedIfd = mNamedIfds[index]; 207e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return selectedIfd->addEntry(entry); 208e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 209e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 2104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkstatus_t TiffWriter::addStrip(uint32_t ifd) { 2114510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 2124510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (index < 0) { 2134510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Ifd %u doesn't exist, cannot add strip entries.", __FUNCTION__, ifd); 2144510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 215e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 2164510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk sp<TiffIfd> selected = mNamedIfds[index]; 2174510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return selected->validateAndSetStripTags(); 218e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 219e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 220e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffWriter::addIfd(uint32_t ifd) { 221e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 222e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (index >= 0) { 223e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: Ifd with ID 0x%x already exists.", __FUNCTION__, ifd); 224e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return BAD_VALUE; 225e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 2264510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 227e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> newIfd = new TiffIfd(ifd); 228e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (mIfd == NULL) { 229e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk mIfd = newIfd; 230e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } else { 231e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> last = findLastIfd(); 232e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk last->setNextIfd(newIfd); 233e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 2344510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2354510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if(mNamedIfds.add(ifd, newIfd) < 0) { 2364510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to add new IFD 0x%x.", __FUNCTION__, ifd); 2374510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2384510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2394510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2404510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return OK; 2414510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk} 2424510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2434510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkstatus_t TiffWriter::addSubIfd(uint32_t parentIfd, uint32_t ifd, SubIfdType type) { 2444510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 2454510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (index >= 0) { 2464510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Ifd with ID 0x%x already exists.", __FUNCTION__, ifd); 2474510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2484510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2494510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2504510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t parentIndex = mNamedIfds.indexOfKey(parentIfd); 2514510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (parentIndex < 0) { 2524510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Parent IFD with ID 0x%x does not exist.", __FUNCTION__, parentIfd); 2534510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2544510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2554510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2564510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk sp<TiffIfd> parent = mNamedIfds[parentIndex]; 2574510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk sp<TiffIfd> newIfd = new TiffIfd(ifd); 2584510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2594510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint16_t subIfdTag; 2604510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (type == SUBIFD) { 2614510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk subIfdTag = TAG_SUBIFDS; 2624510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } else if (type == GPSINFO) { 2634510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk subIfdTag = TAG_GPSINFO; 2644510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } else { 2654510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Unknown SubIFD type %d.", __FUNCTION__, type); 2664510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2674510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2684510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2694510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk sp<TiffEntry> subIfds = parent->getEntry(subIfdTag); 2704510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (subIfds == NULL) { 2714510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (buildEntry(subIfdTag, 1, &newIfd, &subIfds) < 0) { 2724510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to build SubIfd entry in IFD 0x%x.", __FUNCTION__, parentIfd); 2734510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2744510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2754510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } else { 2764510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (type == GPSINFO) { 2774510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Cannot add GPSInfo SubIFD to IFD %u, one already exists.", __FUNCTION__, 2784510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ifd); 2794510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2804510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2814510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2824510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk Vector<sp<TiffIfd> > subIfdList; 2834510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk const sp<TiffIfd>* oldIfdArray = subIfds->getData<sp<TiffIfd> >(); 2844510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (subIfdList.appendArray(oldIfdArray, subIfds->getCount()) < 0) { 2854510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to build SubIfd entry in IFD 0x%x.", __FUNCTION__, parentIfd); 2864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2894510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (subIfdList.add(newIfd) < 0) { 2904510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to build SubIfd entry in IFD 0x%x.", __FUNCTION__, parentIfd); 2914510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2924510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2934510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 2944510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk uint32_t count = subIfdList.size(); 2954510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (buildEntry(subIfdTag, count, subIfdList.array(), &subIfds) < 0) { 2964510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to build SubIfd entry in IFD 0x%x.", __FUNCTION__, parentIfd); 2974510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 2984510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 2994510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 3004510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 3014510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (parent->addEntry(subIfds) < 0) { 3024510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to add SubIfd entry in IFD 0x%x.", __FUNCTION__, parentIfd); 3034510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 3044510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 3054510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 3064510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if(mNamedIfds.add(ifd, newIfd) < 0) { 3074510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ALOGE("%s: Failed to add new IFD 0x%x.", __FUNCTION__, ifd); 3084510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return BAD_VALUE; 3094510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 3104510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 311e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return OK; 312e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 313e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 314e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkTagType TiffWriter::getDefaultType(uint16_t tag) const { 315e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk const TagDefinition_t* definition = lookupDefinition(tag); 316e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (definition == NULL) { 317e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: Could not find definition for tag %x", __FUNCTION__, tag); 318e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return UNKNOWN_TAGTYPE; 319e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 320e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return definition->defaultType; 321e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 322e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 323e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t TiffWriter::getDefaultCount(uint16_t tag) const { 324e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk const TagDefinition_t* definition = lookupDefinition(tag); 325e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (definition == NULL) { 326e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGE("%s: Could not find definition for tag %x", __FUNCTION__, tag); 327e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return 0; 328e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 329e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return definition->fixedCount; 330e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 331e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 3324510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkbool TiffWriter::hasIfd(uint32_t ifd) const { 3334510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk ssize_t index = mNamedIfds.indexOfKey(ifd); 3344510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return index >= 0; 3354510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk} 3364510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 337e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkbool TiffWriter::checkIfDefined(uint16_t tag) const { 338e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return lookupDefinition(tag) != NULL; 339e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 340e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 3414510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunkconst char* TiffWriter::getTagName(uint16_t tag) const { 3424510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk const TagDefinition_t* definition = lookupDefinition(tag); 3434510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk if (definition == NULL) { 3444510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return NULL; 3454510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk } 3464510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk return definition->tagName; 3474510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk} 3484510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk 349e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunksp<TiffIfd> TiffWriter::findLastIfd() { 350e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> ifd = mIfd; 351e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk while(ifd != NULL) { 352e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> nextIfd = ifd->getNextIfd(); 353e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk if (nextIfd == NULL) { 354e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk break; 355e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 356e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ifd = nextIfd; 357e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 358e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return ifd; 359e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 360e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 361e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t TiffWriter::writeFileHeader(EndianOutput& out) { 362e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk status_t ret = OK; 363e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint16_t endMarker = (out.getEndianness() == BIG) ? BIG_ENDIAN_MARKER : LITTLE_ENDIAN_MARKER; 364e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk BAIL_ON_FAIL(out.write(&endMarker, 0, 1), ret); 365e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 366e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint16_t tiffMarker = TIFF_FILE_MARKER; 367e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk BAIL_ON_FAIL(out.write(&tiffMarker, 0, 1), ret); 368e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 369e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint32_t offsetMarker = FILE_HEADER_SIZE; 370e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk BAIL_ON_FAIL(out.write(&offsetMarker, 0, 1), ret); 371e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return ret; 372e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 373e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 374e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t TiffWriter::getTotalSize() const { 375e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk uint32_t totalSize = FILE_HEADER_SIZE; 376e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk sp<TiffIfd> ifd = mIfd; 377e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk while(ifd != NULL) { 378e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk totalSize += ifd->getSize(); 379e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ifd = ifd->getNextIfd(); 380e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 381e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk return totalSize; 382e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 383e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 384e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkvoid TiffWriter::log() const { 385e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk ALOGI("%s: TiffWriter:", __FUNCTION__); 3864510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk size_t length = mNamedIfds.size(); 3874510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk for (size_t i = 0; i < length; ++i) { 3884510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk mNamedIfds[i]->log(); 389e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk } 390e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} 391e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk 392e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/ 393e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/ 394