YuvToJpegEncoder.cpp revision a696f5d667227365da732481770767dcb330dd23
1bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#include "CreateJavaOutputStreamAdaptor.h" 2bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#include "SkJpegUtility.h" 3bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#include "YuvToJpegEncoder.h" 48f2423e8f394ae0666f1b61f83df4c0c7a4782d9Mathias Agopian#include <ui/PixelFormat.h> 58f2423e8f394ae0666f1b61f83df4c0c7a4782d9Mathias Agopian#include <hardware/hardware.h> 6bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 7bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#include <jni.h> 8bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 9bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta ChenYuvToJpegEncoder* YuvToJpegEncoder::create(int format, int* strides) { 10a696f5d667227365da732481770767dcb330dd23Mathias Agopian // Only ImageFormat.NV21 and ImageFormat.YUY2 are supported 11bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // for now. 12a696f5d667227365da732481770767dcb330dd23Mathias Agopian if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { 13bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return new Yuv420SpToJpegEncoder(strides); 148f2423e8f394ae0666f1b61f83df4c0c7a4782d9Mathias Agopian } else if (format == HAL_PIXEL_FORMAT_YCbCr_422_I) { 15bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return new Yuv422IToJpegEncoder(strides); 16bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } else { 17bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return NULL; 18bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 19bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 20bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 21bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta ChenYuvToJpegEncoder::YuvToJpegEncoder(int* strides) : fStrides(strides) { 22bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 23bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 24bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenbool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width, 25bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int height, int* offsets, int jpegQuality) { 26bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_compress_struct cinfo; 27bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen skjpeg_error_mgr sk_err; 28bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen skjpeg_destination_mgr sk_wstream(stream); 29bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 30bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo.err = jpeg_std_error(&sk_err); 31bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen sk_err.error_exit = skjpeg_error_exit; 32bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen if (setjmp(sk_err.fJmpBuf)) { 33bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return false; 34bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 35bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_create_compress(&cinfo); 36bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 37bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo.dest = &sk_wstream; 38bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 39bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen setJpegCompressStruct(&cinfo, width, height, jpegQuality); 40bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 41bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_start_compress(&cinfo, TRUE); 42bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 43bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen compress(&cinfo, (uint8_t*) inYuv, offsets); 44bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 45bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_finish_compress(&cinfo); 46bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 47bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return true; 48bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 49bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 50bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid YuvToJpegEncoder::setJpegCompressStruct(jpeg_compress_struct* cinfo, 51bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int width, int height, int quality) { 52bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_set_quality(cinfo, quality, TRUE); 53bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 54bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->image_width = width; 55bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->image_height = height; 56bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 57bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->input_components = 3; 58bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->in_color_space = JCS_YCbCr; 59bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_set_defaults(cinfo); 60bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_set_colorspace(cinfo, JCS_YCbCr); 61bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->raw_data_in = TRUE; 62bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 63bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->dct_method = JDCT_IFAST; 64bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 65bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen configSamplingFactors(cinfo); 66bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 67bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 68bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen/////////////////////////////////////////////////////////////////// 69bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta ChenYuv420SpToJpegEncoder::Yuv420SpToJpegEncoder(int* strides) : 70bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen YuvToJpegEncoder(strides) { 71bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen fNumPlanes = 2; 72bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 73bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 74bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo, 75bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yuv, int* offsets) { 76bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen SkDebugf("onFlyCompress"); 77bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW y[16]; 78bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW cb[8]; 79bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW cr[8]; 80bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPARRAY planes[3]; 81bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[0] = y; 82bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[1] = cb; 83bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[2] = cr; 84bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 85bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int width = cinfo->image_width; 86bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int height = cinfo->image_height; 87bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yPlanar = yuv + offsets[0]; 88bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vuPlanar = yuv + offsets[1]; //width * height; 89bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* uRows = new uint8_t [8 * (width >> 1)]; 90bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vRows = new uint8_t [8 * (width >> 1)]; 91bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 92bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 93bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // process 16 lines of Y and 8 lines of U/V each time. 94bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen while (cinfo->next_scanline < cinfo->image_height) { 95bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen //deitnerleave u and v 96bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen deinterleave(vuPlanar, uRows, vRows, cinfo->next_scanline, width); 97bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 98bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int i = 0; i < 16; i++) { 99bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // y row 100bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0]; 101bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 102bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // construct u row and v row 103bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen if ((i & 1) == 0) { 104bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // height and width are both halved because of downsampling 105bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int offset = (i >> 1) * (width >> 1); 106bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cb[i/2] = uRows + offset; 107bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cr[i/2] = vRows + offset; 108bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 109bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 110bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_write_raw_data(cinfo, planes, 16); 111bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 112bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete [] uRows; 113bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete [] vRows; 114bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 115bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 116bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 117bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows, 118bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vRows, int rowIndex, int width) { 119bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int row = 0; row < 8; ++row) { 120bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int offset = ((rowIndex >> 1) + row) * fStrides[1]; 121bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vu = vuPlanar + offset; 122bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int i = 0; i < (width >> 1); ++i) { 123bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int index = row * (width >> 1) + i; 124bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uRows[index] = vu[1]; 125bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen vRows[index] = vu[0]; 126bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen vu += 2; 127bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 128bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 129bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 130bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 131bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv420SpToJpegEncoder::configSamplingFactors(jpeg_compress_struct* cinfo) { 132bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // cb and cr are horizontally downsampled and vertically downsampled as well. 133bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[0].h_samp_factor = 2; 134bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[0].v_samp_factor = 2; 135bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[1].h_samp_factor = 1; 136bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[1].v_samp_factor = 1; 137bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[2].h_samp_factor = 1; 138bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[2].v_samp_factor = 1; 139bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 140bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 141bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen/////////////////////////////////////////////////////////////////////////////// 142bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta ChenYuv422IToJpegEncoder::Yuv422IToJpegEncoder(int* strides) : 143bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen YuvToJpegEncoder(strides) { 144bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen fNumPlanes = 1; 145bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 146bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 147bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv422IToJpegEncoder::compress(jpeg_compress_struct* cinfo, 148bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yuv, int* offsets) { 149bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen SkDebugf("onFlyCompress_422"); 150bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW y[16]; 151bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW cb[16]; 152bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPROW cr[16]; 153bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen JSAMPARRAY planes[3]; 154bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[0] = y; 155bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[1] = cb; 156bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen planes[2] = cr; 157bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 158bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int width = cinfo->image_width; 159bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int height = cinfo->image_height; 160bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yRows = new uint8_t [16 * width]; 161bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* uRows = new uint8_t [16 * (width >> 1)]; 162bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vRows = new uint8_t [16 * (width >> 1)]; 163bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 164bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yuvOffset = yuv + offsets[0]; 165bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 166bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // process 16 lines of Y and 16 lines of U/V each time. 167bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen while (cinfo->next_scanline < cinfo->image_height) { 168bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen deinterleave(yuvOffset, yRows, uRows, vRows, cinfo->next_scanline, width, height); 169bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 170bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int i = 0; i < 16; i++) { 171bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // y row 172bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen y[i] = yRows + i * width; 173bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 174bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // construct u row and v row 175bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // width is halved because of downsampling 176bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int offset = i * (width >> 1); 177bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cb[i] = uRows + offset; 178bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cr[i] = vRows + offset; 179bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 180bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 181bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jpeg_write_raw_data(cinfo, planes, 16); 182bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 183bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete [] yRows; 184bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete [] uRows; 185bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete [] vRows; 186bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 187bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 188bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 189bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv422IToJpegEncoder::deinterleave(uint8_t* yuv, uint8_t* yRows, uint8_t* uRows, 190bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* vRows, int rowIndex, int width, int height) { 191bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int row = 0; row < 16; ++row) { 192bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uint8_t* yuvSeg = yuv + (rowIndex + row) * fStrides[0]; 193bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen for (int i = 0; i < (width >> 1); ++i) { 194bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int indexY = row * width + (i << 1); 195bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int indexU = row * (width >> 1) + i; 196bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen yRows[indexY] = yuvSeg[0]; 197bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen yRows[indexY + 1] = yuvSeg[2]; 198bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen uRows[indexU] = yuvSeg[1]; 199bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen vRows[indexU] = yuvSeg[3]; 200bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen yuvSeg += 4; 201bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 202bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 203bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 204bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 205bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenvoid Yuv422IToJpegEncoder::configSamplingFactors(jpeg_compress_struct* cinfo) { 206bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen // cb and cr are horizontally downsampled and vertically downsampled as well. 207bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[0].h_samp_factor = 2; 208bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[0].v_samp_factor = 2; 209bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[1].h_samp_factor = 1; 210bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[1].v_samp_factor = 2; 211bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[2].h_samp_factor = 1; 212bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen cinfo->comp_info[2].v_samp_factor = 2; 213bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 214bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen/////////////////////////////////////////////////////////////////////////////// 215bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 216bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenstatic jboolean YuvImage_compressToJpeg(JNIEnv* env, jobject, jbyteArray inYuv, 217bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen int format, int width, int height, jintArray offsets, 218bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jintArray strides, int jpegQuality, jobject jstream, 219bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jbyteArray jstorage) { 220bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jbyte* yuv = env->GetByteArrayElements(inYuv, NULL); 221bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen SkWStream* strm = CreateJavaOutputStreamAdaptor(env, jstream, jstorage); 222bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 223bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jint* imgOffsets = env->GetIntArrayElements(offsets, NULL); 224bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen jint* imgStrides = env->GetIntArrayElements(strides, NULL); 225bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen YuvToJpegEncoder* encoder = YuvToJpegEncoder::create(format, imgStrides); 226bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen if (encoder == NULL) { 227bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return false; 228bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen } 229bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen encoder->encode(strm, yuv, width, height, imgOffsets, jpegQuality); 230bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 231bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen delete encoder; 232bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen env->ReleaseByteArrayElements(inYuv, yuv, 0); 233bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen env->ReleaseIntArrayElements(offsets, imgOffsets, 0); 234bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen env->ReleaseIntArrayElements(strides, imgStrides, 0); 235bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return true; 236bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 237bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen/////////////////////////////////////////////////////////////////////////////// 238bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 239bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#include <android_runtime/AndroidRuntime.h> 240bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 241bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenstatic JNINativeMethod gYuvImageMethods[] = { 242bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen { "nativeCompressToJpeg", "([BIII[I[IILjava/io/OutputStream;[B)Z", 243bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen (void*)YuvImage_compressToJpeg } 244bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen}; 245bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 246bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen#define kClassPathName "android/graphics/YuvImage" 247bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen 248bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenint register_android_graphics_YuvImage(JNIEnv* env); 249bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chenint register_android_graphics_YuvImage(JNIEnv* env) 250bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen{ 251bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen return android::AndroidRuntime::registerNativeMethods(env, kClassPathName, 252bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen gYuvImageMethods, SK_ARRAY_COUNT(gYuvImageMethods)); 253bca2d613e0d6d2630fedd302c0d779b7610adbcfWei-Ta Chen} 254