blob: bbfe08556d8dcd5291ddf243274f1b95bcea5834 [file] [log] [blame]
/*
* Copyright (C) 2016-2020 Intel Corporation
*
* 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.
*/
#define LOG_TAG "JpegMaker"
#include "JpegMaker.h"
#include "iutils/CameraLog.h"
#include "iutils/Utils.h"
namespace icamera {
JpegMaker::JpegMaker() {
LOG2("@%s", __func__);
mExifMaker = std::unique_ptr<EXIFMaker>(new EXIFMaker());
}
JpegMaker::~JpegMaker() {
LOG2("@%s", __func__);
}
status_t JpegMaker::setupExifWithMetaData(int bufWidth, int bufHeight, const Parameters& parameter,
ExifMetaData* metaData) {
LOG2("@%s", __func__);
status_t status = OK;
status = processJpegSettings(parameter, metaData);
CheckError(status != OK, status, "@%s: Process settngs for JPEG failed!", __func__);
mExifMaker->initialize(bufWidth, bufHeight);
mExifMaker->pictureTaken(metaData);
mExifMaker->enableFlash(metaData->flashFired, metaData->v3AeMode, metaData->flashMode);
mExifMaker->updateSensorInfo(parameter);
mExifMaker->saveMakernote(parameter);
status = processExifSettings(parameter, metaData);
if (status != OK) {
LOGE("@%s: Process settngs for Exif! %d", __func__, status);
return status;
}
mExifMaker->initializeLocation(metaData);
mExifMaker->setSensorAeConfig(parameter);
if (metaData->software) mExifMaker->setSoftware(metaData->software);
return status;
}
status_t JpegMaker::getExif(const EncodePackage& thumbnailPackage, uint8_t* exifPtr,
uint32_t* exifSize) {
if (thumbnailPackage.encodedDataSize > 0 && thumbnailPackage.quality > 0) {
mExifMaker->setThumbnail(static_cast<unsigned char*>(thumbnailPackage.outputData),
thumbnailPackage.encodedDataSize, thumbnailPackage.outputWidth,
thumbnailPackage.outputHeight);
}
*exifSize = mExifMaker->makeExif(exifPtr);
return *exifSize > 0 ? OK : UNKNOWN_ERROR;
}
status_t JpegMaker::processExifSettings(const Parameters& params, ExifMetaData* metaData) {
LOG2("@%s:", __func__);
status_t status = OK;
status = processGpsSettings(params, metaData);
status |= processColoreffectSettings(params, metaData);
status |= processScalerCropSettings(params, metaData);
return status;
}
/* copy exif data into output buffer */
void JpegMaker::writeExifData(EncodePackage* package) {
CheckError(package == nullptr, VOID_VALUE, "@%s, package is nullptr", __func__);
if (package->exifDataSize == 0) return;
CheckError(!package->outputData, VOID_VALUE, "@%s, outputData is nullptr", __func__);
CheckError(!package->exifData, VOID_VALUE, "@%s, exifData is nullptr", __func__);
unsigned int jSOISize = sizeof(mJpegMarkerSOI);
unsigned char* jpegOut = reinterpret_cast<unsigned char*>(package->outputData);
MEMCPY_S(jpegOut, jSOISize, mJpegMarkerSOI, jSOISize);
jpegOut += jSOISize;
MEMCPY_S(jpegOut, package->exifDataSize, reinterpret_cast<unsigned char*>(package->exifData),
package->exifDataSize);
}
/**
* processJpegSettings
*
* Store JPEG settings to the exif metadata
*
* \param [IN] jpeg parameters
* \ metaData [out] metadata of the request
*
*/
status_t JpegMaker::processJpegSettings(const Parameters& params, ExifMetaData* metaData) {
LOG2("@%s:", __func__);
status_t status = OK;
CheckError(!metaData, UNKNOWN_ERROR, "MetaData struct not intialized");
// make jpeg with thumbnail or not
camera_resolution_t thumbSize = {0};
params.getJpegThumbnailSize(thumbSize);
LOG2("%s request thumbname size %dx%d", __func__, thumbSize.width, thumbSize.height);
uint8_t new_jpeg_quality = DEFAULT_JPEG_QUALITY;
int ret = params.getJpegQuality(&new_jpeg_quality);
if (ret != icamera::OK) {
LOGW("cannot find jpeg quality, use default");
}
metaData->mJpegSetting.jpegQuality = new_jpeg_quality;
uint8_t new_jpeg_thumb_quality = DEFAULT_JPEG_QUALITY;
params.getJpegThumbnailQuality(&new_jpeg_thumb_quality);
metaData->mJpegSetting.jpegThumbnailQuality = new_jpeg_thumb_quality;
metaData->mJpegSetting.thumbWidth = thumbSize.width;
metaData->mJpegSetting.thumbHeight = thumbSize.height;
int new_rotation = 0;
params.getJpegRotation(new_rotation);
metaData->mJpegSetting.orientation = new_rotation;
LOG1("jpegQuality=%d,thumbQuality=%d,thumbW=%d,thumbH=%d,orientation=%d",
metaData->mJpegSetting.jpegQuality, metaData->mJpegSetting.jpegThumbnailQuality,
metaData->mJpegSetting.thumbWidth, metaData->mJpegSetting.thumbHeight,
metaData->mJpegSetting.orientation);
params.getAeMode(metaData->aeMode);
params.getAwbMode(metaData->awbMode);
metaData->currentFocusDistance = 0.0;
float focusDistance = 0.0;
params.getFocusDistance(focusDistance);
if (focusDistance != 0) {
metaData->currentFocusDistance = ceil(1000.0 / focusDistance);
}
LOG2("aeMode=%d, awbMode=%d, currentFocusDistance=%f", metaData->aeMode, metaData->awbMode,
metaData->currentFocusDistance);
return status;
}
/**
* This function will get GPS metadata from request setting
*
* \param[in] settings The Anroid metadata to process GPS settings from
* \param[out] metadata The EXIF data where the GPS setting are written to
*/
status_t JpegMaker::processGpsSettings(const Parameters& param, ExifMetaData* metadata) {
LOG2("@%s:", __func__);
status_t status = OK;
// gps latitude
double new_gps_latitude = 0.0;
param.getJpegGpsLatitude(new_gps_latitude);
metadata->mGpsSetting.latitude = new_gps_latitude;
double new_gps_longitude = 0.0;
param.getJpegGpsLongitude(new_gps_longitude);
metadata->mGpsSetting.longitude = new_gps_longitude;
double new_gps_altitude = 0.0;
param.getJpegGpsAltitude(new_gps_altitude);
metadata->mGpsSetting.altitude = new_gps_altitude;
// gps timestamp
int64_t new_gps_timestamp = 0;
param.getJpegGpsTimeStamp(new_gps_timestamp);
metadata->mGpsSetting.gpsTimeStamp = new_gps_timestamp;
// gps processing method
char new_gps_processing_method[MAX_NUM_GPS_PROCESSING_METHOD + 1];
CLEAR(new_gps_processing_method);
param.getJpegGpsProcessingMethod(MAX_NUM_GPS_PROCESSING_METHOD, new_gps_processing_method);
if (strlen(new_gps_processing_method) != 0) {
snprintf(metadata->mGpsSetting.gpsProcessingMethod,
sizeof(metadata->mGpsSetting.gpsProcessingMethod), "%s",
new_gps_processing_method);
}
return status;
}
status_t JpegMaker::processColoreffectSettings(const Parameters& param, ExifMetaData* metaData) {
LOG2("@%s:", __func__);
status_t status = OK;
camera_effect_mode_t new_image_effect = CAM_EFFECT_NONE;
param.getImageEffect(new_image_effect);
metaData->effectMode = new_image_effect;
LOG2("effect mode=%d", metaData->effectMode);
return status;
}
status_t JpegMaker::processScalerCropSettings(const Parameters& param, ExifMetaData* metaData) {
LOG2("@%s:", __func__);
status_t status = OK;
return status;
}
} // namespace icamera