141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org/* 241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * Copyright 2012 The LibYuv Project Authors. All rights reserved. 341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * 441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * Use of this source code is governed by a BSD-style license 541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * that can be found in the LICENSE file in the root of the source 641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * tree. An additional intellectual property rights grant can be found 741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * in the file PATENTS. All contributing project authors may 841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * be found in the AUTHORS file in the root of the source tree. 941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org */ 1041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 1141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/mjpeg_decoder.h" 1241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 1341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_JPEG 1441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include <assert.h> 1541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 16d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org#if !defined(__pnacl__) && !defined(__CLR_VER) && \ 17d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org !defined(COVERAGE_ENABLED) && !defined(TARGET_IPHONE_SIMULATOR) 1841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Must be included before jpeglib. 1941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include <setjmp.h> 2041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAVE_SETJMP 2141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 2241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstruct FILE; // For jpeglib.h. 2341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 2441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// C++ build requires extern C for jpeg internals. 2541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus 2641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgextern "C" { 2741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 2841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 2941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include <jpeglib.h> 3041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 3141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus 3241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} // extern "C" 3341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 3441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 3541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/planar_functions.h" // For CopyPlane(). 3641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 3741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgnamespace libyuv { 3841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 3941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 4041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstruct SetJmpErrorMgr { 4141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_error_mgr base; // Must be at the top 4241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jmp_buf setjmp_buffer; 4341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}; 4441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 4541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 4641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceUnknown = JCS_UNKNOWN; 4741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceGrayscale = JCS_GRAYSCALE; 4841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceRgb = JCS_RGB; 4941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceYCbCr = JCS_YCbCr; 5041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceCMYK = JCS_CMYK; 5141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgconst int MJpegDecoder::kColorSpaceYCCK = JCS_YCCK; 5241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 5341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Methods that are passed to jpeglib. 5441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgboolean fill_input_buffer(jpeg_decompress_struct* cinfo); 5541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid init_source(jpeg_decompress_struct* cinfo); 5641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid skip_input_data(jpeg_decompress_struct* cinfo, 5741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org long num_bytes); // NOLINT 5841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid term_source(jpeg_decompress_struct* cinfo); 5941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid ErrorHandler(jpeg_common_struct* cinfo); 6041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 6141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgMJpegDecoder::MJpegDecoder() 6241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org : has_scanline_padding_(LIBYUV_FALSE), 6341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org num_outbufs_(0), 6441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_(NULL), 6541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_sizes_(NULL), 6641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_(NULL), 6741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_strides_(NULL) { 6841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_ = new jpeg_decompress_struct; 6941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_ = new jpeg_source_mgr; 7041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 7141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org error_mgr_ = new SetJmpErrorMgr; 7241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->err = jpeg_std_error(&error_mgr_->base); 7341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Override standard exit()-based error handler. 7441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org error_mgr_->base.error_exit = &ErrorHandler; 7541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 7641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->client_data = NULL; 7741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_->init_source = &init_source; 7841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_->fill_input_buffer = &fill_input_buffer; 7941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_->skip_input_data = &skip_input_data; 8041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_->resync_to_restart = &jpeg_resync_to_restart; 8141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org source_mgr_->term_source = &term_source; 8241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_create_decompress(decompress_struct_); 8341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->src = source_mgr_; 8441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org buf_vec_.buffers = &buf_; 8541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org buf_vec_.len = 1; 8641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 8741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 8841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgMJpegDecoder::~MJpegDecoder() { 8941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_destroy_decompress(decompress_struct_); 9041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete decompress_struct_; 9141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete source_mgr_; 9241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 9341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete error_mgr_; 9441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 9541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org DestroyOutputBuffers(); 9641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 9741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 9841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) { 9941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!ValidateJpeg(src, src_len)) { 10041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 10141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 10241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 10341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org buf_.data = src; 104d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org buf_.len = static_cast<int>(src_len); 10541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org buf_vec_.pos = 0; 10641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->client_data = &buf_vec_; 10741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 10841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (setjmp(error_mgr_->setjmp_buffer)) { 10941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We called jpeg_read_header, it experienced an error, and we called 11041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // longjmp() and rewound the stack to here. Return error. 11141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 11241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 11341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 11441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (jpeg_read_header(decompress_struct_, TRUE) != JPEG_HEADER_OK) { 11541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: Bad MJPEG header 11641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 11741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 11841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org AllocOutputBuffers(GetNumComponents()); 11941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 12041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int scanlines_size = GetComponentScanlinesPerImcuRow(i); 12141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (scanlines_sizes_[i] != scanlines_size) { 12241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (scanlines_[i]) { 12341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete scanlines_[i]; 12441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 12541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_[i] = new uint8* [scanlines_size]; 12641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_sizes_[i] = scanlines_size; 12741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 12841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 12941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We allocate padding for the final scanline to pad it up to DCTSIZE bytes 13041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // to avoid memory errors, since jpeglib only reads full MCUs blocks. For 13141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // the preceding scanlines, the padding is not needed/wanted because the 13241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // following addresses will already be valid (they are the initial bytes of 13341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // the next scanline) and will be overwritten when jpeglib writes out that 13441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // next scanline. 13541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int databuf_stride = GetComponentStride(i); 13641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int databuf_size = scanlines_size * databuf_stride; 13741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (databuf_strides_[i] != databuf_stride) { 13841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (databuf_[i]) { 13941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete databuf_[i]; 14041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 14141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_[i] = new uint8[databuf_size]; 14241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_strides_[i] = databuf_stride; 14341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 14441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 14541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (GetComponentStride(i) != GetComponentWidth(i)) { 14641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org has_scanline_padding_ = LIBYUV_TRUE; 14741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 14841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 14941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_TRUE; 15041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 15141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 15241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic int DivideAndRoundUp(int numerator, int denominator) { 15341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return (numerator + denominator - 1) / denominator; 15441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 15541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 15641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic int DivideAndRoundDown(int numerator, int denominator) { 15741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return numerator / denominator; 15841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 15941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 16041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Returns width of the last loaded frame. 16141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetWidth() { 16241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->image_width; 16341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 16441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 16541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Returns height of the last loaded frame. 16641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetHeight() { 16741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->image_height; 16841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 16941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 17041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Returns format of the last loaded frame. The return value is one of the 17141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// kColorSpace* constants. 17241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetColorSpace() { 17341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->jpeg_color_space; 17441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 17541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 17641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Number of color components in the color space. 17741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetNumComponents() { 17841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->num_components; 17941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 18041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 18141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Sample factors of the n-th component. 18241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetHorizSampFactor(int component) { 18341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->comp_info[component].h_samp_factor; 18441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 18541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 18641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetVertSampFactor(int component) { 18741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->comp_info[component].v_samp_factor; 18841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 18941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 19041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetHorizSubSampFactor(int component) { 19141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->max_h_samp_factor / 19241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetHorizSampFactor(component); 19341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 19441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 19541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetVertSubSampFactor(int component) { 19641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->max_v_samp_factor / 19741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetVertSampFactor(component); 19841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 19941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 20041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetImageScanlinesPerImcuRow() { 20141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return decompress_struct_->max_v_samp_factor * DCTSIZE; 20241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 20341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 20441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetComponentScanlinesPerImcuRow(int component) { 20541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int vs = GetVertSubSampFactor(component); 20641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return DivideAndRoundUp(GetImageScanlinesPerImcuRow(), vs); 20741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 20841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 20941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetComponentWidth(int component) { 21041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int hs = GetHorizSubSampFactor(component); 21141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return DivideAndRoundUp(GetWidth(), hs); 21241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 21341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 21441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetComponentHeight(int component) { 21541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int vs = GetVertSubSampFactor(component); 21641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return DivideAndRoundUp(GetHeight(), vs); 21741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 21841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 21941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Get width in bytes padded out to a multiple of DCTSIZE 22041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetComponentStride(int component) { 22141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return (GetComponentWidth(component) + DCTSIZE - 1) & ~(DCTSIZE - 1); 22241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 22341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 22441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint MJpegDecoder::GetComponentSize(int component) { 22541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return GetComponentWidth(component) * GetComponentHeight(component); 22641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 22741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 22841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::UnloadFrame() { 22941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 23041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (setjmp(error_mgr_->setjmp_buffer)) { 23141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We called jpeg_abort_decompress, it experienced an error, and we called 23241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // longjmp() and rewound the stack to here. Return error. 23341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 23441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 23541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 23641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_abort_decompress(decompress_struct_); 23741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_TRUE; 23841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 23941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 24041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// TODO(fbarchard): Allow rectangle to be specified: x, y, width, height. 24141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::DecodeToBuffers( 24241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint8** planes, int dst_width, int dst_height) { 24341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (dst_width != GetWidth() || 24441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org dst_height > GetHeight()) { 24541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: Bad dimensions 24641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 24741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 24841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 24941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (setjmp(error_mgr_->setjmp_buffer)) { 25041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We called into jpeglib, it experienced an error sometime during this 25141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // function call, and we called longjmp() and rewound the stack to here. 25241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Return error. 25341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 25441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 25541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 25641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!StartDecode()) { 25741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 25841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 25941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org SetScanlinePointers(databuf_); 26041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int lines_left = dst_height; 26141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Compute amount of lines to skip to implement vertical crop. 26241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // TODO(fbarchard): Ensure skip is a multiple of maximum component 26341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // subsample. ie 2 26441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int skip = (GetHeight() - dst_height) / 2; 26541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (skip > 0) { 26641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // There is no API to skip lines in the output data, so we read them 26741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // into the temp buffer. 26841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org while (skip >= GetImageScanlinesPerImcuRow()) { 26941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 27041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 27141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 27241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 27341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org skip -= GetImageScanlinesPerImcuRow(); 27441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 27541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (skip > 0) { 27641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Have a partial iMCU row left over to skip. Must read it and then 27741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // copy the parts we want into the destination. 27841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 27941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 28041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 28141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 28241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 28341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // TODO(fbarchard): Compute skip to avoid this 28441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org assert(skip % GetVertSubSampFactor(i) == 0); 28541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int rows_to_skip = 28641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org DivideAndRoundDown(skip, GetVertSubSampFactor(i)); 28741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int scanlines_to_copy = GetComponentScanlinesPerImcuRow(i) - 28841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org rows_to_skip; 28941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int data_to_skip = rows_to_skip * GetComponentStride(i); 29041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org CopyPlane(databuf_[i] + data_to_skip, GetComponentStride(i), 29141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i], GetComponentWidth(i), 29241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetComponentWidth(i), scanlines_to_copy); 29341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i] += scanlines_to_copy * GetComponentWidth(i); 29441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 29541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lines_left -= (GetImageScanlinesPerImcuRow() - skip); 29641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 29741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 29841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 29941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Read full MCUs but cropped horizontally 30041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (; lines_left > GetImageScanlinesPerImcuRow(); 30141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lines_left -= GetImageScanlinesPerImcuRow()) { 30241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 30341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 30441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 30541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 30641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 30741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int scanlines_to_copy = GetComponentScanlinesPerImcuRow(i); 30841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org CopyPlane(databuf_[i], GetComponentStride(i), 30941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i], GetComponentWidth(i), 31041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetComponentWidth(i), scanlines_to_copy); 31141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i] += scanlines_to_copy * GetComponentWidth(i); 31241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 31341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 31441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 31541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (lines_left > 0) { 31641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Have a partial iMCU row left over to decode. 31741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 31841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 31941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 32041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 32141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 32241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int scanlines_to_copy = 32341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org DivideAndRoundUp(lines_left, GetVertSubSampFactor(i)); 32441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org CopyPlane(databuf_[i], GetComponentStride(i), 32541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i], GetComponentWidth(i), 32641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetComponentWidth(i), scanlines_to_copy); 32741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org planes[i] += scanlines_to_copy * GetComponentWidth(i); 32841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 32941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 33041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return FinishDecode(); 33141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 33241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 33341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::DecodeToCallback(CallbackFunction fn, void* opaque, 33441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int dst_width, int dst_height) { 33541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (dst_width != GetWidth() || 33641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org dst_height > GetHeight()) { 33741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: Bad dimensions 33841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 33941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 34041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 34141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (setjmp(error_mgr_->setjmp_buffer)) { 34241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We called into jpeglib, it experienced an error sometime during this 34341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // function call, and we called longjmp() and rewound the stack to here. 34441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Return error. 34541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 34641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 34741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 34841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!StartDecode()) { 34941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 35041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 35141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org SetScanlinePointers(databuf_); 35241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int lines_left = dst_height; 35341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // TODO(fbarchard): Compute amount of lines to skip to implement vertical crop 35441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int skip = (GetHeight() - dst_height) / 2; 35541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (skip > 0) { 35641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org while (skip >= GetImageScanlinesPerImcuRow()) { 35741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 35841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 35941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 36041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 36141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org skip -= GetImageScanlinesPerImcuRow(); 36241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 36341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (skip > 0) { 36441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Have a partial iMCU row left over to skip. 36541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 36641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 36741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 36841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 36941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 37041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // TODO(fbarchard): Compute skip to avoid this 37141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org assert(skip % GetVertSubSampFactor(i) == 0); 37241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i)); 37341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int data_to_skip = rows_to_skip * GetComponentStride(i); 37441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Change our own data buffer pointers so we can pass them to the 37541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // callback. 37641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_[i] += data_to_skip; 37741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 37841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int scanlines_to_copy = GetImageScanlinesPerImcuRow() - skip; 37941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (*fn)(opaque, databuf_, databuf_strides_, scanlines_to_copy); 38041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Now change them back. 38141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 38241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int rows_to_skip = DivideAndRoundDown(skip, GetVertSubSampFactor(i)); 38341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int data_to_skip = rows_to_skip * GetComponentStride(i); 38441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_[i] -= data_to_skip; 38541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 38641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lines_left -= scanlines_to_copy; 38741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 38841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 38941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Read full MCUs until we get to the crop point. 39041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (; lines_left >= GetImageScanlinesPerImcuRow(); 39141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lines_left -= GetImageScanlinesPerImcuRow()) { 39241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 39341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 39441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 39541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 39641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (*fn)(opaque, databuf_, databuf_strides_, GetImageScanlinesPerImcuRow()); 39741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 39841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (lines_left > 0) { 39941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Have a partial iMCU row left over to decode. 40041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!DecodeImcuRow()) { 40141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org FinishDecode(); 40241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 40341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 40441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (*fn)(opaque, databuf_, databuf_strides_, lines_left); 40541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 40641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return FinishDecode(); 40741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 40841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 40941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid init_source(j_decompress_ptr cinfo) { 41041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org fill_input_buffer(cinfo); 41141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 41241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 41341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgboolean fill_input_buffer(j_decompress_ptr cinfo) { 414d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org BufferVector* buf_vec = reinterpret_cast<BufferVector*>(cinfo->client_data); 41541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (buf_vec->pos >= buf_vec->len) { 41641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org assert(0 && "No more data"); 41741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: No more data 41841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return FALSE; 41941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 42041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org cinfo->src->next_input_byte = buf_vec->buffers[buf_vec->pos].data; 42141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org cinfo->src->bytes_in_buffer = buf_vec->buffers[buf_vec->pos].len; 42241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org ++buf_vec->pos; 42341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return TRUE; 42441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 42541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 42641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid skip_input_data(j_decompress_ptr cinfo, 42741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org long num_bytes) { // NOLINT 42841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org cinfo->src->next_input_byte += num_bytes; 42941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 43041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 43141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid term_source(j_decompress_ptr cinfo) { 43241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Nothing to do. 43341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 43441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 43541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_SETJMP 43641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid ErrorHandler(j_common_ptr cinfo) { 43741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // This is called when a jpeglib command experiences an error. Unfortunately 43841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // jpeglib's error handling model is not very flexible, because it expects the 43941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // error handler to not return--i.e., it wants the program to terminate. To 44041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // recover from errors we use setjmp() as shown in their example. setjmp() is 44141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // C's implementation for the "call with current continuation" functionality 44241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // seen in some functional programming languages. 44341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // A formatted message can be output, but is unsafe for release. 44441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef DEBUG 44541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org char buf[JMSG_LENGTH_MAX]; 44641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (*cinfo->err->format_message)(cinfo, buf); 44741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: Error in jpeglib: buf 44841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 44941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 450d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org SetJmpErrorMgr* mgr = reinterpret_cast<SetJmpErrorMgr*>(cinfo->err); 45141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // This rewinds the call stack to the point of the corresponding setjmp() 45241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // and causes it to return (for a second time) with value 1. 45341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org longjmp(mgr->setjmp_buffer, 1); 45441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 45541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 45641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 45741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid MJpegDecoder::AllocOutputBuffers(int num_outbufs) { 45841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (num_outbufs != num_outbufs_) { 45941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // We could perhaps optimize this case to resize the output buffers without 46041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // necessarily having to delete and recreate each one, but it's not worth 46141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // it. 46241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org DestroyOutputBuffers(); 46341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 46441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_ = new uint8** [num_outbufs]; 46541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_sizes_ = new int[num_outbufs]; 46641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_ = new uint8* [num_outbufs]; 46741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_strides_ = new int[num_outbufs]; 46841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 46941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs; ++i) { 47041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_[i] = NULL; 47141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_sizes_[i] = 0; 47241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_[i] = NULL; 47341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_strides_[i] = 0; 47441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 47541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 47641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org num_outbufs_ = num_outbufs; 47741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 47841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 47941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 48041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid MJpegDecoder::DestroyOutputBuffers() { 48141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 48241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] scanlines_[i]; 48341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] databuf_[i]; 48441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 48541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] scanlines_; 48641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] databuf_; 48741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] scanlines_sizes_; 48841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org delete [] databuf_strides_; 48941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_ = NULL; 49041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_ = NULL; 49141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_sizes_ = NULL; 49241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org databuf_strides_ = NULL; 49341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org num_outbufs_ = 0; 49441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 49541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 49641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// JDCT_IFAST and do_block_smoothing improve performance substantially. 49741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::StartDecode() { 49841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->raw_data_out = TRUE; 49941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->dct_method = JDCT_IFAST; // JDCT_ISLOW is default 50041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->dither_mode = JDITHER_NONE; 50141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Not applicable to 'raw': 50241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->do_fancy_upsampling = (boolean)(LIBYUV_FALSE); 50341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Only for buffered mode: 50441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->enable_2pass_quant = (boolean)(LIBYUV_FALSE); 50541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Blocky but fast: 50641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org decompress_struct_->do_block_smoothing = (boolean)(LIBYUV_FALSE); 50741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 50841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!jpeg_start_decompress(decompress_struct_)) { 50941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // ERROR: Couldn't start JPEG decompressor"; 51041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_FALSE; 51141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 51241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_TRUE; 51341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 51441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 51541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_BOOL MJpegDecoder::FinishDecode() { 51641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // jpeglib considers it an error if we finish without decoding the whole 51741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // image, so we call "abort" rather than "finish". 51841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_abort_decompress(decompress_struct_); 51941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return LIBYUV_TRUE; 52041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 52141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 52241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid MJpegDecoder::SetScanlinePointers(uint8** data) { 52341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int i = 0; i < num_outbufs_; ++i) { 52441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint8* data_i = data[i]; 52541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org for (int j = 0; j < scanlines_sizes_[i]; ++j) { 52641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_[i][j] = data_i; 52741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org data_i += GetComponentStride(i); 52841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 52941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 53041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 53141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 53241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orginline LIBYUV_BOOL MJpegDecoder::DecodeImcuRow() { 53341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return (unsigned int)(GetImageScanlinesPerImcuRow()) == 53441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org jpeg_read_raw_data(decompress_struct_, 53541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org scanlines_, 53641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org GetImageScanlinesPerImcuRow()); 53741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 53841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 53941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// The helper function which recognizes the jpeg sub-sampling type. 54041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgJpegSubsamplingType MJpegDecoder::JpegSubsamplingTypeHelper( 54141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int* subsample_x, int* subsample_y, int number_of_components) { 54241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (number_of_components == 3) { // Color images. 54341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (subsample_x[0] == 1 && subsample_y[0] == 1 && 54441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[1] == 2 && subsample_y[1] == 2 && 54541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[2] == 2 && subsample_y[2] == 2) { 54641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return kJpegYuv420; 54741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else if (subsample_x[0] == 1 && subsample_y[0] == 1 && 54841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[1] == 2 && subsample_y[1] == 1 && 54941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[2] == 2 && subsample_y[2] == 1) { 55041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return kJpegYuv422; 55141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else if (subsample_x[0] == 1 && subsample_y[0] == 1 && 55241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[1] == 1 && subsample_y[1] == 1 && 55341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org subsample_x[2] == 1 && subsample_y[2] == 1) { 55441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return kJpegYuv444; 55541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 55641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else if (number_of_components == 1) { // Grey-scale images. 55741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (subsample_x[0] == 1 && subsample_y[0] == 1) { 55841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return kJpegYuv400; 55941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 56041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 56141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return kJpegUnknown; 56241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 56341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 56441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} // namespace libyuv 56541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif // HAVE_JPEG 56641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 567