141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org/* 241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org * Copyright 2011 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/convert_argb.h" 1241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 1341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/cpu_id.h" 1441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/format_conversion.h" 1541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_JPEG 1641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/mjpeg_decoder.h" 1741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 1841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/rotate_argb.h" 1941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/row.h" 2041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/video_common.h" 2141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 2241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus 2341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgnamespace libyuv { 2441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgextern "C" { 2541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 2641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 2741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Convert camera sample to I420 with cropping, rotation and vertical flip. 2841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src_width is used for source stride computation 2941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src_height is used to compute location of planes, and indicate inversion 3041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// sample_size is measured in bytes and is the size of the frame. 3141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// With MJPEG it is the compressed size of the frame. 3241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API 3341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint ConvertToARGB(const uint8* sample, size_t sample_size, 3441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint8* crop_argb, int argb_stride, 3541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int crop_x, int crop_y, 3641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int src_width, int src_height, 3741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int crop_width, int crop_height, 3841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org enum RotationMode rotation, 3941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint32 fourcc) { 4041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint32 format = CanonicalFourCC(fourcc); 4141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int aligned_src_width = (src_width + 1) & ~1; 4241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src; 4341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_uv; 4441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int abs_src_height = (src_height < 0) ? -src_height : src_height; 4541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; 4641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int r = 0; 4741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 4841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // One pass rotation is available for some formats. For the rest, convert 4941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // to I420 (with optional vertical flipping) into a temporary I420 buffer, 5041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // and then rotate the I420 to the final destination buffer. 5141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // For in-place conversion, if destination crop_argb is same as source sample, 5241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // also enable temporary buffer. 5341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org LIBYUV_BOOL need_buf = (rotation && format != FOURCC_ARGB) || 5441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb == sample; 5541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint8* tmp_argb = crop_argb; 5641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int tmp_argb_stride = argb_stride; 5741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org uint8* rotate_buffer = NULL; 5841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; 5941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 6041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (crop_argb == NULL || sample == NULL || 6141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_width <= 0 || crop_width <= 0 || 6241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_height == 0 || crop_height == 0) { 6341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return -1; 6441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 6541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (src_height < 0) { 6641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org inv_crop_height = -inv_crop_height; 6741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 6841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 6941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (need_buf) { 7041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int argb_size = crop_width * abs_crop_height * 4; 7141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org rotate_buffer = (uint8*)malloc(argb_size); 7241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!rotate_buffer) { 7341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return 1; // Out of memory runtime error. 7441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 7541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb = rotate_buffer; 7641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org argb_stride = crop_width; 7741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 7841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 7941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org switch (format) { 8041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Single plane formats 8141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_YUY2: 8241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (aligned_src_width * crop_y + crop_x) * 2; 8341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = YUY2ToARGB(src, aligned_src_width * 2, 8441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 8541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 8641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 8741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_UYVY: 8841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (aligned_src_width * crop_y + crop_x) * 2; 8941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = UYVYToARGB(src, aligned_src_width * 2, 9041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 9141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 9241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 9341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_24BG: 9441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 3; 9541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = RGB24ToARGB(src, src_width * 3, 9641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 9741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 9841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 9941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_RAW: 10041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 3; 10141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = RAWToARGB(src, src_width * 3, 10241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 10341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 10441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 10541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_ARGB: 10641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 4; 10741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = ARGBToARGB(src, src_width * 4, 10841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 10941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 11041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 11141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_BGRA: 11241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 4; 11341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = BGRAToARGB(src, src_width * 4, 11441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 11541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 11641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 11741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_ABGR: 11841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 4; 11941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = ABGRToARGB(src, src_width * 4, 12041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 12141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 12241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 12341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_RGBA: 12441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 4; 12541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = RGBAToARGB(src, src_width * 4, 12641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 12741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 12841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 12941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_RGBP: 13041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 2; 13141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = RGB565ToARGB(src, src_width * 2, 13241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 13341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 13441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 13541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_RGBO: 13641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 2; 13741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = ARGB1555ToARGB(src, src_width * 2, 13841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 13941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 14041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 14141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_R444: 14241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x) * 2; 14341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = ARGB4444ToARGB(src, src_width * 2, 14441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 14541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 14641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 14741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // TODO(fbarchard): Support cropping Bayer by odd numbers 14841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // by adjusting fourcc. 14941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_BGGR: 15041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 15141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = BayerBGGRToARGB(src, src_width, 15241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 15341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 15441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 15541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 15641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_GBRG: 15741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 15841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = BayerGBRGToARGB(src, src_width, 15941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 16041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 16141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 16241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 16341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_GRBG: 16441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 16541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = BayerGRBGToARGB(src, src_width, 16641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 16741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 16841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 16941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 17041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_RGGB: 17141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 17241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = BayerRGGBToARGB(src, src_width, 17341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 17441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 17541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 17641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 17741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_I400: 17841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + src_width * crop_y + crop_x; 17941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = I400ToARGB(src, src_width, 18041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 18141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 18241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 18341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 18441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Biplanar formats 18541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_NV12: 18641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 18741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 18841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = NV12ToARGB(src, src_width, 18941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_uv, aligned_src_width, 19041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 19141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 19241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 19341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_NV21: 19441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y + crop_x); 19541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 19641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Call NV12 but with u and v parameters swapped. 19741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = NV21ToARGB(src, src_width, 19841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_uv, aligned_src_width, 19941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 20041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 20141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 20241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_M420: 20341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src = sample + (src_width * crop_y) * 12 / 8 + crop_x; 20441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = M420ToARGB(src, src_width, 20541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 20641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 20741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 20841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// case FOURCC_Q420: 20941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src = sample + (src_width + aligned_src_width * 2) * crop_y + crop_x; 21041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src_uv = sample + (src_width + aligned_src_width * 2) * crop_y + 21141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src_width + crop_x * 2; 21241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// r = Q420ToARGB(src, src_width * 3, 21341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// src_uv, src_width * 3, 21441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// crop_argb, argb_stride, 21541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// crop_width, inv_crop_height); 21641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// break; 21741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Triplanar formats 21841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_I420: 21941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_YU12: 22041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_YV12: { 22141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_y = sample + (src_width * crop_y + crop_x); 22241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_u; 22341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_v; 22441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int halfwidth = (src_width + 1) / 2; 22541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int halfheight = (abs_src_height + 1) / 2; 22641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (format == FOURCC_YV12) { 22741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * abs_src_height + 22841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (halfwidth * crop_y + crop_x) / 2; 22941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * abs_src_height + 23041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 23141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else { 23241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * abs_src_height + 23341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org (halfwidth * crop_y + crop_x) / 2; 23441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * abs_src_height + 23541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 23641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 23741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = I420ToARGB(src_y, src_width, 23841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u, halfwidth, 23941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v, halfwidth, 24041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 24141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 24241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 24341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 24441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_I422: 24541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_YV16: { 24641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_y = sample + src_width * crop_y + crop_x; 24741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_u; 24841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_v; 24941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int halfwidth = (src_width + 1) / 2; 25041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (format == FOURCC_YV16) { 25141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * abs_src_height + 25241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * crop_y + crop_x / 2; 25341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * abs_src_height + 25441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * (abs_src_height + crop_y) + crop_x / 2; 25541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else { 25641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * abs_src_height + 25741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * crop_y + crop_x / 2; 25841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * abs_src_height + 25941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org halfwidth * (abs_src_height + crop_y) + crop_x / 2; 26041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 26141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = I422ToARGB(src_y, src_width, 26241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u, halfwidth, 26341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v, halfwidth, 26441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 26541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 26641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 26741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 26841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_I444: 26941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_YV24: { 27041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_y = sample + src_width * crop_y + crop_x; 27141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_u; 27241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_v; 27341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (format == FOURCC_YV24) { 27441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; 27541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 27641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else { 27741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; 27841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 27941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 28041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = I444ToARGB(src_y, src_width, 28141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u, src_width, 28241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v, src_width, 28341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 28441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 28541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 28641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 28741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_I411: { 28841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int quarterwidth = (src_width + 3) / 4; 28941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_y = sample + src_width * crop_y + crop_x; 29041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_u = sample + src_width * abs_src_height + 29141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org quarterwidth * crop_y + crop_x / 4; 29241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const uint8* src_v = sample + src_width * abs_src_height + 29341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org quarterwidth * (abs_src_height + crop_y) + crop_x / 4; 29441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = I411ToARGB(src_y, src_width, 29541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_u, quarterwidth, 29641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_v, quarterwidth, 29741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 29841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, inv_crop_height); 29941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 30041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 30141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef HAVE_JPEG 30241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org case FOURCC_MJPG: 30341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = MJPGToARGB(sample, sample_size, 30441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_argb, argb_stride, 30541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org src_width, abs_src_height, crop_width, inv_crop_height); 30641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org break; 30741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 30841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org default: 30941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = -1; // unknown fourcc - return failure code. 31041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 31141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 31241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (need_buf) { 31341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (!r) { 31441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org r = ARGBRotate(crop_argb, argb_stride, 31541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org tmp_argb, tmp_argb_stride, 31641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org crop_width, abs_crop_height, rotation); 31741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 31841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org free(rotate_buffer); 31941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 32041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 32141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org return r; 32241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} 32341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 32441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus 32541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} // extern "C" 32641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org} // namespace libyuv 32741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif 328