TiffEntry.cpp revision e507721000647a7d8afe44c63ef7fd04ef8971b1
1/* 2 * Copyright 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <img_utils/TiffIfd.h> 18#include <img_utils/TiffHelpers.h> 19#include <img_utils/TiffEntry.h> 20 21#include <utils/Errors.h> 22#include <utils/StrongPointer.h> 23#include <utils/Vector.h> 24 25namespace android { 26namespace img_utils { 27 28TiffEntry::~TiffEntry() {} 29 30/** 31 * Specialize for each valid type, including sub-IFDs. 32 * 33 * Values with types other than the ones given here should not compile. 34 */ 35template<> 36const Vector<sp<TiffIfd> >* TiffEntry::forceValidType<Vector<sp<TiffIfd> > >(TagType type, 37 const Vector<sp<TiffIfd> >* value) { 38 if (type == LONG) { 39 return value; 40 } 41 ALOGE("%s: Value of type 'ifd vector' is not valid for tag with TIFF type %d.", 42 __FUNCTION__, type); 43 return NULL; 44} 45 46template<> 47const sp<TiffIfd>* TiffEntry::forceValidType<sp<TiffIfd> >(TagType type, const sp<TiffIfd>* value) { 48 if (type == LONG) { 49 return value; 50 } 51 ALOGE("%s: Value of type 'ifd' is not valid for tag with TIFF type %d.", 52 __FUNCTION__, type); 53 return NULL; 54} 55 56template<> 57const uint8_t* TiffEntry::forceValidType<uint8_t>(TagType type, const uint8_t* value) { 58 if (type == BYTE || type == ASCII || type == UNDEFINED) { 59 return value; 60 } 61 ALOGE("%s: Value of type 'uint8_t' is not valid for tag with TIFF type %d.", 62 __FUNCTION__, type); 63 return NULL; 64} 65 66template<> 67const int8_t* TiffEntry::forceValidType<int8_t>(TagType type, const int8_t* value) { 68 if (type == SBYTE || type == ASCII || type == UNDEFINED) { 69 return value; 70 } 71 ALOGE("%s: Value of type 'int8_t' is not valid for tag with TIFF type %d.", 72 __FUNCTION__, type); 73 return NULL; 74} 75 76template<> 77const uint16_t* TiffEntry::forceValidType<uint16_t>(TagType type, const uint16_t* value) { 78 if (type == SHORT) { 79 return value; 80 } 81 ALOGE("%s: Value of type 'uint16_t' is not valid for tag with TIFF type %d.", 82 __FUNCTION__, type); 83 return NULL; 84} 85 86template<> 87const int16_t* TiffEntry::forceValidType<int16_t>(TagType type, const int16_t* value) { 88 if (type == SSHORT) { 89 return value; 90 } 91 ALOGE("%s: Value of type 'int16_t' is not valid for tag with TIFF type %d.", 92 __FUNCTION__, type); 93 return NULL; 94} 95 96template<> 97const uint32_t* TiffEntry::forceValidType<uint32_t>(TagType type, const uint32_t* value) { 98 if (type == LONG || type == RATIONAL) { 99 return value; 100 } 101 ALOGE("%s: Value of type 'uint32_t' is not valid for tag with TIFF type %d.", 102 __FUNCTION__, type); 103 return NULL; 104} 105 106template<> 107const int32_t* TiffEntry::forceValidType<int32_t>(TagType type, const int32_t* value) { 108 if (type == SLONG || type == SRATIONAL) { 109 return value; 110 } 111 ALOGE("%s: Value of type 'int32_t' is not valid for tag with TIFF type %d.", 112 __FUNCTION__, type); 113 return NULL; 114} 115 116template<> 117const double* TiffEntry::forceValidType<double>(TagType type, const double* value) { 118 if (type == DOUBLE) { 119 return value; 120 } 121 ALOGE("%s: Value of type 'double' is not valid for tag with TIFF type %d.", 122 __FUNCTION__, type); 123 return NULL; 124} 125 126template<> 127const float* TiffEntry::forceValidType<float>(TagType type, const float* value) { 128 if (type == FLOAT) { 129 return value; 130 } 131 ALOGE("%s: Value of type 'float' is not valid for tag with TIFF type %d.", 132 __FUNCTION__, type); 133 return NULL; 134} 135 136String8 TiffEntry::toString() const { 137 String8 output; 138 uint32_t count = getCount(); 139 output.appendFormat("[id: %x, type: %d, count: %u, value: '", getTag(), getType(), count); 140 141 size_t cappedCount = count; 142 if (count > MAX_PRINT_STRING_LENGTH) { 143 cappedCount = MAX_PRINT_STRING_LENGTH; 144 } 145 146 TagType type = getType(); 147 switch (type) { 148 case UNDEFINED: 149 case BYTE: { 150 const uint8_t* typed_data = getData<uint8_t>(); 151 for (size_t i = 0; i < cappedCount; ++i) { 152 output.appendFormat("%u ", typed_data[i]); 153 } 154 break; 155 } 156 case ASCII: { 157 const char* typed_data = reinterpret_cast<const char*>(getData<uint8_t>()); 158 size_t len = count; 159 if (count > MAX_PRINT_STRING_LENGTH) { 160 len = MAX_PRINT_STRING_LENGTH; 161 } 162 output.append(typed_data, len); 163 break; 164 } 165 case SHORT: { 166 const uint16_t* typed_data = getData<uint16_t>(); 167 for (size_t i = 0; i < cappedCount; ++i) { 168 output.appendFormat("%u ", typed_data[i]); 169 } 170 break; 171 } 172 case LONG: { 173 const uint32_t* typed_data = getData<uint32_t>(); 174 for (size_t i = 0; i < cappedCount; ++i) { 175 output.appendFormat("%u ", typed_data[i]); 176 } 177 break; 178 } 179 case RATIONAL: { 180 const uint32_t* typed_data = getData<uint32_t>(); 181 cappedCount <<= 1; 182 for (size_t i = 0; i < cappedCount; i+=2) { 183 output.appendFormat("%u/%u ", typed_data[i], typed_data[i + 1]); 184 } 185 break; 186 } 187 case SBYTE: { 188 const int8_t* typed_data = getData<int8_t>(); 189 for (size_t i = 0; i < cappedCount; ++i) { 190 output.appendFormat("%d ", typed_data[i]); 191 } 192 break; 193 } 194 case SSHORT: { 195 const int16_t* typed_data = getData<int16_t>(); 196 for (size_t i = 0; i < cappedCount; ++i) { 197 output.appendFormat("%d ", typed_data[i]); 198 } 199 break; 200 } 201 case SLONG: { 202 const int32_t* typed_data = getData<int32_t>(); 203 for (size_t i = 0; i < cappedCount; ++i) { 204 output.appendFormat("%d ", typed_data[i]); 205 } 206 break; 207 } 208 case SRATIONAL: { 209 const int32_t* typed_data = getData<int32_t>(); 210 cappedCount <<= 1; 211 for (size_t i = 0; i < cappedCount; i+=2) { 212 output.appendFormat("%d/%d ", typed_data[i], typed_data[i + 1]); 213 } 214 break; 215 } 216 case FLOAT: 217 case DOUBLE: { 218 const float* typed_data = getData<float>(); 219 for (size_t i = 0; i < cappedCount; ++i) { 220 output.appendFormat("%f ", typed_data[i]); 221 } 222 break; 223 } 224 default: { 225 output.append("unknown type "); 226 break; 227 } 228 } 229 230 if (count > MAX_PRINT_STRING_LENGTH) { 231 output.append("..."); 232 } 233 output.append("']"); 234 return output; 235} 236 237} /*namespace img_utils*/ 238} /*namespace android*/ 239