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 #ifndef IMG_UTILS_TIFF_HELPERS_H
18 #define IMG_UTILS_TIFF_HELPERS_H
19 
20 #include <stdint.h>
21 
22 namespace android {
23 namespace img_utils {
24 
25 const uint8_t ZERO_WORD[] = {0, 0, 0, 0};
26 
27 #define BAIL_ON_FAIL(x, flag) \
28     if (((flag) = (x)) != OK) return flag;
29 
30 #define BYTES_TILL_WORD(index) \
31     ((TIFF_WORD_SIZE - ((index) % TIFF_WORD_SIZE)) % TIFF_WORD_SIZE)
32 
33 #define WORD_ALIGN(count) \
34     count += BYTES_TILL_WORD(count);
35 
36 #define ZERO_TILL_WORD(output, index, ret) \
37     { \
38         size_t remaining = BYTES_TILL_WORD(index); \
39         if (remaining > 0) { \
40             BAIL_ON_FAIL((output)->write(ZERO_WORD, 0, remaining), ret); \
41         } \
42     }
43 
44 /**
45  * Basic TIFF header constants.
46  */
47 enum {
48     BAD_OFFSET = 0,
49     TIFF_WORD_SIZE = 4, // Size in bytes
50     IFD_HEADER_SIZE = 2, // Size in bytes
51     IFD_FOOTER_SIZE = 4, // Size in bytes
52     TIFF_ENTRY_SIZE = 12, // Size in bytes
53     MAX_IFD_ENTRIES = UINT16_MAX,
54     FILE_HEADER_SIZE = 8, // Size in bytes
55     ENDIAN_MARKER_SIZE = 2, // Size in bytes
56     TIFF_MARKER_SIZE = 2, // Size in bytes
57     OFFSET_MARKER_SIZE = 4, // Size in bytes
58     TIFF_FILE_MARKER = 42,
59     BIG_ENDIAN_MARKER = 0x4D4Du,
60     LITTLE_ENDIAN_MARKER = 0x4949u
61 };
62 
63 /**
64  * Constants for the TIFF tag types.
65  */
66 enum TagType {
67     UNKNOWN_TAGTYPE = 0,
68     BYTE=1,
69     ASCII,
70     SHORT,
71     LONG,
72     RATIONAL,
73     SBYTE,
74     UNDEFINED,
75     SSHORT,
76     SLONG,
77     SRATIONAL,
78     FLOAT,
79     DOUBLE
80 };
81 
82 /**
83  * Sizes of the TIFF entry fields (in bytes).
84  */
85 enum {
86     TAG_SIZE = 2,
87     TYPE_SIZE = 2,
88     COUNT_SIZE = 4,
89     OFFSET_SIZE = 4
90 };
91 
92 /**
93  * Convenience IFD id constants.
94  */
95 enum {
96     IFD_0 = 0,
97     RAW_IFD,
98     PROFILE_IFD,
99     PREVIEW_IFD
100 };
101 
getTypeSize(TagType type)102 inline size_t getTypeSize(TagType type) {
103     switch(type) {
104         case UNDEFINED:
105         case ASCII:
106         case BYTE:
107         case SBYTE:
108             return 1;
109         case SHORT:
110         case SSHORT:
111             return 2;
112         case LONG:
113         case SLONG:
114         case FLOAT:
115             return 4;
116         case RATIONAL:
117         case SRATIONAL:
118         case DOUBLE:
119             return 8;
120         default:
121             return 0;
122     }
123 }
124 
calculateIfdSize(size_t numberOfEntries)125 inline uint32_t calculateIfdSize(size_t numberOfEntries) {
126     return IFD_HEADER_SIZE + IFD_FOOTER_SIZE + TIFF_ENTRY_SIZE * numberOfEntries;
127 }
128 
129 } /*namespace img_utils*/
130 } /*namespace android*/
131 
132 #endif /*IMG_UTILS_TIFF_HELPERS_H*/
133