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