Commit | Line | Data |
---|---|---|
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_APPMARKER_WRITER_H__ | |
18 | #define __HARDWARE_SAMSUNG_SLSI_EXYNOS_APPMARKER_WRITER_H__ | |
19 | ||
20 | #include <ExynosExif.h> | |
21 | ||
6f7be8c2 | 22 | #define JPEG_MAX_SEGMENT_SIZE ((1 << 16) - 1 - 100) |
5763fb39 T |
23 | #define JPEG_MARKER_SIZE 2 |
24 | #define JPEG_SEGMENT_LENFIELD_SIZE 2 | |
25 | ||
26 | #define IFD_FIELDCOUNT_SIZE 2 | |
27 | #define IFD_NEXTIFDOFFSET_SIZE 4 | |
28 | ||
29 | #define IFD_TAG_SIZE 2 | |
30 | #define IFD_TYPE_SIZE 2 | |
31 | #define IFD_COUNT_SIZE 4 | |
32 | #define IFD_VALOFF_SIZE 4 | |
33 | ||
34 | #define IFD_FIELD_SIZE \ | |
35 | (IFD_TAG_SIZE + IFD_TYPE_SIZE + IFD_COUNT_SIZE + IFD_VALOFF_SIZE) | |
36 | ||
37 | #define EXTRA_APPMARKER_MIN 4 | |
38 | #define EXTRA_APPMARKER_LIMIT 10 | |
39 | ||
40 | #define MAX_GPS_PROCESSINGMETHOD_SIZE 108 | |
41 | ||
42 | #define EXIF_SUBSECTIME_LENGTH 5 | |
43 | #define EXIF_DATETIME_LENGTH 20 | |
44 | #define EXIF_GPSDATESTAMP_LENGTH 11 | |
45 | ||
46 | class CAppMarkerWriter { | |
47 | char *m_pAppBase; | |
48 | char *m_pApp1End; | |
49 | size_t m_szMaxThumbSize; // Maximum available thumbnail stream size minus JPEG_MARKER_SIZE | |
50 | uint16_t m_szApp1; // The size of APP1 segment without marker | |
51 | uint16_t m_szApp11; // The size of APP11 segment without marker | |
52 | uint16_t m_n0thIFDFields; | |
53 | uint16_t m_n1stIFDFields; | |
54 | uint16_t m_nExifIFDFields; | |
55 | uint16_t m_nGPSIFDFields; | |
56 | exif_attribute_t *m_pExif; | |
57 | debug_attribute_t *m_pDebug; | |
58 | ||
59 | uint32_t m_szMake; | |
60 | uint32_t m_szSoftware; | |
61 | uint32_t m_szModel; | |
6f7be8c2 JA |
62 | uint32_t m_szDateTime __unused; |
63 | uint32_t m_szSubsecTime __unused; | |
5763fb39 T |
64 | uint32_t m_szUniqueID; |
65 | ||
66 | char *m_pMainBase; | |
67 | // The address to write compressed stream of the thumbnail image | |
68 | char *m_pThumbBase; | |
69 | // points to the "ValueOffset" field of JPEGInterchangeFormatLen tag of 1st IFD | |
70 | // This should be updated after compression of thumbnail image. | |
71 | // Note that the address may not be aligned by 32-bit. | |
72 | char *m_pThumbSizePlaceholder; | |
73 | ||
74 | void Init(); | |
75 | ||
76 | char *WriteAPP1(char *base, bool reserve_thumbnail_space, bool updating = false); | |
77 | char *WriteAPPX(char *base, bool just_reserve); | |
78 | char *WriteAPP11(char *current, size_t dummy, size_t align); | |
79 | public: | |
80 | // dummy: number of dummy bytes written by the compressor of the main image | |
81 | // this dummy size should be added to the APP1 length. Howerver, this dummy area | |
82 | // for the main image stream should not be written by neither of appwriter nor | |
83 | // thumbnail compressor. | |
84 | CAppMarkerWriter(); | |
85 | CAppMarkerWriter(char *base, exif_attribute_t *exif, debug_attribute_t *debug); | |
86 | ||
87 | ~CAppMarkerWriter() { } | |
88 | ||
89 | void PrepareAppWriter(char *base, exif_attribute_t *exif, debug_attribute_t *debug); | |
90 | ||
91 | char *GetMainStreamBase() { return m_pMainBase; } | |
92 | char *GetThumbStreamBase() { return m_pThumbBase; } | |
93 | char *GetThumbStreamSizeAddr() { | |
94 | char *p = m_pThumbSizePlaceholder; | |
95 | m_pThumbSizePlaceholder = NULL; | |
96 | return p; | |
97 | } | |
98 | size_t GetMaxThumbnailSize() { return m_szMaxThumbSize; } | |
99 | // CalculateAPPSize() is valid after Write() is successful. | |
100 | size_t CalculateAPPSize(size_t thumblen = JPEG_MAX_SEGMENT_SIZE) { | |
101 | size_t appsize = 0; | |
102 | if (m_szApp1 > 0) | |
103 | appsize += m_szApp1 + JPEG_MARKER_SIZE; | |
104 | if (m_pDebug) { | |
105 | for (int idx = 0; idx < m_pDebug->num_of_appmarker; idx++) | |
106 | appsize += m_pDebug->debugSize[m_pDebug->idx[idx][0]] | |
107 | + JPEG_MARKER_SIZE + JPEG_SEGMENT_LENFIELD_SIZE; | |
108 | } | |
109 | if (IsThumbSpaceReserved()) | |
110 | appsize += m_szMaxThumbSize; | |
111 | else | |
112 | appsize += min(m_szMaxThumbSize, thumblen); | |
113 | ||
114 | return appsize + m_szApp11; | |
115 | } | |
116 | ||
117 | char *GetApp1End() { return m_pApp1End; } | |
118 | ||
119 | void Write(bool reserve_thumbnail_space, size_t dummy, size_t align, bool reserve_debug = false) { | |
120 | m_pApp1End = WriteAPP1(m_pAppBase, reserve_thumbnail_space); | |
121 | char *appXend = WriteAPPX(m_pApp1End, reserve_debug); | |
122 | char *app11end = WriteAPP11(appXend, dummy, align); | |
123 | m_szApp11 = PTR_DIFF(appXend, app11end); | |
124 | m_pMainBase = app11end - dummy; | |
125 | } | |
126 | ||
127 | void Update() { WriteAPP1(m_pAppBase, false, true); } | |
128 | ||
129 | bool IsThumbSpaceReserved() { | |
130 | return PTR_DIFF(m_pAppBase, m_pApp1End) == (m_szApp1 + m_szMaxThumbSize + JPEG_MARKER_SIZE); | |
131 | } | |
132 | ||
133 | void Finalize(size_t thumbsize); | |
134 | ||
135 | void UpdateApp1Size(size_t amount); | |
136 | }; | |
137 | #endif //__HARDWARE_SAMSUNG_SLSI_EXYNOS_APPMARKER_WRITER_H__ |