exynos: add libion dependencies
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libhwjpeg / IFDWriter.h
CommitLineData
5763fb39
T
1/*
2 * Copyright Samsung Electronics Co.,LTD.
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17#ifndef __HARDWARE_SAMSUNG_SLSI_EXYNOS_IFDWRITER_H__
18#define __HARDWARE_SAMSUNG_SLSI_EXYNOS_IFDWRITER_H__
19
20#include "hwjpeg-internal.h"
21
22class CEndianessChecker {
23 bool __little;
24public:
25 CEndianessChecker();
26 operator bool() { return __little; }
27};
28
6f7be8c2 29extern CEndianessChecker __LITTLE_ENDIAN_HWJPEG__;
5763fb39
T
30
31template <typename T>
32char *WriteDataInBig(char *p, T val)
33{
34 if (sizeof(val) == 1) {
35 *p++ = val;
6f7be8c2 36 } else if (__LITTLE_ENDIAN_HWJPEG__) {
5763fb39
T
37 switch (sizeof(val)) {
38 case 2:
39 *p++ = static_cast<char>((val >> 8) & 0xFF);
40 *p++ = static_cast<char>(val & 0xFF);
41 break;
42 case 4:
43 *p++ = static_cast<char>((val >> 24) & 0xFF);
44 *p++ = static_cast<char>((val >> 16) & 0xFF);
45 *p++ = static_cast<char>((val >> 8) & 0xFF);
46 *p++ = static_cast<char>(val & 0xFF);
47 break;
48 }
49 } else {
50 switch (sizeof(val)) {
51 case 2:
52 *p++ = static_cast<char>(val & 0xFF);
53 *p++ = static_cast<char>((val >> 8) & 0xFF);
54 break;
55 case 4:
56 *p++ = static_cast<char>(val & 0xFF);
57 *p++ = static_cast<char>((val >> 8) & 0xFF);
58 *p++ = static_cast<char>((val >> 16) & 0xFF);
59 *p++ = static_cast<char>((val >> 24) & 0xFF);
60 break;
61 }
62 }
63
64 return p;
65}
66
67template <typename T>
68char *WriteData(char *p, T val)
69{
70 const char *pt = reinterpret_cast<char *>(&val);
71 for (size_t i = 0; i < sizeof(val); i++)
72 *p++ = *pt++;
73 return p;
74}
75
76class CIFDWriter {
77 char *m_pBase;
78 char *m_pIFDBase;
79 char *m_pValue;
80 unsigned int m_nTags;
81
82 char *WriteOffset(char *target, char *addr) {
83 uint32_t val = Offset(addr);
84 const char *p = reinterpret_cast<char *>(&val);
85 *target++ = *p++;
86 *target++ = *p++;
87 *target++ = *p++;
88 *target++ = *p++;
89 return target;
90 }
91
92 void WriteTagTypeCount(uint16_t tag, uint16_t type, uint32_t count) {
93 const char *p = reinterpret_cast<char *>(&tag);
94 *m_pIFDBase++ = *p++;
95 *m_pIFDBase++ = *p++;
96
97 p = reinterpret_cast<char *>(&type);
98 *m_pIFDBase++ = *p++;
99 *m_pIFDBase++ = *p++;
100
101 p = reinterpret_cast<char *>(&count);
102 *m_pIFDBase++ = *p++;
103 *m_pIFDBase++ = *p++;
104 *m_pIFDBase++ = *p++;
105 *m_pIFDBase++ = *p++;
106
107 m_nTags--;
108 }
109public:
110 CIFDWriter(char *offset_base, char *ifdbase, uint16_t tagcount) {
111 m_nTags = tagcount;
112 m_pBase = offset_base;
113 m_pIFDBase = ifdbase;
114 m_pValue = m_pIFDBase + IFD_FIELDCOUNT_SIZE +
115 IFD_FIELD_SIZE * tagcount + IFD_NEXTIFDOFFSET_SIZE;
116
117 // COUNT field of IFD
118 const char *pval = reinterpret_cast<char *>(&m_nTags);
119 *m_pIFDBase++ = *pval++;
120 *m_pIFDBase++ = *pval++;
121 }
122
123 uint32_t Offset(char *p) {
124 return static_cast<uint32_t>(PTR_TO_ULONG(p) - PTR_TO_ULONG(m_pBase));
125 }
126
127 void WriteByte(uint16_t tag, uint32_t count, const uint8_t value[]) {
128 ALOG_ASSERT(m_nTags == 0);
129
130 WriteTagTypeCount(tag, EXIF_TYPE_BYTE, count);
131
132 if (count > IFD_VALOFF_SIZE) {
133 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
134 for (uint32_t i = 0; i < count; i++) {
135 *m_pValue++ = static_cast<char>(value[i]);
136 }
137 } else {
138 for (uint32_t i = 0; i < count; i++)
139 *m_pIFDBase++ = static_cast<char>(value[i]);
140 m_pIFDBase += IFD_VALOFF_SIZE - count;
141 }
142 }
143
144 void WriteShort(uint16_t tag, uint32_t count, const uint16_t value[]) {
145 ALOG_ASSERT(m_nTags == 0);
146
147 WriteTagTypeCount(tag, EXIF_TYPE_SHORT, count);
148
149 const char *p = reinterpret_cast<const char *>(&value[0]);
150
151 if (count > (IFD_VALOFF_SIZE / sizeof(value[0]))) {
152 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
153 for (uint32_t i = 0; i < count; i++) {
154 *m_pValue++ = *p++;
155 *m_pValue++ = *p++;
156 }
157 } else {
158 for (uint32_t i = 0; i < count; i++) {
159 *m_pIFDBase++ = *p++;
160 *m_pIFDBase++ = *p++;
161 }
162 m_pIFDBase += IFD_VALOFF_SIZE - count * sizeof(value[0]);
163 }
164 }
165
166 void WriteLong(uint16_t tag, uint32_t count, const uint32_t value[]) {
167 ALOG_ASSERT(m_nTags == 0);
168
169 WriteTagTypeCount(tag, EXIF_TYPE_LONG, count);
170
171 const char *p = reinterpret_cast<const char *>(&value[0]);
172 if (count > (IFD_VALOFF_SIZE / sizeof(value[0]))) {
173 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
174 *m_pValue++ = *p++;
175 } else {
176 *m_pIFDBase++ = *p++;
177 *m_pIFDBase++ = *p++;
178 *m_pIFDBase++ = *p++;
179 *m_pIFDBase++ = *p++;
180 }
181 }
182
183 void WriteASCII(uint16_t tag, uint32_t count, const char *value) {
184 ALOG_ASSERT(m_nTags == 0);
185
186 WriteTagTypeCount(tag, EXIF_TYPE_ASCII, count);
187
188 if (count > IFD_VALOFF_SIZE) {
189 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
190 memcpy(m_pValue, value, count);
191 m_pValue[count - 1] = '\0';
192 m_pValue += count;
193 } else {
194 for (uint32_t i = 0; i < count; i++)
195 *m_pIFDBase++ = value[i];
196 *(m_pIFDBase - 1) = '\0';
197 m_pIFDBase += IFD_VALOFF_SIZE - count;
198 }
199 }
200
201 void WriteCString(uint16_t tag, uint32_t count, const char *string) {
202 ALOG_ASSERT(m_nTags == 0);
203
204 WriteTagTypeCount(tag, EXIF_TYPE_ASCII, count);
205
206 if (count > IFD_VALOFF_SIZE) {
207 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
208 strncpy(m_pValue, string, count);
209 m_pValue[count - 1] = '\0';
210 m_pValue += count;
211 } else {
212 uint32_t i;
213
214 for (i = 0; (i < (count - 1)) && (string[i] != '\0'); i++)
215 *m_pIFDBase++ = string[i];
216
217 while (i++ < count)
218 *m_pIFDBase++ = '\0';
219
220 m_pIFDBase += IFD_VALOFF_SIZE - count;
221 }
222 }
223
224 void WriteRational(uint16_t tag, uint32_t count, const rational_t value[]) {
225 ALOG_ASSERT(m_nTags == 0);
226
227 WriteTagTypeCount(tag, EXIF_TYPE_RATIONAL, count);
228 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
229
230 for (uint32_t i = 0; i < count; i++) {
231 const char *pt;
232 pt = reinterpret_cast<const char *>(&value[i].num);
233 *m_pValue++ = *pt++;
234 *m_pValue++ = *pt++;
235 *m_pValue++ = *pt++;
236 *m_pValue++ = *pt++;
237 pt = reinterpret_cast<const char *>(&value[i].den);
238 *m_pValue++ = *pt++;
239 *m_pValue++ = *pt++;
240 *m_pValue++ = *pt++;
241 *m_pValue++ = *pt++;
242 }
243 }
244
245 void WriteSRational(uint16_t tag, uint32_t count, const srational_t value[]) {
246 ALOG_ASSERT(m_nTags == 0);
247
248 WriteTagTypeCount(tag, EXIF_TYPE_SRATIONAL, count);
249 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
250
251 const char *pt = reinterpret_cast<const char *>(value);
252 for (uint32_t i = 0; i < sizeof(srational_t) * count; i++)
253 *m_pValue++ = *pt++;
254 }
255
256 void WriteUndef(uint16_t tag, uint32_t count, const unsigned char *value) {
257 ALOG_ASSERT(m_nTags == 0);
258
259 WriteTagTypeCount(tag, EXIF_TYPE_UNDEFINED, count);
260 if (count > IFD_VALOFF_SIZE) {
261 m_pIFDBase = WriteOffset(m_pIFDBase, m_pValue);
262 memcpy(m_pValue, value, count);
263 m_pValue += count;
264 } else {
265 for (uint32_t i = 0; i < count; i++)
266 *m_pIFDBase++ = static_cast<char>(value[i]);
267 m_pIFDBase += IFD_VALOFF_SIZE - count;
268 }
269 }
270
271 char *BeginSubIFD(uint16_t tag) {
272 ALOG_ASSERT(m_nTags == 0);
273
274 WriteTagTypeCount(tag, EXIF_TYPE_LONG, 1);
275
276 uint32_t offset = Offset(m_pValue);
277 const char *poff = reinterpret_cast<char *>(&offset);
278 *m_pIFDBase++ = *poff++;
279 *m_pIFDBase++ = *poff++;
280 *m_pIFDBase++ = *poff++;
281 *m_pIFDBase++ = *poff++;
282
283 return m_pValue;
284 }
285
286 void EndSubIFD(char *end_of_subIFD) { m_pValue = end_of_subIFD; }
287 void CancelSubIFD() { m_pIFDBase -= IFD_FIELD_SIZE; }
288
289 void Finish(bool last) {
290 ALOG_ASSERT(m_nTags > 0);
291
292 uint32_t offset = last ? 0 : Offset(m_pValue);
293 const char *pv = reinterpret_cast<char *>(&offset);
294 *m_pIFDBase++ = *pv++;
295 *m_pIFDBase++ = *pv++;
296 *m_pIFDBase++ = *pv++;
297 *m_pIFDBase++ = *pv++;
298 }
299
300 char *GetNextIFDBase() { return m_pValue; }
301 char *GetNextTagAddress() { return m_pIFDBase; }
302};
303
304#endif //__HARDWARE_SAMSUNG_SLSI_EXYNOS_IFDWRITER_H__