1e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/*
2e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Copyright 2014 The Android Open Source Project
3e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
4e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * you may not use this file except in compliance with the License.
6e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * You may obtain a copy of the License at
7e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
8e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
10e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * See the License for the specific language governing permissions and
14e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * limitations under the License.
15e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
16e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
17e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#ifndef IMG_UTILS_TIFF_HELPERS_H
18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define IMG_UTILS_TIFF_HELPERS_H
19e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
20e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <stdint.h>
21e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
22e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android {
23e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils {
24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkconst uint8_t ZERO_WORD[] = {0, 0, 0, 0};
26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
27e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define BAIL_ON_FAIL(x, flag) \
28482343e68853e137c293d4db1e861353ab483ab7Chih-Hung Hsieh    if (((flag) = (x)) != OK) return flag;
29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define BYTES_TILL_WORD(index) \
31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    ((TIFF_WORD_SIZE - ((index) % TIFF_WORD_SIZE)) % TIFF_WORD_SIZE)
32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define WORD_ALIGN(count) \
34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    count += BYTES_TILL_WORD(count);
35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#define ZERO_TILL_WORD(output, index, ret) \
37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    { \
38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        size_t remaining = BYTES_TILL_WORD(index); \
39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        if (remaining > 0) { \
404510de26e5361f3a9f07057ec6f26483c888c1faRuben Brunk            BAIL_ON_FAIL((output)->write(ZERO_WORD, 0, remaining), ret); \
41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        } \
42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
45e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Basic TIFF header constants.
46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkenum {
48e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BAD_OFFSET = 0,
49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TIFF_WORD_SIZE = 4, // Size in bytes
50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    IFD_HEADER_SIZE = 2, // Size in bytes
51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    IFD_FOOTER_SIZE = 4, // Size in bytes
52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TIFF_ENTRY_SIZE = 12, // Size in bytes
53e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    MAX_IFD_ENTRIES = UINT16_MAX,
54e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    FILE_HEADER_SIZE = 8, // Size in bytes
55e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    ENDIAN_MARKER_SIZE = 2, // Size in bytes
56e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TIFF_MARKER_SIZE = 2, // Size in bytes
57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    OFFSET_MARKER_SIZE = 4, // Size in bytes
58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TIFF_FILE_MARKER = 42,
59e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BIG_ENDIAN_MARKER = 0x4D4Du,
60e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    LITTLE_ENDIAN_MARKER = 0x4949u
61e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
62e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
63e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
64e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Constants for the TIFF tag types.
65e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
66e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkenum TagType {
67e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    UNKNOWN_TAGTYPE = 0,
68e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    BYTE=1,
69e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    ASCII,
70e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    SHORT,
71e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    LONG,
72e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    RATIONAL,
73e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    SBYTE,
74e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    UNDEFINED,
75e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    SSHORT,
76e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    SLONG,
77e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    SRATIONAL,
78e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    FLOAT,
79e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    DOUBLE
80e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
81e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
82e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
83e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Sizes of the TIFF entry fields (in bytes).
84e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
85e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkenum {
86e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TAG_SIZE = 2,
87e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    TYPE_SIZE = 2,
88e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    COUNT_SIZE = 4,
89e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    OFFSET_SIZE = 4
90e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
91e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
92e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/**
93e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Convenience IFD id constants.
94e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
95e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkenum {
96e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    IFD_0 = 0,
97e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    RAW_IFD,
98e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    PROFILE_IFD,
99e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    PREVIEW_IFD
100e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk};
101e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
102e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkinline size_t getTypeSize(TagType type) {
103e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    switch(type) {
104e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case UNDEFINED:
105e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case ASCII:
106e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case BYTE:
107e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case SBYTE:
108e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return 1;
109e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case SHORT:
110e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case SSHORT:
111e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return 2;
112e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case LONG:
113e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case SLONG:
114e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case FLOAT:
115e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return 4;
116e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case RATIONAL:
117e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case SRATIONAL:
118e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case DOUBLE:
119e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return 8;
120e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        default:
121e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return 0;
122e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
123e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
124e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
125e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkinline uint32_t calculateIfdSize(size_t numberOfEntries) {
126e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return IFD_HEADER_SIZE + IFD_FOOTER_SIZE + TIFF_ENTRY_SIZE * numberOfEntries;
127e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
128e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
129e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/
130e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/
131e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
132e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#endif /*IMG_UTILS_TIFF_HELPERS_H*/
133