Encoder_libjpeg.cpp revision ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf
1/* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/** 18* @file Encoder_libjpeg.cpp 19* 20* This file encodes a YUV422I buffer to a jpeg 21* TODO(XXX): Need to support formats other than yuv422i 22* Change interface to pre/post-proc algo framework 23* 24*/ 25 26#define LOG_TAG "CameraHAL" 27 28#include "CameraHal.h" 29#include "Encoder_libjpeg.h" 30 31#include <stdlib.h> 32#include <unistd.h> 33#include <sys/types.h> 34#include <sys/stat.h> 35#include <fcntl.h> 36#include <stdio.h> 37#include <errno.h> 38 39extern "C" { 40 #include "jpeglib.h" 41 #include "jerror.h" 42} 43 44namespace android { 45 46struct libjpeg_destination_mgr : jpeg_destination_mgr { 47 libjpeg_destination_mgr(uint8_t* input, int size); 48 49 uint8_t* buf; 50 int bufsize; 51 size_t jpegsize; 52}; 53 54static void libjpeg_init_destination (j_compress_ptr cinfo) { 55 libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 56 57 dest->next_output_byte = dest->buf; 58 dest->free_in_buffer = dest->bufsize; 59 dest->jpegsize = 0; 60} 61 62static boolean libjpeg_empty_output_buffer(j_compress_ptr cinfo) { 63 libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 64 65 dest->next_output_byte = dest->buf; 66 dest->free_in_buffer = dest->bufsize; 67 return TRUE; // ? 68} 69 70static void libjpeg_term_destination (j_compress_ptr cinfo) { 71 libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; 72 dest->jpegsize = dest->bufsize - dest->free_in_buffer; 73} 74 75libjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) { 76 this->init_destination = libjpeg_init_destination; 77 this->empty_output_buffer = libjpeg_empty_output_buffer; 78 this->term_destination = libjpeg_term_destination; 79 80 this->buf = input; 81 this->bufsize = size; 82} 83 84/* private static functions */ 85 86static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { 87 // TODO(XXX): optimize later 88 while ((width-=2) >= 0) { 89 uint8_t u0 = (src[0] >> 0) & 0xFF; 90 uint8_t y0 = (src[0] >> 8) & 0xFF; 91 uint8_t v0 = (src[0] >> 16) & 0xFF; 92 uint8_t y1 = (src[0] >> 24) & 0xFF; 93 dst[0] = y0; 94 dst[1] = u0; 95 dst[2] = v0; 96 dst[3] = y1; 97 dst[4] = u0; 98 dst[5] = v0; 99 dst += 6; 100 src++; 101 } 102} 103 104/* private member functions */ 105size_t Encoder_libjpeg::encode() { 106 jpeg_compress_struct cinfo; 107 jpeg_error_mgr jerr; 108 jpeg_destination_mgr jdest; 109 uint8_t* row_tmp = NULL; 110 uint8_t* row_src = NULL; 111 int bpp = 2; // TODO(XXX): hardcoded for uyvy 112 113 cinfo.err = jpeg_std_error(&jerr); 114 115 jpeg_create_compress(&cinfo); 116 117 libjpeg_destination_mgr dest_mgr(mDest, mDestSize); 118 119 CAMHAL_LOGDB("encoding... \n\t" 120 "width: %d \n\t" 121 "height:%d \n\t" 122 "dest %p \n\t" 123 "dest size:%d \n\t" 124 "mSrc %p", 125 mWidth, mHeight, mDest, mDestSize, mSrc); 126 127 cinfo.dest = &dest_mgr; 128 cinfo.image_width = mWidth; 129 cinfo.image_height = mHeight; 130 cinfo.input_components = 3; 131 cinfo.in_color_space = JCS_YCbCr; 132 cinfo.input_gamma = 1; 133 134 jpeg_set_defaults(&cinfo); 135 jpeg_set_quality(&cinfo, mQuality, TRUE); 136 cinfo.dct_method = JDCT_IFAST; 137 138 jpeg_start_compress(&cinfo, TRUE); 139 140 row_tmp = (uint8_t*)malloc(mWidth * 3); 141 row_src = mSrc; 142 143 while (cinfo.next_scanline < cinfo.image_height) { 144 JSAMPROW row[1]; /* pointer to JSAMPLE row[s] */ 145 146 uyvy_to_yuv(row_tmp, (uint32_t*)row_src, mWidth); 147 row[0] = row_tmp; 148 jpeg_write_scanlines(&cinfo, row, 1); 149 row_src = row_src + mWidth*bpp; 150 } 151 152 jpeg_finish_compress(&cinfo); 153 jpeg_destroy_compress(&cinfo); 154 155 return dest_mgr.jpegsize; 156} 157 158} // namespace android 159