113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang/*
213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * Copyright Samsung Electronics Co.,LTD.
313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * Copyright (C) 2010 The Android Open Source Project
413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang *
513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * Licensed under the Apache License, Version 2.0 (the "License");
613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * you may not use this file except in compliance with the License.
713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * You may obtain a copy of the License at
813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang *
913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang *     http://www.apache.org/licenses/LICENSE-2.0
1013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang *
1113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * Unless required by applicable law or agreed to in writing, software
1213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * distributed under the License is distributed on an "AS IS" BASIS,
1313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * See the License for the specific language governing permissions and
1513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * limitations under the License.
1613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang */
1713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
1813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#include <utils/Log.h>
1913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
2013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#include "ExynosJpegEncoderForCamera.h"
2113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
2213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangstatic const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
2313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
2469d1e6e9c2036cc231544f61df9ee13e00d1fe0cSungjoong Kang#define JPEG_ERROR_LOG ALOGE
2569d1e6e9c2036cc231544f61df9ee13e00d1fe0cSungjoong Kang#define LOG_TAG "ExynosJpegForCamera"
2613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
2713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define JPEG_THUMBNAIL_QUALITY (60)
2813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define EXIF_LIMIT_SIZE (64*1024)
2913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define THUMBNAIL_IMAGE_PIXEL_SIZE (4)
3013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define MAX_JPG_WIDTH (8192)
3113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define MAX_JPG_HEIGHT (8192)
3213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
3313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define MAX_INPUT_BUFFER_PLANE_NUM (1)
3413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang#define MAX_OUTPUT_BUFFER_PLANE_NUM (1)
3513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
3613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong KangExynosJpegEncoderForCamera::ExynosJpegEncoderForCamera()
3713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
3813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_flagCreate = false;
3913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_jpegMain = NULL;
4013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_jpegThumb = NULL;
4113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailW = 0;
4213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailH = 0;
4313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
4413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_ionJpegClient = 0;
4513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    initJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
4613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    initJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);
47eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    initJpegMemory(&m_stMainInBuf, MAX_IMAGE_PLANE_NUM);
48eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    initJpegMemory(&m_stMainOutBuf, MAX_IMAGE_PLANE_NUM);
4913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
5013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
5113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong KangExynosJpegEncoderForCamera::~ExynosJpegEncoderForCamera()
5213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
5313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == true) {
5413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        this->destroy();
5513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
5613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
5713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
5813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangbool ExynosJpegEncoderForCamera::flagCreate(void)
5913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
6013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_flagCreate;
6113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
6213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
6313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::create(void)
6413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
6513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
6613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == true) {
6713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_ALREADY_CREATE;
6813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
6913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
7013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_jpegMain == NULL) {
7113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegMain = new ExynosJpegEncoder;
7213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
7313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (m_jpegMain == NULL) {
7413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("ERR(%s):Cannot create ExynosJpegEncoder class\n", __func__);
7513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
7613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
7713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
7813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ret = m_jpegMain->create();
7913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ret) {
8013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ret;
8113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
8213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
8313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ret = m_jpegMain->setCache(JPEG_CACHE_ON);
8413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
8513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ret) {
8613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            m_jpegMain->destroy();
8713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ret;
8813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
8913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
9013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
9113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_ionJpegClient = createIonClient(m_ionJpegClient);
9213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if(m_ionJpegClient == 0) {
9313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
9413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
95eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainOutBuf.ionClient = m_stMainInBuf.ionClient = m_stThumbInBuf.ionClient = m_stThumbOutBuf.ionClient = m_ionJpegClient;
9613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
9713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_flagCreate = true;
9813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
9913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
10013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
10113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
10213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::destroy(void)
10313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
10413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
10513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_ALREADY_DESTROY;
10613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
10713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
10813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_jpegMain != NULL) {
10913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegMain->destroy();
11013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        delete m_jpegMain;
11113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegMain = NULL;
11213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
11313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
11413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_jpegThumb != NULL) {
11513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        int iSize = sizeof(char)*m_thumbnailW*m_thumbnailH*4;
11613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
11713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        freeJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
11813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        freeJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);
119eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang        initJpegMemory(&m_stMainInBuf, MAX_IMAGE_PLANE_NUM);
120eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang        initJpegMemory(&m_stMainOutBuf, MAX_IMAGE_PLANE_NUM);
12113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_ionJpegClient = deleteIonClient(m_ionJpegClient);
122eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang        m_stMainOutBuf.ionClient = m_stMainInBuf.ionClient = m_stThumbInBuf.ionClient = m_stThumbOutBuf.ionClient = m_ionJpegClient;
12313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegThumb->destroy();
12413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        delete m_jpegThumb;
12513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegThumb = NULL;
12613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
12713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
12813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_flagCreate = false;
12913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailW = 0;
13013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailH = 0;
13113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
13213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
13313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
13413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
13513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setSize(int w, int h)
13613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
13713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
13813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
13913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
14013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
14113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_jpegMain->setSize(w, h);
14213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
14313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
14413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
14513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setQuality(int quality)
14613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
14713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
14813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
14913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
15013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
15113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_jpegMain->setQuality(quality);
15213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
15313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
15413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setColorFormat(int colorFormat)
15513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
15613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
15713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
15813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
15913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
16013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_jpegMain->setColorFormat(colorFormat);
16113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
16213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
16313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setJpegFormat(int jpegFormat)
16413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
16513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
16613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
16713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
16813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
16913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_jpegMain->setJpegFormat(jpegFormat);
17013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
17113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
17213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::updateConfig(void)
17313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
17413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
17513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
17613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
17713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
17813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return m_jpegMain->updateConfig();
17913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
18013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
181eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kangint  ExynosJpegEncoderForCamera::setInBuf(int *buf, char** vBuf, int *size)
18213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
18313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
18413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
18513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
18613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
18713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (buf == NULL) {
18813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFR_IS_NULL;
18913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
19013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
19113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (size == NULL) {
19213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFR_IS_NULL;
19313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
19413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
19513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
19613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
19713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegMain->setInBuf(buf, size);
19813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
19913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__);
20013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
20113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
202eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainInBuf.ionBuffer[0] = buf[0];
203eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainInBuf.iSize[0] = size[0];
204eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainInBuf.pcBuf[0] = vBuf[0];
20513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
20613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
20713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
20813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
209eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kangint  ExynosJpegEncoderForCamera::setOutBuf(int buf, char* vBuf, int size)
21013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
21113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
21213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
21313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
21413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
21513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (buf == NULL) {
21613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFR_IS_NULL;
21713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
21813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
21913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (size<=0) {
22013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFER_TOO_SMALL;
22113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
22213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
22313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
22413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegMain->setOutBuf(buf, size);
22513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
22613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__);
22713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
22813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
229eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainOutBuf.ionBuffer[0] = buf;
230eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainOutBuf.iSize[0] = size;
231eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    m_stMainOutBuf.pcBuf[0] = vBuf;
23213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
23313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
23413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
23513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
23613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo)
23713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
23813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
23913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char *exifOut = NULL;
24013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
24113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
24213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_NOT_YET_CREATED;
24313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
24413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
24513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
24613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegMain->encode();
24713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
24813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("encode failed\n");
24913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
25013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
25113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
25213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int iJpegSize = m_jpegMain->getJpegSize();
25313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
25413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (iJpegSize<=0) {
25513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("%s:: output_size is too small(%d)!!\n", __func__, iJpegSize);
25613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_OUT_BUFFER_SIZE_TOO_SMALL;
25713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
25813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
259eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    int iOutputSize = m_stMainOutBuf.iSize[0];
260eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    int iJpegBuffer = m_stMainOutBuf.ionBuffer[0];
261eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang    char *pcJpegBuffer = m_stMainOutBuf.pcBuf[0];
26213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
26313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (pcJpegBuffer[0] == NULL) {
26413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("%s::pcJpegBuffer[0] is null!!\n", __func__);
26513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_OUT_BUFFER_CREATE_FAIL;
26613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
26713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
26813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (exifInfo != NULL) {
26913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        unsigned int thumbLen, exifLen;
27013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
27113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        unsigned int bufSize = 0;
27213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (exifInfo->enableThumb) {
27313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            if (encodeThumbnail(&thumbLen)) {
27413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                bufSize = EXIF_FILE_SIZE;
27513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                exifInfo->enableThumb = false;
27613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            } else {
27713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                if (thumbLen > EXIF_LIMIT_SIZE) {
27813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                    bufSize = EXIF_FILE_SIZE;
27913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                    exifInfo->enableThumb = false;
28013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                }
28113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                else {
28213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                    bufSize = EXIF_FILE_SIZE + thumbLen;
28313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                }
28413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            }
28513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        } else {
28613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            bufSize = EXIF_FILE_SIZE;
28713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            exifInfo->enableThumb = false;
28813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
28913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
29013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        exifOut = new unsigned char[bufSize];
29113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (exifOut == NULL) {
29213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("%s::Failed to allocate for exifOut\n", __func__);
29313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            delete[] exifOut;
29413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_EXIFOUT_ALLOC_FAIL;
29513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
29613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memset(exifOut, 0, bufSize);
29713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
29813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (makeExif (exifOut, exifInfo, &exifLen)) {
29913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("%s::Failed to make EXIF\n", __func__);
30013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            delete[] exifOut;
30113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_MAKE_EXIF_FAIL;
30213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
30313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
30413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (exifLen <= EXIF_LIMIT_SIZE) {
30513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            memmove(pcJpegBuffer+exifLen+2, pcJpegBuffer+2, iJpegSize - 2);
30613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            memcpy(pcJpegBuffer+2, exifOut, exifLen);
30713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            iJpegSize += exifLen;
30813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
30913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
31013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        delete[] exifOut;
31113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
31213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
31313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *size = iJpegSize;
31413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
31513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
31613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
31713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
31813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::makeExif (unsigned char *exifOut,
31913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              exif_attribute_t *exifInfo,
32013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              unsigned int *size,
32113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              bool useMainbufForThumb)
32213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
32313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset;
32413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned int tmp, LongerTagOffest = 0, exifSizeExceptThumb;
32513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pApp1Start = pCur = exifOut;
32613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
32713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    //2 Exif Identifier Code & TIFF Header
32813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += 4;  // Skip 4 Byte for APP1 marker and length
32913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
33013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pCur, ExifIdentifierCode, 6);
33113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += 6;
33213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
33313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    /* Byte Order - little endian, Offset of IFD - 0x00000008.H */
33413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
33513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pCur, TiffHeader, 8);
33613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pIfdStart = pCur;
33713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += 8;
33813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
33913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    //2 0th IFD TIFF Tags
34013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (exifInfo->enableGps)
34113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = NUM_0TH_IFD_TIFF;
34213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    else
34313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = NUM_0TH_IFD_TIFF - 1;
34413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
34513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pCur, &tmp, NUM_SIZE);
34613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += NUM_SIZE;
34713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
34813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
34913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
35013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
35113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->width);
35213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
35313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->height);
35413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII,
35513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart);
35613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII,
35713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart);
35813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
35913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->orientation);
36013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
36113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart);
36213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII,
36313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
36413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT,
36513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->ycbcr_positioning);
36613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG,
36713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, LongerTagOffest);
36813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (exifInfo->enableGps) {
36913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pGpsIfdPtr = pCur;
37013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur += IFD_SIZE;   // Skip a ifd size for gps IFD pointer
37113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
37213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
37313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pNextIfdOffset = pCur;  // Skip a offset size for next IFD offset
37413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += OFFSET_SIZE;
37513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
37613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    //2 0th IFD Exif Private Tags
37713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur = pIfdStart + LongerTagOffest;
37813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
37913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    tmp = NUM_0TH_IFD_EXIF;
38013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pCur, &tmp , NUM_SIZE);
38113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += NUM_SIZE;
38213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
38313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE;
38413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
38513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL,
38613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart);
38713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL,
38813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart);
38913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT,
39013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->exposure_program);
39113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT,
39213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->iso_speed_rating);
39313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED,
39413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 4, exifInfo->exif_version);
39513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII,
39613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
39713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII,
39813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
39913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL,
40013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart);
40113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL,
40213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart);
40313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL,
40413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart);
40513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL,
40613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart);
40713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL,
40813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart);
40913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT,
41013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->metering_mode);
41113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT,
41213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->flash);
41313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL,
41413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart);
41513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 };
41613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int commentsLen = strlen((char *)exifInfo->user_comment) + 1;
41713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen);
41813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(exifInfo->user_comment, code, sizeof(code));
41913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED,
42013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart);
42113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT,
42213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->color_space);
42313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG,
42413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->width);
42513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG,
42613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->height);
42713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG,
42813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->exposure_mode);
42913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG,
43013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->white_balance);
43113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG,
43213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                 1, exifInfo->scene_capture_type);
43313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    tmp = 0;
43413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
43513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pCur += OFFSET_SIZE;
43613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
43713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    //2 0th IFD GPS Info Tags
43813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (exifInfo->enableGps) {
43913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG,
44013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD
44113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
44213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur = pIfdStart + LongerTagOffest;
44313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
44413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (exifInfo->gps_processing_method[0] == 0) {
44513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            // don't create GPS_PROCESSING_METHOD tag if there isn't any
44613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            tmp = NUM_0TH_IFD_GPS - 1;
44713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        } else {
44813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            tmp = NUM_0TH_IFD_GPS;
44913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
45013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pCur, &tmp, NUM_SIZE);
45113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur += NUM_SIZE;
45213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
45313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
45413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
45513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE,
45613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     4, exifInfo->gps_version_id);
45713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII,
45813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     2, exifInfo->gps_latitude_ref);
45913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL,
46013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart);
46113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII,
46213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     2, exifInfo->gps_longitude_ref);
46313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL,
46413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart);
46513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE,
46613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->gps_altitude_ref);
46713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL,
46813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart);
46913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL,
47013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart);
47113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = strlen((char*)exifInfo->gps_processing_method);
47213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (tmp > 0) {
47313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            if (tmp > 100) {
47413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                tmp = 100;
47513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            }
47613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)];
47713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
47813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp);
47913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED,
48013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                         tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart);
48113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
48213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII,
48313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart);
48413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = 0;
48513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
48613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur += OFFSET_SIZE;
48713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
48813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
48913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    //2 1th IFD TIFF Tags
49013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int iThumbFd = 0;
49113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char *thumbBuf = NULL;
49213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned int thumbSize = 0;
49313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int thumbBufSize = 0;
49413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
49513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
49613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (useMainbufForThumb) {
49713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (m_jpegMain) {
49813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            ret = m_jpegMain->getOutBuf((int *)&iThumbFd, (int *)&thumbBufSize);
49913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            if (ret != ERROR_NONE) {
50013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                iThumbFd = -1;
50113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            }
50213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            thumbSize = (unsigned int)m_jpegMain->getJpegSize();
503eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang            thumbBuf = m_stMainOutBuf.pcBuf[0];
50413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
50513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    } else {
50613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (m_jpegThumb) {
50713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            ret = m_jpegThumb->getOutBuf((int *)&iThumbFd, (int *)&thumbBufSize);
50813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            if (ret != ERROR_NONE) {
50913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                iThumbFd = -1;
51013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            }
51113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            thumbSize = (unsigned int)m_jpegThumb->getJpegSize();
512eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang            thumbBuf = m_stThumbOutBuf.pcBuf[0];
51313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
51413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
51513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
51613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize != 0)) {
51713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        exifSizeExceptThumb = tmp = LongerTagOffest;
51813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
51913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
52013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur = pIfdStart + LongerTagOffest;
52113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
52213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = NUM_1TH_IFD_TIFF;
52313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pCur, &tmp, NUM_SIZE);
52413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur += NUM_SIZE;
52513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
52613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE;
52713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
52813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
52913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->widthThumb);
53013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
53113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->heightThumb);
53213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT,
53313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->compression_scheme);
53413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
53513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->orientation);
53613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL,
53713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart);
53813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL,
53913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart);
54013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT,
54113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, exifInfo->resolution_unit);
54213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG,
54313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, LongerTagOffest);
54413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG,
54513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                     1, thumbSize);
54613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
54713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = 0;
54813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
54913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pCur += OFFSET_SIZE;
55013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
55113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pIfdStart + LongerTagOffest,
55213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang               thumbBuf, thumbSize);
55313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        LongerTagOffest += thumbSize;
55413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (LongerTagOffest > EXIF_LIMIT_SIZE) {
55513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            LongerTagOffest = exifSizeExceptThumb;
55613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            tmp = 0;
55713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
55813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
55913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    } else {
56013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        tmp = 0;
56113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
56213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
56313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
56413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char App1Marker[2] = { 0xff, 0xe1 };
56513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pApp1Start, App1Marker, 2);
56613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pApp1Start += 2;
56713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
56813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *size = 10 + LongerTagOffest;
56913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    tmp = *size - 2;    // APP1 Maker isn't counted
57013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF};
57113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(pApp1Start, size_mm, 2);
57213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
57313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
57413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
57513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
57613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang/*
57713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang * private member functions
57813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang*/
57913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kanginline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
58013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short tag,
58113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short type,
58213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int count,
58313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int value)
58413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
58513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &tag, 2);
58613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
58713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &type, 2);
58813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
58913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &count, 4);
59013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
59113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &value, 4);
59213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
59313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
59413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
59513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kanginline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
59613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short tag,
59713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short type,
59813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int count,
59913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned char *pValue)
60013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
60113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char buf[4] = { 0,};
60213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
60313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(buf, pValue, count);
60413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &tag, 2);
60513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
60613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &type, 2);
60713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
60813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &count, 4);
60913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
61013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, buf, 4);
61113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
61213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
61313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
61413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kanginline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
61513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short tag,
61613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short type,
61713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int count,
61813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned char *pValue,
61913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int *offset,
62013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned char *start)
62113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
62213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &tag, 2);
62313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
62413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &type, 2);
62513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
62613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &count, 4);
62713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
62813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, offset, 4);
62913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
63013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(start + *offset, pValue, count);
63113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *offset += count;
63213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
63313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
63413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kanginline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
63513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short tag,
63613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned short type,
63713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int count,
63813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             rational_t *pValue,
63913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned int *offset,
64013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                             unsigned char *start)
64113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
64213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &tag, 2);
64313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
64413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &type, 2);
64513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 2;
64613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, &count, 4);
64713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
64813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(*pCur, offset, 4);
64913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *pCur += 4;
65013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    memcpy(start + *offset, pValue, 8 * count);
65113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *offset += 8 * count;
65213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
65313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
65413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::scaleDownYuv422(char **srcBuf, unsigned int srcW, unsigned int srcH,  char **dstBuf, unsigned int dstW, unsigned int dstH)
65513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
65613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int step_x, step_y;
65713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int src_y_start_pos, dst_pos, src_pos;
65813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char *src_buf = srcBuf[0];
65913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char *dst_buf = dstBuf[0];
66013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
66113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (dstW & 0x01 || dstH & 0x01) {
66213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
66313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
66413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
66513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    step_x = srcW / dstW;
66613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    step_y = srcH / dstH;
66713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
66813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned int srcWStride = srcW * 2;
66913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    unsigned int stepXStride = step_x * 2;
67013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
67113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    dst_pos = 0;
67213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (unsigned int y = 0; y < dstH; y++) {
67313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        src_y_start_pos = srcWStride * step_y * y;
67413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
67513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        for (unsigned int x = 0; x < dstW; x += 2) {
67613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            src_pos = src_y_start_pos + (stepXStride * x);
67713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
67813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos    ];
67913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos + 1];
68013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos + 2];
68113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos + 3];
68213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
68313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
68413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
68513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
68613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
68713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
68813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::scaleDownYuv422_2p(char **srcBuf, unsigned int srcW, unsigned int srcH, char **dstBuf, unsigned int dstW, unsigned int dstH)
68913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
69013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int32_t step_x, step_y;
69113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int32_t src_y_start_pos, dst_pos, src_pos;
69213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int32_t src_Y_offset;
69313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char *src_buf;
69413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    char *dst_buf;
69513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
69613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (dstW % 2 != 0 || dstH % 2 != 0) {
69713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
69813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
69913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
70013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    step_x = srcW / dstW;
70113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    step_y = srcH / dstH;
70213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
70313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    // Y scale down
70413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    src_buf = srcBuf[0];
70513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    dst_buf = dstBuf[0];
70613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    dst_pos = 0;
70713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (uint32_t y = 0; y < dstH; y++) {
70813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        src_y_start_pos = y * step_y * srcW;
70913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
71013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        for (uint32_t x = 0; x < dstW; x++) {
71113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            src_pos = src_y_start_pos + (x * step_x);
71213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
71313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos];
71413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
71513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
71613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
71713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    // UV scale down
71813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (uint32_t i = 0; i < dstH; i++) {
71913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        src_y_start_pos = i * step_y * srcW + (srcW*srcH);
72013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
72113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        for (uint32_t j = 0; j < dstW; j += 2) {
72213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            src_pos = src_y_start_pos + (j * step_x);
72313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
72413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos    ];
72513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            dst_buf[dst_pos++] = src_buf[src_pos + 1];
72613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
72713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
72813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
72913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
73013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
73113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
73213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang// thumbnail
73313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setThumbnailSize(int w, int h)
73413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
73513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
73613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
73713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
73813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
73913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (w < 0 || MAX_JPG_WIDTH < w) {
74013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return false;
74113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
74213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
74313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (h < 0 || MAX_JPG_HEIGHT < h) {
74413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return false;
74513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
74613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
74713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailW = w;
74813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailH = h;
74913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
75013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
75113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
75213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::setThumbnailQuality(int quality)
75313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
75413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
75513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
75613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
75713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
75813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (quality < 1 || 100 < quality) {
75913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return false;
76013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
76113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
76213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_thumbnailQuality = quality;
76313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
76413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
76513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
76613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::encodeThumbnail(unsigned int *size, bool useMain)
76713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
76813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
76913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
77013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_flagCreate == false) {
77113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
77213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
77313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
77413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    // create jpeg thumbnail class
77513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_jpegThumb == NULL) {
77613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        m_jpegThumb = new ExynosJpegEncoder;
77713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
77813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (m_jpegThumb == NULL) {
77913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("ERR(%s):Cannot open a jpeg device file\n", __func__);
78013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_CANNOT_CREATE_SEC_THUMB;
78113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
78213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
78313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
78413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->create();
78513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
78613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail create\n", __func__);
78713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
78813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
78913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
79013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ret = m_jpegThumb->setCache(JPEG_CACHE_ON);
79113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
79213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail cache set\n", __func__);
79313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
79413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
79513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
79613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    void *pConfig = m_jpegMain->getJpegConfig();
79713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (pConfig == NULL) {
79813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail getJpegConfig\n", __func__);
79913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFR_IS_NULL;
80013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
80113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
80213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->setJpegConfig(pConfig);
80313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
80413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail setJpegConfig\n", __func__);
80513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
80613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
80713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
80813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    /* TODO: Currently we fix the thumbnail quality */
80913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->setQuality(JPEG_THUMBNAIL_QUALITY);
81013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
81113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail setQuality\n", __func__);
81213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
81313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
81413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
81513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->setSize(m_thumbnailW, m_thumbnailH);
81613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
81713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail setSize\n", __func__);
81813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
81913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
82013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
82113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    freeJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM);
82213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    freeJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM);
82313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
82413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (m_jpegThumb->setColorBufSize(m_stThumbInBuf.iSize, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
82513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_INVALID_COLOR_FORMAT;
82613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
82713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    m_stThumbOutBuf.iSize[0] = sizeof(char)*m_thumbnailW*m_thumbnailH*THUMBNAIL_IMAGE_PIXEL_SIZE;
82813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
82913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
83013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (allocJpegMemory(&m_stThumbInBuf, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
83113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_MEM_ALLOC_FAIL;
83213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
83313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
83413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (allocJpegMemory(&m_stThumbOutBuf, MAX_IMAGE_PLANE_NUM) != ERROR_NONE) {
83513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_MEM_ALLOC_FAIL;
83613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
83713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
83813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->setInBuf(m_stThumbInBuf.ionBuffer, m_stThumbInBuf.iSize);
83913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
84013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail setInBuf\n", __func__);
84113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
84213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
84313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
84413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->setOutBuf(m_stThumbOutBuf.ionBuffer[0], m_stThumbOutBuf.iSize[0]);
84513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
84613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("ERR(%s):Fail setOutBuf\n", __func__);
84713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
84813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
84913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
85013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->updateConfig();
85113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
85213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("update config failed\n");
85313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
85413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
85513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
85613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (useMain) {
85713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        int iTempWidth=0;
85813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        int iTempHeight=0;
85913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        int iTempColorformat = 0;
86013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
86113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        iTempColorformat = m_jpegMain->getColorFormat();
86213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
86313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ret = m_jpegMain->getSize(&iTempWidth, &iTempHeight);
86413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ret) {
86513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("ERR(%s):Fail getSize\n", __func__);
86613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ret;
86713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
86813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
86913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        switch (iTempColorformat) {
87013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        case V4L2_PIX_FMT_YUYV:
871eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang            ret = scaleDownYuv422(m_stMainInBuf.pcBuf,
87213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              iTempWidth,
87313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              iTempHeight,
87413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_stThumbInBuf.pcBuf,
87513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_thumbnailW,
87613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_thumbnailH);
87713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            break;
87813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        case V4L2_PIX_FMT_NV16:
879eed7ed1bffb083b112a3366e740ebdc186203afaSungjoong Kang            ret = scaleDownYuv422_2p(m_stMainInBuf.pcBuf,
88013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              iTempWidth,
88113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              iTempHeight,
88213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_stThumbInBuf.pcBuf,
88313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_thumbnailW,
88413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                              m_thumbnailH);
88513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            break;
88613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        default:
88713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_INVALID_COLOR_FORMAT;
88813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            break;
88913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
89013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
89113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ret) {
89213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("%s::scaleDown(%d, %d, %d, %d) fail", __func__, iTempWidth, iTempHeight, m_thumbnailW, m_thumbnailH);
89313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ret;
89413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
89513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
89613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    else {
89713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_IMPLEMENT_NOT_YET;
89813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
89913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
90013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int iOutSizeThumb;
90113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
90213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    ret = m_jpegThumb->encode();
90313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ret) {
90413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("encode failed\n");
90513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ret;
90613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
90713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
90813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    iOutSizeThumb = m_jpegThumb->getJpegSize();
90913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (iOutSizeThumb<=0) {
91013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("jpeg size is too small\n");
91113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_THUMB_JPEG_SIZE_TOO_SMALL;
91213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
91313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
91413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    *size = (unsigned int)iOutSizeThumb;
91513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
91613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
91713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
91813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
91913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
92013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::createIonClient(ion_client ionClient)
92113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
92213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ionClient == 0) {
92313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ionClient = ion_client_create();
92413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ionClient < 0) {
92513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, ionClient);
92613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return 0;
92713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
92813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
92913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
93013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ionClient;
93113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
93213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
93313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::deleteIonClient(ion_client ionClient)
93413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
93513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (ionClient != 0) {
93613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (ionClient > 0) {
93713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            ion_client_destroy(ionClient);
93813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
93913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        ionClient = 0;
94013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
94113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
94213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ionClient;
94313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
94413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
94513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangint ExynosJpegEncoderForCamera::allocJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
94613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
94713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int ret = ERROR_NONE;
94813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int i = 0;
94913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
95013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (pstMem->ionClient == 0) {
95113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        JPEG_ERROR_LOG("[%s] i = %d , ionClient is zero (%d)\n", __func__, i, pstMem->ionClient);
95213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return ERROR_BUFFR_IS_NULL;
95313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
95413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
95513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (i=0;i<iMemoryNum;i++) {
95613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (pstMem->iSize[i] == 0) {
95713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            break;
95813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
95913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
96013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->ionBuffer[i] = ion_alloc(pstMem->ionClient, \
96113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                                        pstMem->iSize[i], 0, ION_HEAP_SYSTEM_MASK, 0);
96213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if ((pstMem->ionBuffer[i] == -1) ||(pstMem->ionBuffer[i] == 0)) {
96313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("[%s]ion_alloc(%d) failed\n", __func__, pstMem->iSize[i]);
96413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            pstMem->ionBuffer[i] = -1;
96513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            freeJpegMemory(pstMem, iMemoryNum);
96613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_MEM_ALLOC_FAIL;
96713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
96813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
96913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->pcBuf[i] = (char *)ion_map(pstMem->ionBuffer[i], \
97013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                                                            pstMem->iSize[i], 0);
97113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if ((pstMem->pcBuf[i] == (char *)MAP_FAILED) || (pstMem->pcBuf[i] == NULL)) {
97213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            JPEG_ERROR_LOG("[%s]src ion map failed(%d)\n", __func__, pstMem->iSize[i]);
97313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            pstMem->pcBuf[i] = (char *)MAP_FAILED;
97413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            freeJpegMemory(pstMem, iMemoryNum);
97513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            return ERROR_MEM_ALLOC_FAIL;
97613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
97713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
97813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
97913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    return ERROR_NONE;
98013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
98113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
98213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangvoid ExynosJpegEncoderForCamera::freeJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
98313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
98413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int i =0 ;
98513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    if (pstMem->ionClient == 0) {
98613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        return;
98713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
98813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
98913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
99013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (i=0;i<iMemoryNum;i++) {
99113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        if (pstMem->ionBuffer[i] != -1) {
99213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            if (pstMem->pcBuf[i] != (char *)MAP_FAILED) {
99313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang                ion_unmap(pstMem->pcBuf[i], pstMem->iSize[i]);
99413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            }
99513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang            ion_free(pstMem->ionBuffer[i]);
99613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        }
99713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->ionBuffer[i] = -1;
99813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->pcBuf[i] = (char *)MAP_FAILED;
99913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->iSize[i] = 0;
100013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
100113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
100213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang
100313d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kangvoid ExynosJpegEncoderForCamera::initJpegMemory(struct stJpegMem *pstMem, int iMemoryNum)
100413d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang{
100513d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    int i =0 ;
100613d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    for (i=0;i<iMemoryNum;i++) {
100713d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->pcBuf[i] = (char *)MAP_FAILED;
100813d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->ionBuffer[i] = -1;
100913d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang        pstMem->iSize[i] = 0;
101013d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    }
101113d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang    pstMem->ionClient = 0;
101213d8c7b4650fb7897b4291ed9b3d57b19f7d1ccdSungjoong Kang}
10132ed2aecf5abca549c0f065f9b0fe043f325e42a8Rebecca Schultz Zavin
1014