1ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu/* 2ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * Copyright (C) Texas Instruments - http://www.ti.com/ 3ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * 4ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * Licensed under the Apache License, Version 2.0 (the "License"); 5ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * you may not use this file except in compliance with the License. 6ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * You may obtain a copy of the License at 7ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * 8ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * http://www.apache.org/licenses/LICENSE-2.0 9ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * 10ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * Unless required by applicable law or agreed to in writing, software 11ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * distributed under the License is distributed on an "AS IS" BASIS, 12ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * See the License for the specific language governing permissions and 14ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu * limitations under the License. 15ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu */ 16ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 17ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu/** 18ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* @file Encoder_libjpeg.cpp 19ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* 20ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* This file encodes a YUV422I buffer to a jpeg 21ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* TODO(XXX): Need to support formats other than yuv422i 22ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* Change interface to pre/post-proc algo framework 23ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu* 24ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu*/ 25ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 26ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#define LOG_TAG "CameraHAL" 27ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 28ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include "CameraHal.h" 29ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include "Encoder_libjpeg.h" 30c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu#include "NV12_resize.h" 31ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 32ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <stdlib.h> 33ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <unistd.h> 34ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <sys/types.h> 35ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <sys/stat.h> 36ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <fcntl.h> 37ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <stdio.h> 38ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu#include <errno.h> 39c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu#include <math.h> 40ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 41ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luuextern "C" { 42ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu #include "jpeglib.h" 43ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu #include "jerror.h" 44ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 45ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 4636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu#define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0])) 47ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu#define MIN(x,y) ((x < y) ? x : y) 4836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 49ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luunamespace android { 50c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peevstruct integer_string_pair { 51c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev unsigned int integer; 52c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev const char* string; 5336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu}; 54ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 55c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peevstatic integer_string_pair degress_to_exif_lut [] = { 5636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu // degrees, exif_orientation 57c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev {0, "1"}, 58c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev {90, "6"}, 59c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev {180, "3"}, 60c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev {270, "8"}, 6136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu}; 62ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luustruct libjpeg_destination_mgr : jpeg_destination_mgr { 63ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu libjpeg_destination_mgr(uint8_t* input, int size); 64ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 65ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu uint8_t* buf; 66ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu int bufsize; 67ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu size_t jpegsize; 68ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu}; 69ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 70ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luustatic void libjpeg_init_destination (j_compress_ptr cinfo) { 71ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 72ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 73ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->next_output_byte = dest->buf; 74ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->free_in_buffer = dest->bufsize; 75ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->jpegsize = 0; 76ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 77ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 78ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luustatic boolean libjpeg_empty_output_buffer(j_compress_ptr cinfo) { 79ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 80ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 81ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->next_output_byte = dest->buf; 82ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->free_in_buffer = dest->bufsize; 83ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu return TRUE; // ? 84ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 85ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 86ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luustatic void libjpeg_term_destination (j_compress_ptr cinfo) { 87ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 88ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu dest->jpegsize = dest->bufsize - dest->free_in_buffer; 89ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 90ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 91ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luulibjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) { 92ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu this->init_destination = libjpeg_init_destination; 93ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu this->empty_output_buffer = libjpeg_empty_output_buffer; 94ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu this->term_destination = libjpeg_term_destination; 95ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 96ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu this->buf = input; 97ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu this->bufsize = size; 98c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 99c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu jpegsize = 0; 100ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 101ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 102ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu/* private static functions */ 103c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luustatic void nv21_to_yuv(uint8_t* dst, uint8_t* y, uint8_t* uv, int width) { 104c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (!dst || !y || !uv) { 105c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu return; 106c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 107c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 108cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng while ((width--) > 0) { 109c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu uint8_t y0 = y[0]; 110c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu uint8_t v0 = uv[0]; 111c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu uint8_t u0 = *(uv+1); 112c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu dst[0] = y0; 113c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu dst[1] = u0; 114c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu dst[2] = v0; 115c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu dst += 3; 116c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu y++; 117c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if(!(width % 2)) uv+=2; 118c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 119c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu} 120ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 121ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luustatic void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { 12276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu if (!dst || !src) { 12376f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu return; 12476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu } 12576f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu 12676f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu if (width % 2) { 12776f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu return; // not supporting odd widths 12876f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu } 12976f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu 13076f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu // currently, neon routine only supports multiple of 16 width 13176f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu if (width % 16) { 13276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu while ((width-=2) >= 0) { 13376f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu uint8_t u0 = (src[0] >> 0) & 0xFF; 13476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu uint8_t y0 = (src[0] >> 8) & 0xFF; 13576f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu uint8_t v0 = (src[0] >> 16) & 0xFF; 13676f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu uint8_t y1 = (src[0] >> 24) & 0xFF; 13776f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[0] = y0; 13876f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[1] = u0; 13976f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[2] = v0; 14076f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[3] = y1; 14176f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[4] = u0; 14276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst[5] = v0; 14376f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu dst += 6; 14476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu src++; 14576f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu } 14676f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu } else { 14776f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu int n = width; 14876f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu asm volatile ( 14976f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " pld [%[src], %[src_stride], lsl #2] \n\t" 15076f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " cmp %[n], #16 \n\t" 15176f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " blt 5f \n\t" 15276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu "0: @ 16 pixel swap \n\t" 15376f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vld2.8 {q0, q1} , [%[src]]! @ q0 = uv q1 = y \n\t" 15476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vuzp.8 q0, q2 @ d1 = u d5 = v \n\t" 15576f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vmov d1, d0 @ q0 = u0u1u2..u0u1u2... \n\t" 15676f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vmov d5, d4 @ q2 = v0v1v2..v0v1v2... \n\t" 15776f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vzip.8 d0, d1 @ q0 = u0u0u1u1u2u2... \n\t" 15876f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vzip.8 d4, d5 @ q2 = v0v0v1v1v2v2... \n\t" 15976f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vswp q0, q1 @ now q0 = y q1 = u q2 = v \n\t" 16076f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vst3.8 {d0,d2,d4},[%[dst]]! \n\t" 16176f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vst3.8 {d1,d3,d5},[%[dst]]! \n\t" 16276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " sub %[n], %[n], #16 \n\t" 16376f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " cmp %[n], #16 \n\t" 16476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " bge 0b \n\t" 16576f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu "5: @ end \n\t" 16676f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu#ifdef NEEDS_ARM_ERRATA_754319_754320 16776f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu " vmov s0,s0 @ add noop for errata item \n\t" 16876f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu#endif 16976f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) 17076f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu : [src_stride] "r" (width) 17176f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu : "cc", "memory", "q0", "q1", "q2" 17276f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu ); 173ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu } 174ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 175ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 176c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luustatic void resize_nv12(Encoder_libjpeg::params* params, uint8_t* dst_buffer) { 177c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu structConvImage o_img_ptr, i_img_ptr; 178c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 179c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (!params || !dst_buffer) { 180c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu return; 181c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 182c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 183c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu //input 184c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.uWidth = params->in_width; 185c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.uStride = i_img_ptr.uWidth; 186c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.uHeight = params->in_height; 187c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp; 188c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.imgPtr = (uint8_t*) params->src; 189c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu i_img_ptr.clrPtr = i_img_ptr.imgPtr + (i_img_ptr.uWidth * i_img_ptr.uHeight); 190c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 191c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu //ouput 192c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.uWidth = params->out_width; 193c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.uStride = o_img_ptr.uWidth; 194c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.uHeight = params->out_height; 195c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp; 196c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.imgPtr = dst_buffer; 197c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu o_img_ptr.clrPtr = o_img_ptr.imgPtr + (o_img_ptr.uWidth * o_img_ptr.uHeight); 198c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 199c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu VT_resizeFrame_Video_opt2_lp(&i_img_ptr, &o_img_ptr, NULL, 0); 200c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu} 201c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 20236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu/* public static functions */ 203c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peevconst char* ExifElementsTable::degreesToExifOrientation(unsigned int degrees) { 20476f0345d0475def0f0c6fd2da7c2b35ed8a1bb2aTyler Luu for (unsigned int i = 0; i < ARRAY_SIZE(degress_to_exif_lut); i++) { 205c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev if (degrees == degress_to_exif_lut[i].integer) { 206c78626b15e9f29a5bcf85447ceafb17dcbf58b69Emilian Peev return degress_to_exif_lut[i].string; 20736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 20836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 20936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu return NULL; 21036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu} 21136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 212c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luuvoid ExifElementsTable::stringToRational(const char* str, unsigned int* num, unsigned int* den) { 213c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu int len; 214c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu char * tempVal = NULL; 215c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 216c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (str != NULL) { 217c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu len = strlen(str); 218c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu tempVal = (char*) malloc( sizeof(char) * (len + 1)); 219c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } 220c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 221c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (tempVal != NULL) { 222c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu // convert the decimal string into a rational 223c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu size_t den_len; 224c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu char *ctx; 225c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu unsigned int numerator = 0; 226c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu unsigned int denominator = 0; 227c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu char* temp = NULL; 228c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 229c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu memset(tempVal, '\0', len + 1); 230c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu strncpy(tempVal, str, len); 231c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu temp = strtok_r(tempVal, ".", &ctx); 232c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 233c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (temp != NULL) 234c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu numerator = atoi(temp); 235c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 236c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (!numerator) 237c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu numerator = 1; 238c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 239c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu temp = strtok_r(NULL, ".", &ctx); 240c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (temp != NULL) { 241c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu den_len = strlen(temp); 242c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if(HUGE_VAL == den_len ) { 243c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu den_len = 0; 244c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } 245c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 246c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu denominator = static_cast<unsigned int>(pow(10, den_len)); 247c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu numerator = numerator * denominator + atoi(temp); 248c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } else { 249c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu denominator = 1; 250c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } 251c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 252c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu free(tempVal); 253c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 254c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu *num = numerator; 255c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu *den = denominator; 256c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } 257c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu} 258c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 259c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luubool ExifElementsTable::isAsciiTag(const char* tag) { 260c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu // TODO(XXX): Add tags as necessary 261c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu return (strcmp(tag, TAG_GPS_PROCESSING_METHOD) == 0); 262c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu} 263c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu 26436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luuvoid ExifElementsTable::insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size) { 26536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu ReadMode_t read_mode = (ReadMode_t)(READ_METADATA | READ_IMAGE); 26636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 26736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu ResetJpgfile(); 26836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (ReadJpegSectionsFromBuffer(jpeg, jpeg_size, read_mode)) { 26936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu jpeg_opened = true; 2701e3a7ee3fced4b9723f65147ae856bba7d4e2342Angus Kong create_EXIF(table, exif_tag_count, gps_tag_count, has_datetime_tag); 27136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 27236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu} 27336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 274c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luustatus_t ExifElementsTable::insertExifThumbnailImage(const char* thumb, int len) { 275c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu status_t ret = NO_ERROR; 276c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 277c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if ((len > 0) && jpeg_opened) { 278c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu ret = ReplaceThumbnailFromBuffer(thumb, len); 279c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu CAMHAL_LOGDB("insertExifThumbnailImage. ReplaceThumbnail(). ret=%d", ret); 280c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 281c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 282c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu return ret; 283c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu} 284c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 28536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luuvoid ExifElementsTable::saveJpeg(unsigned char* jpeg, size_t jpeg_size) { 28636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (jpeg_opened) { 28736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu WriteJpegToBuffer(jpeg, jpeg_size); 28836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu DiscardData(); 28936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu jpeg_opened = false; 29036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 29136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu} 29236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 29336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu/* public functions */ 29436e9bdd56757ff8048e08f6e52f234480c44f122Tyler LuuExifElementsTable::~ExifElementsTable() { 29536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu int num_elements = gps_tag_count + exif_tag_count; 29636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 29736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu for (int i = 0; i < num_elements; i++) { 29836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (table[i].Value) { 29936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu free(table[i].Value); 30036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 30136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 30236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 30336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (jpeg_opened) { 30436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu DiscardData(); 30536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 30636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu} 30736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 30836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luustatus_t ExifElementsTable::insertElement(const char* tag, const char* value) { 309ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu unsigned int value_length = 0; 31036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu status_t ret = NO_ERROR; 31136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 31236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (!value || !tag) { 31336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu return -EINVAL; 31436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 31536e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 31636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (position >= MAX_EXIF_TAGS_SUPPORTED) { 31736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu CAMHAL_LOGEA("Max number of EXIF elements already inserted"); 31836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu return NO_MEMORY; 31936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 32036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 321c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu if (isAsciiTag(tag)) { 322c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu value_length = sizeof(ExifAsciiPrefix) + strlen(value + sizeof(ExifAsciiPrefix)); 323c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } else { 324c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu value_length = strlen(value); 325c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu } 32636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 32736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (IsGpsTag(tag)) { 32836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].GpsTag = TRUE; 32936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].Tag = GpsTagNameToValue(tag); 33036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu gps_tag_count++; 33136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } else { 33236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].GpsTag = FALSE; 33336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].Tag = TagNameToValue(tag); 33436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu exif_tag_count++; 335ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu 336ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu if (strcmp(tag, TAG_DATETIME) == 0) { 3371e3a7ee3fced4b9723f65147ae856bba7d4e2342Angus Kong has_datetime_tag = true; 338ef73bec8a83a2fd7fbb072d009382c64eb2da0eeTyler Luu } 33936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 34036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 34136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].DataLength = 0; 34236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].Value = (char*) malloc(sizeof(char) * (value_length + 1)); 34336e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 34436e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu if (table[position].Value) { 345c11c07d676f130e6e28ab1611f4862a01a160389Tyler Luu memcpy(table[position].Value, value, value_length + 1); 34636e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu table[position].DataLength = value_length + 1; 34736e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu } 34836e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 34936e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu position++; 35036e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu return ret; 35136e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu} 35236e9bdd56757ff8048e08f6e52f234480c44f122Tyler Luu 353ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu/* private member functions */ 354c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luusize_t Encoder_libjpeg::encode(params* input) { 355ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_compress_struct cinfo; 356ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_error_mgr jerr; 357ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_destination_mgr jdest; 358c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu uint8_t* src = NULL, *resize_src = NULL; 359ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu uint8_t* row_tmp = NULL; 360ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu uint8_t* row_src = NULL; 361c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu uint8_t* row_uv = NULL; // used only for NV12 362c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu int out_width = 0, in_width = 0; 363c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu int out_height = 0, in_height = 0; 364c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu int bpp = 2; // for uyvy 365d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov int right_crop = 0, start_offset = 0; 366c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 367c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (!input) { 368c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu return 0; 369c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 370c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 371c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu out_width = input->out_width; 372c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu in_width = input->in_width; 373c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu out_height = input->out_height; 374c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu in_height = input->in_height; 375d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov right_crop = input->right_crop; 376d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov start_offset = input->start_offset; 377c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu src = input->src; 378c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu input->jpeg_size = 0; 379c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 380c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu libjpeg_destination_mgr dest_mgr(input->dst, input->dst_size); 381c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 382c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu // param check... 383c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if ((in_width < 2) || (out_width < 2) || (in_height < 2) || (out_height < 2) || 384c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu (src == NULL) || (input->dst == NULL) || (input->quality < 1) || (input->src_size < 1) || 385c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu (input->dst_size < 1) || (input->format == NULL)) { 386c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu goto exit; 387c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 388c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 389c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 390c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu bpp = 1; 391c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if ((in_width != out_width) || (in_height != out_height)) { 392c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu resize_src = (uint8_t*) malloc(input->dst_size); 393c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu resize_nv12(input, resize_src); 394c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (resize_src) src = resize_src; 395c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 396c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } else if ((in_width != out_width) || (in_height != out_height)) { 397c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format); 398c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu goto exit; 399c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I)) { 400c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu // we currently only support yuv422i and yuv420sp 401c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu CAMHAL_LOGEB("Encoder: format not supported: %s", input->format); 402c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu goto exit; 403c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 404ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 405ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.err = jpeg_std_error(&jerr); 406ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 407ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_create_compress(&cinfo); 408ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 409ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu CAMHAL_LOGDB("encoding... \n\t" 410ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu "width: %d \n\t" 411ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu "height:%d \n\t" 412ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu "dest %p \n\t" 413ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu "dest size:%d \n\t" 414ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu "mSrc %p", 415c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu out_width, out_height, input->dst, 416c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu input->dst_size, src); 417ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 418ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.dest = &dest_mgr; 419d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov cinfo.image_width = out_width - right_crop; 420c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu cinfo.image_height = out_height; 421ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.input_components = 3; 422ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.in_color_space = JCS_YCbCr; 423ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.input_gamma = 1; 424ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 425ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_set_defaults(&cinfo); 426c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu jpeg_set_quality(&cinfo, input->quality, TRUE); 427ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu cinfo.dct_method = JDCT_IFAST; 428ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 429ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_start_compress(&cinfo, TRUE); 430ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 431c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu row_tmp = (uint8_t*)malloc(out_width * 3); 432d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov row_src = src + start_offset; 433c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu row_uv = src + out_width * out_height * bpp; 434ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 4358e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu while ((cinfo.next_scanline < cinfo.image_height) && !mCancelEncoding) { 436ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu JSAMPROW row[1]; /* pointer to JSAMPLE row[s] */ 437ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 438c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu // convert input yuv format to yuv444 439c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 440d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov nv21_to_yuv(row_tmp, row_src, row_uv, out_width - right_crop); 441c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } else { 442d9520b9de06f01b9411307040cf245e6fc7fe361Milen Mitkov uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width - right_crop); 443c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 444c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 445ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu row[0] = row_tmp; 446ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_write_scanlines(&cinfo, row, 1); 447c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu row_src = row_src + out_width*bpp; 448c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 449c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu // move uv row if input format needs it 450c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 451c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (!(cinfo.next_scanline % 2)) 452c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu row_uv = row_uv + out_width * bpp; 453c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu } 454ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu } 455ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 4568e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu // no need to finish encoding routine if we are prematurely stopping 4578e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu // we will end up crashing in dest_mgr since data is incomplete 4588e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu if (!mCancelEncoding) 4598e52e3bcc31f65a699c25557cf3026d324e631b4Tyler Luu jpeg_finish_compress(&cinfo); 460ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu jpeg_destroy_compress(&cinfo); 461ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 462c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu if (resize_src) free(resize_src); 463cb1183d6c3c8894fa09ad3ff7952388f6e7bec94Akwasi Boateng if (row_tmp) free(row_tmp); 464c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu 465c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu exit: 466c160a1f85c70e49a7613d774e2d99035f3cb4851Tyler Luu input->jpeg_size = dest_mgr.jpegsize; 467ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu return dest_mgr.jpegsize; 468ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} 469ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu 470ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cfTyler Luu} // namespace android 471