You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.9 KiB
140 lines
4.9 KiB
/*
|
|
* Copyright Samsung Electronics Co.,LTD.
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef __HARDWARE_SAMSUNG_SLSI_EXYNOS_APPMARKER_WRITER_H__
|
|
#define __HARDWARE_SAMSUNG_SLSI_EXYNOS_APPMARKER_WRITER_H__
|
|
|
|
#include <ExynosExif.h>
|
|
#include "include/hardware/exynos/ExynosExif.h"
|
|
|
|
#define JPEG_MAX_SEGMENT_SIZE ((1 << 16) - 1)
|
|
#define JPEG_MARKER_SIZE 2
|
|
#define JPEG_SEGMENT_LENFIELD_SIZE 2
|
|
#define JPEG_APP1_OEM_RESERVED 200
|
|
|
|
#define IFD_FIELDCOUNT_SIZE 2
|
|
#define IFD_NEXTIFDOFFSET_SIZE 4
|
|
|
|
#define IFD_TAG_SIZE 2
|
|
#define IFD_TYPE_SIZE 2
|
|
#define IFD_COUNT_SIZE 4
|
|
#define IFD_VALOFF_SIZE 4
|
|
|
|
#define IFD_FIELD_SIZE \
|
|
(IFD_TAG_SIZE + IFD_TYPE_SIZE + IFD_COUNT_SIZE + IFD_VALOFF_SIZE)
|
|
|
|
#define EXTRA_APPMARKER_MIN 4
|
|
#define EXTRA_APPMARKER_LIMIT 10
|
|
|
|
#define MAX_GPS_PROCESSINGMETHOD_SIZE 108
|
|
|
|
#define EXIF_SUBSECTIME_LENGTH 5
|
|
#define EXIF_DATETIME_LENGTH 20
|
|
#define EXIF_GPSDATESTAMP_LENGTH 11
|
|
|
|
class CAppMarkerWriter {
|
|
char *m_pAppBase;
|
|
char *m_pApp1End;
|
|
size_t m_szMaxThumbSize; // Maximum available thumbnail stream size minus JPEG_MARKER_SIZE
|
|
uint16_t m_szApp1; // The size of APP1 segment without marker
|
|
uint16_t m_szApp11; // The size of APP11 segment without marker
|
|
uint16_t m_n0thIFDFields;
|
|
uint16_t m_n1stIFDFields;
|
|
uint16_t m_nExifIFDFields;
|
|
uint16_t m_nGPSIFDFields;
|
|
exif_attribute_t *m_pExif;
|
|
extra_appinfo_t *m_pExtra;
|
|
|
|
uint32_t m_szMake;
|
|
uint32_t m_szSoftware;
|
|
uint32_t m_szModel;
|
|
uint32_t m_szUniqueID;
|
|
|
|
char *m_pMainBase;
|
|
// The address to write compressed stream of the thumbnail image
|
|
char *m_pThumbBase;
|
|
// points to the "ValueOffset" field of JPEGInterchangeFormatLen tag of 1st IFD
|
|
// This should be updated after compression of thumbnail image.
|
|
// Note that the address may not be aligned by 32-bit.
|
|
char *m_pThumbSizePlaceholder;
|
|
|
|
void Init();
|
|
|
|
char *WriteAPP1(char *base, bool reserve_thumbnail_space, bool updating = false);
|
|
char *WriteAPPX(char *base, bool just_reserve);
|
|
char *WriteAPP11(char *current, size_t dummy, size_t align);
|
|
public:
|
|
// dummy: number of dummy bytes written by the compressor of the main image
|
|
// this dummy size should be added to the APP1 length. Howerver, this dummy area
|
|
// for the main image stream should not be written by neither of appwriter nor
|
|
// thumbnail compressor.
|
|
CAppMarkerWriter();
|
|
CAppMarkerWriter(char *base, exif_attribute_t *exif, debug_attribute_t *debug);
|
|
|
|
~CAppMarkerWriter() { }
|
|
|
|
void PrepareAppWriter(char *base, exif_attribute_t *exif, extra_appinfo_t *info);
|
|
|
|
char *GetMainStreamBase() { return m_pMainBase; }
|
|
char *GetThumbStreamBase() { return m_pThumbBase; }
|
|
char *GetThumbStreamSizeAddr() {
|
|
char *p = m_pThumbSizePlaceholder;
|
|
m_pThumbSizePlaceholder = NULL;
|
|
return p;
|
|
}
|
|
size_t GetMaxThumbnailSize() { return m_szMaxThumbSize; }
|
|
size_t GetAPP1ResrevedSize() { return JPEG_APP1_OEM_RESERVED; }
|
|
// CalculateAPPSize() is valid after Write() is successful.
|
|
size_t CalculateAPPSize(size_t thumblen = JPEG_MAX_SEGMENT_SIZE) {
|
|
size_t appsize = 0;
|
|
if (m_szApp1 > 0)
|
|
appsize += m_szApp1 + JPEG_MARKER_SIZE;
|
|
if (m_pExtra) {
|
|
for (int idx = 0; idx < m_pExtra->num_of_appmarker; idx++)
|
|
appsize += m_pExtra->appInfo[idx].dataSize +
|
|
+ JPEG_MARKER_SIZE + JPEG_SEGMENT_LENFIELD_SIZE;
|
|
}
|
|
if (IsThumbSpaceReserved())
|
|
appsize += m_szMaxThumbSize + JPEG_APP1_OEM_RESERVED ;
|
|
else
|
|
appsize += min(m_szMaxThumbSize, thumblen);
|
|
|
|
return appsize + m_szApp11;
|
|
}
|
|
|
|
char *GetApp1End() { return m_pApp1End; }
|
|
|
|
void Write(bool reserve_thumbnail_space, size_t dummy, size_t align, bool reserve_debug = false) {
|
|
m_pApp1End = WriteAPP1(m_pAppBase, reserve_thumbnail_space);
|
|
char *appXend = WriteAPPX(m_pApp1End, reserve_debug);
|
|
char *app11end = WriteAPP11(appXend, dummy, align);
|
|
m_szApp11 = PTR_DIFF(appXend, app11end);
|
|
m_pMainBase = app11end - dummy;
|
|
}
|
|
|
|
void Update() { WriteAPP1(m_pAppBase, false, true); }
|
|
|
|
bool IsThumbSpaceReserved() {
|
|
return PTR_DIFF(m_pAppBase, m_pApp1End) ==
|
|
(m_szApp1 + m_szMaxThumbSize + JPEG_APP1_OEM_RESERVED + JPEG_MARKER_SIZE);
|
|
}
|
|
|
|
void Finalize(size_t thumbsize);
|
|
|
|
void UpdateApp1Size(size_t amount);
|
|
};
|
|
#endif //__HARDWARE_SAMSUNG_SLSI_EXYNOS_APPMARKER_WRITER_H__
|