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
~TiffEntry()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<>
forceValidType(TagType type,const sp<TiffIfd> * value)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<>
forceValidType(TagType type,const uint8_t * value)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<>
forceValidType(TagType type,const int8_t * value)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<>
forceValidType(TagType type,const uint16_t * value)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<>
forceValidType(TagType type,const int16_t * value)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<>
forceValidType(TagType type,const uint32_t * value)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<>
forceValidType(TagType type,const int32_t * value)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<>
forceValidType(TagType type,const double * value)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<>
forceValidType(TagType type,const float * value)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
toString() const126 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