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 25 namespace android { 26 namespace img_utils { 27 28 TiffEntry::~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 */ 35 36 template<> 37 const sp<TiffIfd>* TiffEntry::forceValidType<sp<TiffIfd> >(TagType type, const sp<TiffIfd>* value) { 38 if (type == LONG) { 39 return value; 40 } 41 ALOGE("%s: Value of type 'ifd' is not valid for tag with TIFF type %d.", 42 __FUNCTION__, type); 43 return NULL; 44 } 45 46 template<> 47 const uint8_t* TiffEntry::forceValidType<uint8_t>(TagType type, const uint8_t* value) { 48 if (type == BYTE || type == ASCII || type == UNDEFINED) { 49 return value; 50 } 51 ALOGE("%s: Value of type 'uint8_t' is not valid for tag with TIFF type %d.", 52 __FUNCTION__, type); 53 return NULL; 54 } 55 56 template<> 57 const int8_t* TiffEntry::forceValidType<int8_t>(TagType type, const int8_t* value) { 58 if (type == SBYTE || type == ASCII || type == UNDEFINED) { 59 return value; 60 } 61 ALOGE("%s: Value of type 'int8_t' is not valid for tag with TIFF type %d.", 62 __FUNCTION__, type); 63 return NULL; 64 } 65 66 template<> 67 const uint16_t* TiffEntry::forceValidType<uint16_t>(TagType type, const uint16_t* value) { 68 if (type == SHORT) { 69 return value; 70 } 71 ALOGE("%s: Value of type 'uint16_t' is not valid for tag with TIFF type %d.", 72 __FUNCTION__, type); 73 return NULL; 74 } 75 76 template<> 77 const int16_t* TiffEntry::forceValidType<int16_t>(TagType type, const int16_t* value) { 78 if (type == SSHORT) { 79 return value; 80 } 81 ALOGE("%s: Value of type 'int16_t' is not valid for tag with TIFF type %d.", 82 __FUNCTION__, type); 83 return NULL; 84 } 85 86 template<> 87 const uint32_t* TiffEntry::forceValidType<uint32_t>(TagType type, const uint32_t* value) { 88 if (type == LONG || type == RATIONAL) { 89 return value; 90 } 91 ALOGE("%s: Value of type 'uint32_t' is not valid for tag with TIFF type %d.", 92 __FUNCTION__, type); 93 return NULL; 94 } 95 96 template<> 97 const int32_t* TiffEntry::forceValidType<int32_t>(TagType type, const int32_t* value) { 98 if (type == SLONG || type == SRATIONAL) { 99 return value; 100 } 101 ALOGE("%s: Value of type 'int32_t' is not valid for tag with TIFF type %d.", 102 __FUNCTION__, type); 103 return NULL; 104 } 105 106 template<> 107 const double* TiffEntry::forceValidType<double>(TagType type, const double* value) { 108 if (type == DOUBLE) { 109 return value; 110 } 111 ALOGE("%s: Value of type 'double' is not valid for tag with TIFF type %d.", 112 __FUNCTION__, type); 113 return NULL; 114 } 115 116 template<> 117 const float* TiffEntry::forceValidType<float>(TagType type, const float* value) { 118 if (type == FLOAT) { 119 return value; 120 } 121 ALOGE("%s: Value of type 'float' is not valid for tag with TIFF type %d.", 122 __FUNCTION__, type); 123 return NULL; 124 } 125 126 String8 TiffEntry::toString() const { 127 String8 output; 128 uint32_t count = getCount(); 129 output.appendFormat("[id: %x, type: %d, count: %u, value: '", getTag(), getType(), count); 130 131 size_t cappedCount = count; 132 if (count > MAX_PRINT_STRING_LENGTH) { 133 cappedCount = MAX_PRINT_STRING_LENGTH; 134 } 135 136 TagType type = getType(); 137 switch (type) { 138 case UNDEFINED: 139 case BYTE: { 140 const uint8_t* typed_data = getData<uint8_t>(); 141 for (size_t i = 0; i < cappedCount; ++i) { 142 output.appendFormat("%u ", typed_data[i]); 143 } 144 break; 145 } 146 case ASCII: { 147 const char* typed_data = reinterpret_cast<const char*>(getData<uint8_t>()); 148 size_t len = count; 149 if (count > MAX_PRINT_STRING_LENGTH) { 150 len = MAX_PRINT_STRING_LENGTH; 151 } 152 output.append(typed_data, len); 153 break; 154 } 155 case SHORT: { 156 const uint16_t* typed_data = getData<uint16_t>(); 157 for (size_t i = 0; i < cappedCount; ++i) { 158 output.appendFormat("%u ", typed_data[i]); 159 } 160 break; 161 } 162 case LONG: { 163 const uint32_t* typed_data = getData<uint32_t>(); 164 for (size_t i = 0; i < cappedCount; ++i) { 165 output.appendFormat("%u ", typed_data[i]); 166 } 167 break; 168 } 169 case RATIONAL: { 170 const uint32_t* typed_data = getData<uint32_t>(); 171 cappedCount <<= 1; 172 for (size_t i = 0; i < cappedCount; i+=2) { 173 output.appendFormat("%u/%u ", typed_data[i], typed_data[i + 1]); 174 } 175 break; 176 } 177 case SBYTE: { 178 const int8_t* typed_data = getData<int8_t>(); 179 for (size_t i = 0; i < cappedCount; ++i) { 180 output.appendFormat("%d ", typed_data[i]); 181 } 182 break; 183 } 184 case SSHORT: { 185 const int16_t* typed_data = getData<int16_t>(); 186 for (size_t i = 0; i < cappedCount; ++i) { 187 output.appendFormat("%d ", typed_data[i]); 188 } 189 break; 190 } 191 case SLONG: { 192 const int32_t* typed_data = getData<int32_t>(); 193 for (size_t i = 0; i < cappedCount; ++i) { 194 output.appendFormat("%d ", typed_data[i]); 195 } 196 break; 197 } 198 case SRATIONAL: { 199 const int32_t* typed_data = getData<int32_t>(); 200 cappedCount <<= 1; 201 for (size_t i = 0; i < cappedCount; i+=2) { 202 output.appendFormat("%d/%d ", typed_data[i], typed_data[i + 1]); 203 } 204 break; 205 } 206 case FLOAT: { 207 const float* typed_data = getData<float>(); 208 for (size_t i = 0; i < cappedCount; ++i) { 209 output.appendFormat("%f ", typed_data[i]); 210 } 211 break; 212 } 213 case DOUBLE: { 214 const double* typed_data = getData<double>(); 215 for (size_t i = 0; i < cappedCount; ++i) { 216 output.appendFormat("%f ", typed_data[i]); 217 } 218 break; 219 } 220 default: { 221 output.append("unknown type "); 222 break; 223 } 224 } 225 226 if (count > MAX_PRINT_STRING_LENGTH) { 227 output.append("..."); 228 } 229 output.append("']"); 230 return output; 231 } 232 233 } /*namespace img_utils*/ 234 } /*namespace android*/ 235