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