19426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin/*
29426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * Copyright Samsung Electronics Co.,LTD.
39426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * Copyright (C) 2010 The Android Open Source Project
49426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin *
59426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * Licensed under the Apache License, Version 2.0 (the "License");
69426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * you may not use this file except in compliance with the License.
79426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * You may obtain a copy of the License at
89426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin *
99426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin *     http://www.apache.org/licenses/LICENSE-2.0
109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin *
119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * Unless required by applicable law or agreed to in writing, software
129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * distributed under the License is distributed on an "AS IS" BASIS,
139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * See the License for the specific language governing permissions and
159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * limitations under the License.
169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin */
179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#include <utils/Log.h>
199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#include "ExynosJpegEncoderForCamera.h"
219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinstatic const char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define JPEG_ERROR_LOG(fmt,...)
259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define THUMBNAIL_IMAGE_PIXEL_SIZE (4)
279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define MAX_JPG_WIDTH (8192)
289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define MAX_JPG_HEIGHT (8192)
299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define MAX_INPUT_BUFFER_PLANE_NUM (2)
319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#define MAX_OUTPUT_BUFFER_PLANE_NUM (2)
329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung ShinExynosJpegEncoderForCamera::ExynosJpegEncoderForCamera()
349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_flagCreate = false;
369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_jpegMain = NULL;
379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_jpegThumb = NULL;
389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailW = 0;
399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailH = 0;
409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_pThumbInputBuffer = NULL;
429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_pThumbOutputBuffer = NULL;
439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_pJpegInputBuffer = 0;
459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_pExtInBuf = NULL;
469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_iInBufSize = 0;
479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif // JPEG_WA_FOR_PAGEFAULT
489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_ionJpegClient = 0;;
499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_ionThumbInBuffer = 0;
509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_ionThumbOutBuffer = 0;
519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_ionJpegInBuffer = 0;;
539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif // JPEG_WA_FOR_PAGEFAULT
549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung ShinExynosJpegEncoderForCamera::~ExynosJpegEncoderForCamera()
579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == true) {
599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        this->destroy();
609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinbool ExynosJpegEncoderForCamera::flagCreate(void)
649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_flagCreate;
669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::create(void)
699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == true) {
729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_ALREADY_CREATE;
739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_jpegMain == NULL) {
769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegMain = new ExynosJpegEncoder;
779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_jpegMain == NULL) {
799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("ERR(%s):Cannot create ExynosJpegEncoder class\n", __func__);
809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegMain->create();
849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegMain->setCache(JPEG_CACHE_ON);
899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            m_jpegMain->destroy();
929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_flagCreate = true;
979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::destroy(void)
1029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_ALREADY_DESTROY;
1059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_jpegMain != NULL) {
1089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegMain->destroy();
1099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        delete m_jpegMain;
1109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegMain = NULL;
1119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_jpegThumb != NULL) {
1149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iSize = sizeof(char)*m_thumbnailW*m_thumbnailH*4;
1159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
1179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iSize += JPEG_WA_BUFFER_SIZE;
1189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        freeJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, m_iInBufSize);
1199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif //JPEG_WA_FOR_PAGEFAULT
1209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        freeJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iSize);
1229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        freeJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iSize);
1239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_ionJpegClient != 0) {
1259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            ion_client_destroy(m_ionJpegClient);
1269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            m_ionJpegClient = 0;
1279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
1289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegThumb->destroy();
1309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        delete m_jpegThumb;
1319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegThumb = NULL;
1329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_flagCreate = false;
1359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailW = 0;
1369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailH = 0;
1379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailQuality = JPEG_THUMBNAIL_QUALITY;
1389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
1399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setSize(int w, int h)
1429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_jpegMain->setSize(w, h);
1489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setQuality(int quality)
1529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_jpegMain->setQuality(quality);
1589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setColorFormat(int colorFormat)
1619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_jpegMain->setColorFormat(colorFormat);
1679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setJpegFormat(int jpegFormat)
1709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_jpegMain->setJpegFormat(jpegFormat);
1769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::updateConfig(void)
1799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return m_jpegMain->updateConfig();
1859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
1869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint  ExynosJpegEncoderForCamera::setInBuf(char **buf, int *size)
1889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
1899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
1909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
1919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (buf == NULL) {
1949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFR_IS_NULL;
1959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
1969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (size<=0) {
1989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFER_TOO_SMALL;
1999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
2029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
2049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    size += JPEG_WA_BUFFER_SIZE;
2059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    freeJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, size);
2079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_ionJpegClient == 0) {
2099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_ionJpegClient = ion_client_create();
2109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_ionJpegClient < 0) {
2119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, size);
2129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            m_ionJpegClient = 0;
2139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
2149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
2159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = allocJpegIonMemory(m_ionJpegClient, &m_ionJpegInBuffer, &m_pJpegInputBuffer, size);
2189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret != ERROR_NONE) {
2199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegMain->setInBuf(&m_pJpegInputBuffer, &size);
2239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
2249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__);
2259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_iInBufSize = size;
2289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_pExtInBuf = buf;
2309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#else // NO JPEG_WA_FOR_PAGEFAULT
2329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegMain->setInBuf(buf, size);
2339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
2349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s::Fail to JPEG input buffer!!\n", __func__);
2359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif // JPEG_WA_FOR_PAGEFAULT
2389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
2409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
2419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint  ExynosJpegEncoderForCamera::setOutBuf(char *buf, int size)
2439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
2449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
2459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
2469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (buf == NULL) {
2499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFR_IS_NULL;
2509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (size<=0) {
2539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFER_TOO_SMALL;
2549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
2579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegMain->setOutBuf(buf, size);
2589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
2599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s::Fail to JPEG output buffer!!\n", __func__);
2609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
2649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
2659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::encode(int *size, exif_attribute_t *exifInfo)
2679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
2689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
2699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char *exifOut = NULL;
2709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
2729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_NOT_YET_CREATED;
2739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
2769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(m_pJpegInputBuffer, m_pExtInBuf, m_iInBufSize-JPEG_WA_BUFFER_SIZE);
2779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif // JPEG_WA_FOR_PAGEFAULT
2789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegMain->encode();
2809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
2819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("encode failed\n");
2829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int iJpegSize = m_jpegMain->getJpegSize();
2869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (iJpegSize<=0) {
2889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s:: output_size is too small(%d)!!\n", __func__, iJpegSize);
2899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_OUT_BUFFER_SIZE_TOO_SMALL;
2909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int iOutputSize = 0;
2939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *pcJpegBuffer = NULL;
2949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegMain->getOutBuf((char **)&pcJpegBuffer, &iOutputSize);
2959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret != ERROR_NONE) {
2969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
2979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
2989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
2999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (pcJpegBuffer == NULL) {
3009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s::pcJpegBuffer is null!!\n", __func__);
3019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_OUT_BUFFER_CREATE_FAIL;
3029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
3039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (pcJpegBuffer[0] == NULL) {
3059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("%s::pcJpegBuffer[0] is null!!\n", __func__);
3069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_OUT_BUFFER_CREATE_FAIL;
3079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
3089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (exifInfo != NULL) {
3109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        unsigned int thumbLen, exifLen;
3119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        unsigned int bufSize = 0;
3139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (exifInfo->enableThumb) {
3149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            if (encodeThumbnail(&thumbLen)) {
3159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                bufSize = EXIF_FILE_SIZE;
3169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                exifInfo->enableThumb = false;
3179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            } else {
3189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                if (thumbLen > EXIF_LIMIT_SIZE) {
3199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                    bufSize = EXIF_FILE_SIZE;
3209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                    exifInfo->enableThumb = false;
3219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                }
3229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                else {
3239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                    bufSize = EXIF_FILE_SIZE + thumbLen;
3249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                }
3259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            }
3269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        } else {
3279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            bufSize = EXIF_FILE_SIZE;
3289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            exifInfo->enableThumb = false;
3299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
3309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        exifOut = new unsigned char[bufSize];
3329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (exifOut == NULL) {
3339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("%s::Failed to allocate for exifOut\n", __func__);
3349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            delete[] exifOut;
3359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ERROR_EXIFOUT_ALLOC_FAIL;
3369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
3379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memset(exifOut, 0, bufSize);
3389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (makeExif (exifOut, exifInfo, &exifLen)) {
3409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("%s::Failed to make EXIF\n", __func__);
3419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            delete[] exifOut;
3429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ERROR_MAKE_EXIF_FAIL;
3439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
3449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (exifLen <= EXIF_LIMIT_SIZE) {
3469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            memmove(pcJpegBuffer+exifLen+2, pcJpegBuffer+2, iJpegSize - 2);
3479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            memcpy(pcJpegBuffer+2, exifOut, exifLen);
3489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            iJpegSize += exifLen;
3499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
3509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        delete[] exifOut;
3529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
3539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *size = iJpegSize;
3559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
3579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
3589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::makeExif (unsigned char *exifOut,
3609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              exif_attribute_t *exifInfo,
3619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              unsigned int *size,
3629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              bool useMainbufForThumb)
3639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
3649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char *pCur, *pApp1Start, *pIfdStart, *pGpsIfdPtr, *pNextIfdOffset;
3659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned int tmp, LongerTagOffest = 0, exifSizeExceptThumb;
3669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pApp1Start = pCur = exifOut;
3679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    //2 Exif Identifier Code & TIFF Header
3699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += 4;  // Skip 4 Byte for APP1 marker and length
3709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char ExifIdentifierCode[6] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
3719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pCur, ExifIdentifierCode, 6);
3729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += 6;
3739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    /* Byte Order - little endian, Offset of IFD - 0x00000008.H */
3759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char TiffHeader[8] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
3769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pCur, TiffHeader, 8);
3779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pIfdStart = pCur;
3789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += 8;
3799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    //2 0th IFD TIFF Tags
3819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (exifInfo->enableGps)
3829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = NUM_0TH_IFD_TIFF;
3839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    else
3849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = NUM_0TH_IFD_TIFF - 1;
3859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pCur, &tmp, NUM_SIZE);
3879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += NUM_SIZE;
3889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    LongerTagOffest += 8 + NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
3909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
3919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
3929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->width);
3939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
3949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->height);
3959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_MAKE, EXIF_TYPE_ASCII,
3969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 strlen((char *)exifInfo->maker) + 1, exifInfo->maker, &LongerTagOffest, pIfdStart);
3979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_MODEL, EXIF_TYPE_ASCII,
3989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 strlen((char *)exifInfo->model) + 1, exifInfo->model, &LongerTagOffest, pIfdStart);
3999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
4009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->orientation);
4019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII,
4029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 strlen((char *)exifInfo->software) + 1, exifInfo->software, &LongerTagOffest, pIfdStart);
4039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII,
4049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
4059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT,
4069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->ycbcr_positioning);
4079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG,
4089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, LongerTagOffest);
4099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (exifInfo->enableGps) {
4109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pGpsIfdPtr = pCur;
4119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur += IFD_SIZE;   // Skip a ifd size for gps IFD pointer
4129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
4139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pNextIfdOffset = pCur;  // Skip a offset size for next IFD offset
4159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += OFFSET_SIZE;
4169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    //2 0th IFD Exif Private Tags
4189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur = pIfdStart + LongerTagOffest;
4199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    tmp = NUM_0TH_IFD_EXIF;
4219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pCur, &tmp , NUM_SIZE);
4229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += NUM_SIZE;
4239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    LongerTagOffest += NUM_SIZE + NUM_0TH_IFD_EXIF*IFD_SIZE + OFFSET_SIZE;
4259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL,
4279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, &exifInfo->exposure_time, &LongerTagOffest, pIfdStart);
4289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL,
4299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, &exifInfo->fnumber, &LongerTagOffest, pIfdStart);
4309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT,
4319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->exposure_program);
4329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT,
4339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->iso_speed_rating);
4349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED,
4359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 4, exifInfo->exif_version);
4369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII,
4379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
4389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII,
4399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 20, exifInfo->date_time, &LongerTagOffest, pIfdStart);
4409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL,
4419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, (rational_t *)&exifInfo->shutter_speed, &LongerTagOffest, pIfdStart);
4429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL,
4439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, &exifInfo->aperture, &LongerTagOffest, pIfdStart);
4449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL,
4459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, (rational_t *)&exifInfo->brightness, &LongerTagOffest, pIfdStart);
4469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL,
4479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, (rational_t *)&exifInfo->exposure_bias, &LongerTagOffest, pIfdStart);
4489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL,
4499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, &exifInfo->max_aperture, &LongerTagOffest, pIfdStart);
4509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT,
4519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->metering_mode);
4529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_FLASH, EXIF_TYPE_SHORT,
4539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->flash);
4549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL,
4559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, &exifInfo->focal_length, &LongerTagOffest, pIfdStart);
4569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char code[8] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 };
4579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int commentsLen = strlen((char *)exifInfo->user_comment) + 1;
4589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memmove(exifInfo->user_comment + sizeof(code), exifInfo->user_comment, commentsLen);
4599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(exifInfo->user_comment, code, sizeof(code));
4609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED,
4619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 commentsLen + sizeof(code), exifInfo->user_comment, &LongerTagOffest, pIfdStart);
4629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT,
4639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->color_space);
4649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG,
4659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->width);
4669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG,
4679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->height);
4689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_LONG,
4699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->exposure_mode);
4709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_LONG,
4719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->white_balance);
4729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    writeExifIfd(&pCur, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_LONG,
4739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                 1, exifInfo->scene_capture_type);
4749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    tmp = 0;
4759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
4769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pCur += OFFSET_SIZE;
4779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    //2 0th IFD GPS Info Tags
4799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (exifInfo->enableGps) {
4809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pGpsIfdPtr, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG,
4819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, LongerTagOffest); // GPS IFD pointer skipped on 0th IFD
4829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur = pIfdStart + LongerTagOffest;
4849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (exifInfo->gps_processing_method[0] == 0) {
4869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            // don't create GPS_PROCESSING_METHOD tag if there isn't any
4879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            tmp = NUM_0TH_IFD_GPS - 1;
4889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        } else {
4899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            tmp = NUM_0TH_IFD_GPS;
4909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
4919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pCur, &tmp, NUM_SIZE);
4929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur += NUM_SIZE;
4939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        LongerTagOffest += NUM_SIZE + tmp*IFD_SIZE + OFFSET_SIZE;
4959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
4969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE,
4979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     4, exifInfo->gps_version_id);
4989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII,
4999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     2, exifInfo->gps_latitude_ref);
5009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL,
5019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     3, exifInfo->gps_latitude, &LongerTagOffest, pIfdStart);
5029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII,
5039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     2, exifInfo->gps_longitude_ref);
5049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL,
5059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     3, exifInfo->gps_longitude, &LongerTagOffest, pIfdStart);
5069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE,
5079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->gps_altitude_ref);
5089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL,
5099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, &exifInfo->gps_altitude, &LongerTagOffest, pIfdStart);
5109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL,
5119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     3, exifInfo->gps_timestamp, &LongerTagOffest, pIfdStart);
5129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = strlen((char*)exifInfo->gps_processing_method);
5139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (tmp > 0) {
5149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            if (tmp > 100) {
5159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                tmp = 100;
5169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            }
5179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            unsigned char tmp_buf[100+sizeof(ExifAsciiPrefix)];
5189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            memcpy(tmp_buf, ExifAsciiPrefix, sizeof(ExifAsciiPrefix));
5199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            memcpy(&tmp_buf[sizeof(ExifAsciiPrefix)], exifInfo->gps_processing_method, tmp);
5209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            writeExifIfd(&pCur, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED,
5219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                         tmp+sizeof(ExifAsciiPrefix), tmp_buf, &LongerTagOffest, pIfdStart);
5229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
5239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII,
5249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     11, exifInfo->gps_datestamp, &LongerTagOffest, pIfdStart);
5259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = 0;
5269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
5279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur += OFFSET_SIZE;
5289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
5299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    //2 1th IFD TIFF Tags
5319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *thumbBuf = NULL;
5329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned int thumbSize = 0;
5339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
5349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (useMainbufForThumb) {
5369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_jpegMain) {
5379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            ret = m_jpegMain->getOutBuf((char **)&thumbBuf, (int *)&thumbSize);
5389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            if (ret != ERROR_NONE) {
5399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                thumbBuf = NULL;
5409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            }
5419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            thumbSize = (unsigned int)m_jpegMain->getJpegSize();
5429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
5439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    } else {
5449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_jpegThumb) {
5459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            ret = m_jpegThumb->getOutBuf((char **)&thumbBuf, (int *)&thumbSize);
5469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            if (ret != ERROR_NONE) {
5479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                thumbBuf = NULL;
5489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            }
5499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            thumbSize = (unsigned int)m_jpegThumb->getJpegSize();
5509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
5519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
5529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (exifInfo->enableThumb && (thumbBuf != NULL) && (thumbSize != 0)) {
5549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        exifSizeExceptThumb = tmp = LongerTagOffest;
5559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
5569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur = pIfdStart + LongerTagOffest;
5589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = NUM_1TH_IFD_TIFF;
5609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pCur, &tmp, NUM_SIZE);
5619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur += NUM_SIZE;
5629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        LongerTagOffest += NUM_SIZE + NUM_1TH_IFD_TIFF*IFD_SIZE + OFFSET_SIZE;
5649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG,
5669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->widthThumb);
5679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG,
5689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->heightThumb);
5699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT,
5709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->compression_scheme);
5719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT,
5729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->orientation);
5739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL,
5749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, &exifInfo->x_resolution, &LongerTagOffest, pIfdStart);
5759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL,
5769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, &exifInfo->y_resolution, &LongerTagOffest, pIfdStart);
5779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT,
5789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, exifInfo->resolution_unit);
5799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG,
5809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, LongerTagOffest);
5819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        writeExifIfd(&pCur, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG,
5829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                     1, thumbSize);
5839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = 0;
5859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pCur, &tmp, OFFSET_SIZE); // next IFD offset
5869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        pCur += OFFSET_SIZE;
5879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
5889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pIfdStart + LongerTagOffest,
5899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin               thumbBuf, thumbSize);
5909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        LongerTagOffest += thumbSize;
5919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (LongerTagOffest > EXIF_LIMIT_SIZE) {
5929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            LongerTagOffest = exifSizeExceptThumb;
5939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            tmp = 0;
5949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
5959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
5969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    } else {
5979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        tmp = 0;
5989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        memcpy(pNextIfdOffset, &tmp, OFFSET_SIZE);  // NEXT IFD offset skipped on 0th IFD
5999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
6009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char App1Marker[2] = { 0xff, 0xe1 };
6029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pApp1Start, App1Marker, 2);
6039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pApp1Start += 2;
6049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *size = 10 + LongerTagOffest;
6069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    tmp = *size - 2;    // APP1 Maker isn't counted
6079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned char size_mm[2] = {(tmp >> 8) & 0xFF, tmp & 0xFF};
6089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(pApp1Start, size_mm, 2);
6099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
6119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
6129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin/*
6149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin * private member functions
6159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin*/
6169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shininline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
6179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short tag,
6189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short type,
6199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int count,
6209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int value)
6219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
6229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &tag, 2);
6239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &type, 2);
6259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &count, 4);
6279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &value, 4);
6299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
6319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shininline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
6339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short tag,
6349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short type,
6359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int count,
6369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned char *pValue)
6379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
6389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char buf[4] = { 0,};
6399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(buf, pValue, count);
6419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &tag, 2);
6429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &type, 2);
6449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &count, 4);
6469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, buf, 4);
6489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
6509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shininline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
6529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short tag,
6539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short type,
6549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int count,
6559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned char *pValue,
6569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int *offset,
6579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned char *start)
6589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
6599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &tag, 2);
6609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &type, 2);
6629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &count, 4);
6649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, offset, 4);
6669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(start + *offset, pValue, count);
6689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *offset += count;
6699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
6709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shininline void ExynosJpegEncoderForCamera::writeExifIfd(unsigned char **pCur,
6729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short tag,
6739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned short type,
6749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int count,
6759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             rational_t *pValue,
6769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned int *offset,
6779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                                             unsigned char *start)
6789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
6799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &tag, 2);
6809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &type, 2);
6829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 2;
6839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, &count, 4);
6849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(*pCur, offset, 4);
6869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *pCur += 4;
6879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    memcpy(start + *offset, pValue, 8 * count);
6889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *offset += 8 * count;
6899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
6909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::scaleDownYuv422(char **srcBuf, unsigned int srcW, unsigned int srcH,  char **dstBuf, unsigned int dstW, unsigned int dstH)
6929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
6939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int step_x, step_y;
6949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int src_y_start_pos, dst_pos, src_pos;
6959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *src_buf = srcBuf[0];
6969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *dst_buf = dstBuf[0];
6979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
6989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (dstW & 0x01 || dstH & 0x01) {
6999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
7009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    step_x = srcW / dstW;
7039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    step_y = srcH / dstH;
7049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned int srcWStride = srcW * 2;
7069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    unsigned int stepXStride = step_x * 2;
7079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    dst_pos = 0;
7099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    for (unsigned int y = 0; y < dstH; y++) {
7109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        src_y_start_pos = srcWStride * step_y * y;
7119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        for (unsigned int x = 0; x < dstW; x += 2) {
7139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            src_pos = src_y_start_pos + (stepXStride * x);
7149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos    ];
7169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos + 1];
7179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos + 2];
7189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos + 3];
7199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
7209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
7239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
7249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::scaleDownYuv422_2p(char **srcBuf, unsigned int srcW, unsigned int srcH, char **dstBuf, unsigned int dstW, unsigned int dstH)
7269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
7279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int32_t step_x, step_y;
7289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int32_t src_y_start_pos, dst_pos, src_pos;
7299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int32_t src_Y_offset;
7309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *src_buf;
7319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *dst_buf;
7329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (dstW % 2 != 0 || dstH % 2 != 0) {
7349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_INVALID_SCALING_WIDTH_HEIGHT;
7359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    step_x = srcW / dstW;
7389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    step_y = srcH / dstH;
7399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    // Y scale down
7419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    src_buf = srcBuf[0];
7429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    dst_buf = dstBuf[0];
7439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    dst_pos = 0;
7449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    for (uint32_t y = 0; y < dstH; y++) {
7459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        src_y_start_pos = y * step_y * srcW;
7469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        for (uint32_t x = 0; x < dstW; x++) {
7489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            src_pos = src_y_start_pos + (x * step_x);
7499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos];
7519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
7529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    // UV scale down
7559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    src_buf = srcBuf[1];
7569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    dst_buf = dstBuf[1];
7579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    dst_pos = 0;
7589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    for (uint32_t i = 0; i < dstH; i++) {
7599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        src_y_start_pos = i * step_y * srcW;
7609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        for (uint32_t j = 0; j < dstW; j += 2) {
7629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            src_pos = src_y_start_pos + (j * step_x);
7639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos    ];
7659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            dst_buf[dst_pos++] = src_buf[src_pos + 1];
7669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
7679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
7709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
7719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin// thumbnail
7739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setThumbnailSize(int w, int h)
7749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
7759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
7769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
7779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (w < 0 || MAX_JPG_WIDTH < w) {
7809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return false;
7819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (h < 0 || MAX_JPG_HEIGHT < h) {
7849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return false;
7859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailW = w;
7889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailH = h;
7899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
7909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
7919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::setThumbnailQuality(int quality)
7939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
7949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
7959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
7969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
7979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
7989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (quality < 1 || 100 < quality) {
7999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return false;
8009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    m_thumbnailQuality = quality;
8039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
8049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
8059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::encodeThumbnail(unsigned int *size, bool useMain)
8079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
8089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
8099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_flagCreate == false) {
8119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_CANNOT_CREATE_EXYNOS_JPEG_ENC_HAL;
8129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    // create jpeg thumbnail class
8159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_jpegThumb == NULL) {
8169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_jpegThumb = new ExynosJpegEncoder;
8179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_jpegThumb == NULL) {
8199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("ERR(%s):Cannot open a jpeg device file\n", __func__);
8209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ERROR_CANNOT_CREATE_SEC_THUMB;
8219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
8229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->create();
8259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
8269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail create\n", __func__);
8279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegThumb->setCache(JPEG_CACHE_ON);
8319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
8329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail cache set\n", __func__);
8339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    void *pConfig = m_jpegMain->getJpegConfig();
8379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (pConfig == NULL) {
8389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail getJpegConfig\n", __func__);
8399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFR_IS_NULL;
8409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->setJpegConfig(pConfig);
8439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
8449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail setJpegConfig\n", __func__);
8459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    /* TODO: Currently we fix the thumbnail quality */
8499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->setQuality(JPEG_THUMBNAIL_QUALITY);
8509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
8519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail setQuality\n", __func__);
8529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->setSize(m_thumbnailW, m_thumbnailH);
8569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
8579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail setSize\n", __func__);
8589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int iThumbSize = sizeof(char)*m_thumbnailW*m_thumbnailH*THUMBNAIL_IMAGE_PIXEL_SIZE;
8629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    char *pcThumbInBuf[MAX_INPUT_BUFFER_PLANE_NUM];
8639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int iThumbInBufSize[MAX_INPUT_BUFFER_PLANE_NUM];
8649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    switch (m_jpegMain->getColorFormat()) {
8659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    case V4L2_PIX_FMT_YUYV:
8669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iThumbInBufSize[0] = m_thumbnailW*m_thumbnailH*2;
8679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iThumbInBufSize[1] = 0;
8689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        break;
8699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    case V4L2_PIX_FMT_NV16:
8709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    case V4L2_PIX_FMT_NV61:
8719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iThumbInBufSize[0] = m_thumbnailW*m_thumbnailH;
8729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iThumbInBufSize[1] = m_thumbnailW*m_thumbnailH;
8739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        break;
8749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    default:
8759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_INVALID_COLOR_FORMAT;
8769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#ifdef JPEG_WA_FOR_PAGEFAULT
8789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    iThumbSize += JPEG_WA_BUFFER_SIZE;
8799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin#endif //JPEG_WA_FOR_PAGEFAULT
8809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    freeJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iThumbSize);
8829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    freeJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iThumbSize);
8839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (m_ionJpegClient == 0) {
8859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        m_ionJpegClient = ion_client_create();
8869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (m_ionJpegClient < 0) {
8879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("[%s]src ion client create failed, value = %d\n", __func__, m_ionJpegClient);
8889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            m_ionJpegClient = 0;
8899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
8909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
8919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = allocJpegIonMemory(m_ionJpegClient, &m_ionThumbInBuffer, &m_pThumbInputBuffer, iThumbSize);
8949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret != ERROR_NONE) {
8959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
8969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
8979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
8989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pcThumbInBuf[0] = m_pThumbInputBuffer;
8999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    pcThumbInBuf[1] = pcThumbInBuf[0] + iThumbInBufSize[0];
9009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->setInBuf(pcThumbInBuf, iThumbInBufSize);
9029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
9039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail setInBuf\n", __func__);
9049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
9059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = allocJpegIonMemory(m_ionJpegClient, &m_ionThumbOutBuffer, &m_pThumbOutputBuffer, iThumbSize);
9089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret != ERROR_NONE) {
9099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
9109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9129426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->setOutBuf((char *)m_pThumbOutputBuffer, iThumbSize);
9139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
9149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("ERR(%s):Fail setOutBuf\n", __func__);
9159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
9169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->updateConfig();
9199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
9209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("update config failed\n");
9219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
9229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (useMain) {
9259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iTempWidth=0;
9269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iTempHeight=0;
9279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        char *pcMainInputBuf[MAX_INPUT_BUFFER_PLANE_NUM];
9289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        char *pcThumbInputBuf[MAX_INPUT_BUFFER_PLANE_NUM];
9299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iMainInputSize[MAX_INPUT_BUFFER_PLANE_NUM];
9309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iThumbInputSize[MAX_INPUT_BUFFER_PLANE_NUM];
9319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        int iTempColorformat = 0;
9329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        iTempColorformat = m_jpegMain->getColorFormat();
9349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegMain->getSize(&iTempWidth, &iTempHeight);
9369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
9379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("ERR(%s):Fail getSize\n", __func__);
9389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
9399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
9409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegMain->getInBuf(pcMainInputBuf, iMainInputSize, MAX_INPUT_BUFFER_PLANE_NUM);
9429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
9439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("ERR(%s):Fail getInBuf\n", __func__);
9449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
9459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
9469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ret = m_jpegThumb->getInBuf(pcThumbInputBuf, iThumbInputSize, MAX_INPUT_BUFFER_PLANE_NUM);
9489426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
9499426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("ERR(%s):Fail getInBuf\n", __func__);
9509426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
9519426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
9529426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9539426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        switch (iTempColorformat) {
9549426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        case V4L2_PIX_FMT_YUYV:
9559426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            ret = scaleDownYuv422(pcMainInputBuf,
9569426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              iTempWidth,
9579426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              iTempHeight,
9589426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              pcThumbInputBuf,
9599426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              m_thumbnailW,
9609426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              m_thumbnailH);
9619426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            break;
9629426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        case V4L2_PIX_FMT_NV16:
9639426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            ret = scaleDownYuv422_2p(pcMainInputBuf,
9649426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              iTempWidth,
9659426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              iTempHeight,
9669426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              pcThumbInputBuf,
9679426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              m_thumbnailW,
9689426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin                              m_thumbnailH);
9699426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            break;
9709426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        default:
9719426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ERROR_INVALID_COLOR_FORMAT;
9729426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            break;
9739426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
9749426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        if (ret) {
9759426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            JPEG_ERROR_LOG("%s::scaleDown(%d, %d, %d, %d) fail", __func__, iTempWidth, iTempHeight, m_thumbnailW, m_thumbnailH);
9769426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin            return ret;
9779426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        }
9789426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9799426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    else {
9809426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_IMPLEMENT_NOT_YET;
9819426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9829426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9839426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int outSizeThumb;
9849426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9859426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    ret = m_jpegThumb->encode();
9869426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ret) {
9879426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("encode failed\n");
9889426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
9899426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9909426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9919426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    outSizeThumb = m_jpegThumb->getJpegSize();
9929426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (outSizeThumb<=0) {
9939426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("jpeg size is too small\n");
9949426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_THUMB_JPEG_SIZE_TOO_SMALL;
9959426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
9969426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9979426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *size = (unsigned int)outSizeThumb;
9989426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
9999426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ERROR_NONE;
10009426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10019426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
10029426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10039426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinint ExynosJpegEncoderForCamera::allocJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size)
10049426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
10059426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    int ret = ERROR_NONE;
10069426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10079426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ionClient == 0) {
10089426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("[%s]ionClient is zero (%d)\n", __func__, ionClient);
10099426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ERROR_BUFFR_IS_NULL;
10109426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10119426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1012eb42d13a54dda74f691c972d993dcbd10b6934b7Rebecca Schultz Zavin    *ionBuffer = ion_alloc(ionClient, size, 0, ION_HEAP_SYSTEM_MASK, 0);
10139426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (*ionBuffer == -1) {
10149426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("[%s]ion_alloc(%d) failed\n", __func__, size);
10159426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        *ionBuffer = 0;
10169426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
10179426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10189426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10199426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    *buffer = (char *)ion_map(*ionBuffer, size, 0);
10209426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (*buffer == MAP_FAILED) {
10219426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        JPEG_ERROR_LOG("[%s]src ion map failed(%d)\n", __func__, size);
10229426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ion_free(*ionBuffer);
10239426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        *ionBuffer = 0;
10249426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        *buffer = NULL;
10259426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return ret;
10269426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10279426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10289426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    return ret;
10299426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
10309426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10319426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shinvoid ExynosJpegEncoderForCamera::freeJpegIonMemory(ion_client ionClient, ion_buffer *ionBuffer, char **buffer, int size)
10329426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin{
10339426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (ionClient == 0) {
10349426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        return;
10359426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10369426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10379426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (*buffer != NULL) {
10389426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ion_unmap(*buffer, size);
10399426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        *buffer = NULL;
10409426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10419426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
10429426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    if (*ionBuffer != 0) {
10439426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        ion_free(*ionBuffer);
10449426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin        *ionBuffer = 0;
10459426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin    }
10469426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin}
10479426c428f0ffede2ee24d397912f7db84c56c3f7Jiyoung Shin
1048