1ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian/* 2ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * 4ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * Use of this source code is governed by a BSD-style license 5ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * that can be found in the LICENSE file in the root of the source 6ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * tree. An additional intellectual property rights grant can be found 7ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * in the file PATENTS. All contributing project authors may 8ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian * be found in the AUTHORS file in the root of the source tree. 9ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian */ 10ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 11ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/convert_argb.h" 12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/cpu_id.h" 14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef HAVE_JPEG 15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/mjpeg_decoder.h" 16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/rotate_argb.h" 18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h" 19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/video_common.h" 20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv { 23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" { 24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 267bc9febe8749e98a3812a0dc4380ceae75c29450Johann// Convert camera sample to ARGB with cropping, rotation and vertical flip. 27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// src_width is used for source stride computation 28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// src_height is used to compute location of planes, and indicate inversion 29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// sample_size is measured in bytes and is the size of the frame. 30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// With MJPEG it is the compressed size of the frame. 31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ConvertToARGB(const uint8* sample, size_t sample_size, 33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* crop_argb, int argb_stride, 34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int crop_x, int crop_y, 35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int src_width, int src_height, 36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int crop_width, int crop_height, 37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian enum RotationMode rotation, 38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint32 fourcc) { 39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint32 format = CanonicalFourCC(fourcc); 40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int aligned_src_width = (src_width + 1) & ~1; 41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src; 42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_uv; 43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int abs_src_height = (src_height < 0) ? -src_height : src_height; 44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; 45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int r = 0; 46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // One pass rotation is available for some formats. For the rest, convert 48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // to I420 (with optional vertical flipping) into a temporary I420 buffer, 49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // and then rotate the I420 to the final destination buffer. 50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // For in-place conversion, if destination crop_argb is same as source sample, 51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // also enable temporary buffer. 52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian LIBYUV_BOOL need_buf = (rotation && format != FOURCC_ARGB) || 53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb == sample; 547bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint8* dest_argb = crop_argb; 557bc9febe8749e98a3812a0dc4380ceae75c29450Johann int dest_argb_stride = argb_stride; 56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rotate_buffer = NULL; 57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; 58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (crop_argb == NULL || sample == NULL || 60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_width <= 0 || crop_width <= 0 || 61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_height == 0 || crop_height == 0) { 62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_height < 0) { 65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian inv_crop_height = -inv_crop_height; 66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (need_buf) { 697bc9febe8749e98a3812a0dc4380ceae75c29450Johann int argb_size = crop_width * 4 * abs_crop_height; 70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian rotate_buffer = (uint8*)malloc(argb_size); 71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!rotate_buffer) { 72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 1; // Out of memory runtime error. 73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb = rotate_buffer; 757bc9febe8749e98a3812a0dc4380ceae75c29450Johann argb_stride = crop_width * 4; 76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian switch (format) { 79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Single plane formats 80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_YUY2: 81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (aligned_src_width * crop_y + crop_x) * 2; 82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = YUY2ToARGB(src, aligned_src_width * 2, 83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_UYVY: 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (aligned_src_width * crop_y + crop_x) * 2; 88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = UYVYToARGB(src, aligned_src_width * 2, 89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_24BG: 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 3; 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = RGB24ToARGB(src, src_width * 3, 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_RAW: 99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 3; 100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = RAWToARGB(src, src_width * 3, 101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_ARGB: 105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 4; 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = ARGBToARGB(src, src_width * 4, 107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_BGRA: 111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 4; 112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = BGRAToARGB(src, src_width * 4, 113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_ABGR: 117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 4; 118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = ABGRToARGB(src, src_width * 4, 119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_RGBA: 123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 4; 124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = RGBAToARGB(src, src_width * 4, 125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_RGBP: 129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 2; 130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = RGB565ToARGB(src, src_width * 2, 131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_RGBO: 135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 2; 136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = ARGB1555ToARGB(src, src_width * 2, 137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_R444: 141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x) * 2; 142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = ARGB4444ToARGB(src, src_width * 2, 143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_I400: 147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + src_width * crop_y + crop_x; 148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = I400ToARGB(src, src_width, 149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Biplanar formats 154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_NV12: 155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x); 156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = NV12ToARGB(src, src_width, 158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv, aligned_src_width, 159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_NV21: 163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y + crop_x); 164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Call NV12 but with u and v parameters swapped. 166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = NV21ToARGB(src, src_width, 167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv, aligned_src_width, 168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_M420: 172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src = sample + (src_width * crop_y) * 12 / 8 + crop_x; 173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = M420ToARGB(src, src_width, 174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Triplanar formats 178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_I420: 179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_YV12: { 180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y = sample + (src_width * crop_y + crop_x); 181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u; 182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v; 183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (src_width + 1) / 2; 184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (abs_src_height + 1) / 2; 185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (format == FOURCC_YV12) { 186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * abs_src_height + 187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (halfwidth * crop_y + crop_x) / 2; 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * abs_src_height + 189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * abs_src_height + 192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian (halfwidth * crop_y + crop_x) / 2; 193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * abs_src_height + 194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = I420ToARGB(src_y, src_width, 197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, halfwidth, 198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, halfwidth, 199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 203da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 204da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian case FOURCC_J420: { 205da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian const uint8* src_y = sample + (src_width * crop_y + crop_x); 206da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian const uint8* src_u; 207da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian const uint8* src_v; 208da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int halfwidth = (src_width + 1) / 2; 209da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int halfheight = (abs_src_height + 1) / 2; 210da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_u = sample + src_width * abs_src_height + 211da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian (halfwidth * crop_y + crop_x) / 2; 212da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_v = sample + src_width * abs_src_height + 213da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 214da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian r = J420ToARGB(src_y, src_width, 215da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_u, halfwidth, 216da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_v, halfwidth, 217da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian crop_argb, argb_stride, 218da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian crop_width, inv_crop_height); 219da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian break; 220da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 221da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_I422: 223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_YV16: { 224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y = sample + src_width * crop_y + crop_x; 225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u; 226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v; 227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (src_width + 1) / 2; 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (format == FOURCC_YV16) { 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * abs_src_height + 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * crop_y + crop_x / 2; 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * abs_src_height + 232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * (abs_src_height + crop_y) + crop_x / 2; 233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * abs_src_height + 235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * crop_y + crop_x / 2; 236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * abs_src_height + 237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfwidth * (abs_src_height + crop_y) + crop_x / 2; 238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = I422ToARGB(src_y, src_width, 240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, halfwidth, 241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, halfwidth, 242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_I444: 247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_YV24: { 248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y = sample + src_width * crop_y + crop_x; 249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u; 250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v; 251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (format == FOURCC_YV24) { 252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; 253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } else { 255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; 256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = I444ToARGB(src_y, src_width, 259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, src_width, 260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, src_width, 261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_I411: { 266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int quarterwidth = (src_width + 3) / 4; 267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y = sample + src_width * crop_y + crop_x; 268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u = sample + src_width * abs_src_height + 269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian quarterwidth * crop_y + crop_x / 4; 270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v = sample + src_width * abs_src_height + 271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian quarterwidth * (abs_src_height + crop_y) + crop_x / 4; 272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = I411ToARGB(src_y, src_width, 273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u, quarterwidth, 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v, quarterwidth, 275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, inv_crop_height); 277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef HAVE_JPEG 280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian case FOURCC_MJPG: 281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = MJPGToARGB(sample, sample_size, 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_argb, argb_stride, 283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_width, abs_src_height, crop_width, inv_crop_height); 284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian break; 285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian default: 287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = -1; // unknown fourcc - return failure code. 288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (need_buf) { 291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!r) { 292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian r = ARGBRotate(crop_argb, argb_stride, 2937bc9febe8749e98a3812a0dc4380ceae75c29450Johann dest_argb, dest_argb_stride, 294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian crop_width, abs_crop_height, rotation); 295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free(rotate_buffer); 297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return r; 300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // extern "C" 304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // namespace libyuv 305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 306