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/planar_functions.h" 12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include <string.h> // for memset() 14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/cpu_id.h" 16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef HAVE_JPEG 17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/mjpeg_decoder.h" 18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 19ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "libyuv/row.h" 20ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 21ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace libyuv { 23ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianextern "C" { 24ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy a plane of data 27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid CopyPlane(const uint8* src_y, int src_stride_y, 29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y == width) { 36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = dst_stride_y = 0; 39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Nothing to do. 41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_y == dst_y && src_stride_y == dst_stride_y) { 42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return; 43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 44da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_COPYROW_SSE2) 45da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 46da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2; 47ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 49da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_COPYROW_AVX) 50da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX)) { 51da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX; 52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_ERMS) 55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasERMS)) { 56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_ERMS; 57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_NEON) 60da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 61da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON; 62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_MIPS) 65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS)) { 66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_MIPS; 67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Copy plane 71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src_y, dst_y, width); 73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid CopyPlane_16(const uint16* src_y, int src_stride_y, 80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint16* dst_y, int dst_stride_y, 81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*CopyRow)(const uint16* src, uint16* dst, int width) = CopyRow_16_C; 84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y == width) { 87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = dst_stride_y = 0; 90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_16_SSE2) 92da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32)) { 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_16_SSE2; 94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_16_ERMS) 97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasERMS)) { 98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_16_ERMS; 99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_16_NEON) 102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_16_NEON; 104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_COPYROW_16_MIPS) 107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS)) { 108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow = CopyRow_16_MIPS; 109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Copy plane 113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyRow(src_y, dst_y, width); 115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy I422. 121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I422Copy(const uint8* src_y, int src_stride_y, 123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 134ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 135ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 136ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 137ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = src_u + (height - 1) * src_stride_u; 140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = src_v + (height - 1) * src_stride_v; 141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u = -src_stride_u; 143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v = -src_stride_v; 144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height); 147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height); 148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy I444. 152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I444Copy(const uint8* src_y, int src_stride_y, 154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_y || !dst_u || !dst_v || 162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = src_u + (height - 1) * src_stride_u; 170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = src_v + (height - 1) * src_stride_v; 171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u = -src_stride_u; 173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v = -src_stride_v; 174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height); 178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height); 179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy I400. 183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I400ToI400(const uint8* src_y, int src_stride_y, 185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !dst_y || width <= 0 || height == 0) { 188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert I420 to I400. 201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I420ToI400(const uint8* src_y, int src_stride_y, 203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !dst_y || width <= 0 || height == 0) { 208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Mirror a plane of data. 221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MirrorPlane(const uint8* src_y, int src_stride_y, 222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; 226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_MIRRORROW_NEON) 233da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 234da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_Any_NEON; 235da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 236da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_NEON; 237da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_MIRRORROW_SSE2) 241da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 242da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_Any_SSE2; 243da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 244da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_SSE2; 245da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_MIRRORROW_SSSE3) 249da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 250da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_Any_SSSE3; 251da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 252da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_SSSE3; 253da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_MIRRORROW_AVX2) 257da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 258da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_Any_AVX2; 259da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 260da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_AVX2; 261da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 262da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 263da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 264da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// TODO(fbarchard): Mirror on mips handle unaligned memory. 265da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_MIRRORROW_MIPS_DSPR2) 266da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && 267da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && 268da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian IS_ALIGNED(dst_y, 4) && IS_ALIGNED(dst_stride_y, 4)) { 269da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian MirrorRow = MirrorRow_MIPS_DSPR2; 270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Mirror plane 274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MirrorRow(src_y, dst_y, width); 276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert YUY2 to I422. 282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint YUY2ToI422(const uint8* src_yuy2, int src_stride_yuy2, 284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToUV422Row)(const uint8* src_yuy2, 290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int pix) = 291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row_C; 292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = 293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow_C; 294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_yuy2 = -src_stride_yuy2; 299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_yuy2 == width * 2 && 302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y == width && 303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_u * 2 == width && 304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_v * 2 == width) { 305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_yuy2 = dst_stride_y = dst_stride_u = dst_stride_v = 0; 308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_SSE2) 310da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_SSE2; 312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_SSE2; 313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 314da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_SSE2; 315da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_SSE2; 316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_AVX2) 320da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_AVX2; 322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_AVX2; 323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_AVX2; 325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_AVX2; 326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_YUY2TOYROW_NEON) 330da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_Any_NEON; 332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_Any_NEON; 334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow = YUY2ToYRow_NEON; 337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row = YUY2ToUV422Row_NEON; 338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian YUY2ToYRow(src_yuy2, dst_y, width); 345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_yuy2 += src_stride_yuy2; 346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert UYVY to I422. 354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint UYVYToI422(const uint8* src_uyvy, int src_stride_uyvy, 356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*UYVYToUV422Row)(const uint8* src_uyvy, 362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, uint8* dst_v, int pix) = 363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row_C; 364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*UYVYToYRow)(const uint8* src_uyvy, 365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int pix) = UYVYToYRow_C; 366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_uyvy = -src_stride_uyvy; 371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_uyvy == width * 2 && 374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y == width && 375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_u * 2 == width && 376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_v * 2 == width) { 377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 379ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_uyvy = dst_stride_y = dst_stride_u = dst_stride_v = 0; 380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_SSE2) 382da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 383ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_Any_SSE2; 384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_SSE2; 385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 386da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_SSE2; 387da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_SSE2; 388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_AVX2) 392da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_Any_AVX2; 394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_AVX2; 395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_AVX2; 397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_AVX2; 398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_UYVYTOYROW_NEON) 402da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_Any_NEON; 404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (width >= 16) { 405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_Any_NEON; 406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow = UYVYToYRow_NEON; 409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row = UYVYToUV422Row_NEON; 410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToUV422Row(src_uyvy, dst_u, dst_v, width); 416ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian UYVYToYRow(src_uyvy, dst_y, width); 417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uyvy += src_stride_uyvy; 418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 419ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_u += dst_stride_u; 420ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_v += dst_stride_v; 421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Mirror I400 with optional flipping 426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I400Mirror(const uint8* src_y, int src_stride_y, 428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !dst_y || 431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Mirror I420 with optional flipping 446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I420Mirror(const uint8* src_y, int src_stride_y, 448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 449ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 452ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 453ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || !dst_y || !dst_u || !dst_v || 457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian halfheight = (height + 1) >> 1; 464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u = src_u + (halfheight - 1) * src_stride_u; 466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v = src_v + (halfheight - 1) * src_stride_v; 467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u = -src_stride_u; 469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v = -src_stride_v; 470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_y) { 473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MirrorPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MirrorPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); 476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MirrorPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); 477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ARGB mirror. 481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBMirror(const uint8* src_argb, int src_stride_argb, 483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = 487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMirrorRow_C; 488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 491ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 494ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 495ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 497da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBMIRRORROW_NEON) 498da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 499da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_Any_NEON; 500da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 501da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_NEON; 502da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 505da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBMIRRORROW_SSE2) 506da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 507da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_Any_SSE2; 508da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 509da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_SSE2; 510da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 513da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBMIRRORROW_AVX2) 514da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 515da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_Any_AVX2; 516da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 517da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBMirrorRow = ARGBMirrorRow_AVX2; 518da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Mirror plane 523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMirrorRow(src_argb, dst_argb, width); 525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 531da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian// Get a blender that optimized for the CPU and pixel count. 532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// As there are 6 blenders to choose from, the caller should try to use 533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// the same blend function for all pixels if possible. 534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianARGBBlendRow GetARGBBlend() { 536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, 537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int width) = ARGBBlendRow_C; 538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBBLENDROW_SSSE3) 539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBBlendRow = ARGBBlendRow_SSSE3; 541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBBlendRow; 542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBBLENDROW_SSE2) 545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBBlendRow = ARGBBlendRow_SSE2; 547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBBLENDROW_NEON) 550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBBlendRow = ARGBBlendRow_NEON; 552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBBlendRow; 555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Alpha Blend 2 ARGB images and store to destination. 558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBBlend(const uint8* src_argb0, int src_stride_argb0, 560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb1, int src_stride_argb1, 561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBBlendRow)(const uint8* src_argb, const uint8* src_argb1, 565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int width) = GetARGBBlend(); 566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb0 == width * 4 && 577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1 == width * 4 && 578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBBlendRow(src_argb0, src_argb1, dst_argb, width); 586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb0 += src_stride_argb0; 587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1 += src_stride_argb1; 588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Multiply 2 ARGB images and store to destination. 594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBMultiply(const uint8* src_argb0, int src_stride_argb0, 596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb1, int src_stride_argb1, 597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBMultiplyRow)(const uint8* src0, const uint8* src1, uint8* dst, 601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBMultiplyRow_C; 602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb0 == width * 4 && 613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1 == width * 4 && 614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBMULTIPLYROW_SSE2) 620da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_Any_SSE2; 622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_SSE2; 624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBMULTIPLYROW_AVX2) 628da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_Any_AVX2; 630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_AVX2; 632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 634ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBMULTIPLYROW_NEON) 636da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 637ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_Any_NEON; 638ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow = ARGBMultiplyRow_NEON; 640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Multiply plane 645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBMultiplyRow(src_argb0, src_argb1, dst_argb, width); 647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb0 += src_stride_argb0; 648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1 += src_stride_argb1; 649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Add 2 ARGB images and store to destination. 655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBAdd(const uint8* src_argb0, int src_stride_argb0, 657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb1, int src_stride_argb1, 658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBAddRow)(const uint8* src0, const uint8* src1, uint8* dst, 662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBAddRow_C; 663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb0 == width * 4 && 674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1 == width * 4 && 675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 680da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBADDROW_SSE2) && (defined(_MSC_VER) && !defined(__clang__)) 681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_SSE2; 683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 685da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBADDROW_SSE2) && !(defined(_MSC_VER) && !defined(__clang__)) 686da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_Any_SSE2; 688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_SSE2; 690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBADDROW_AVX2) 694da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_Any_AVX2; 696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_AVX2; 698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBADDROW_NEON) 702da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_Any_NEON; 704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow = ARGBAddRow_NEON; 706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Add plane 711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAddRow(src_argb0, src_argb1, dst_argb, width); 713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb0 += src_stride_argb0; 714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1 += src_stride_argb1; 715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Subtract 2 ARGB images and store to destination. 721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBSubtract(const uint8* src_argb0, int src_stride_argb0, 723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb1, int src_stride_argb1, 724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBSubtractRow)(const uint8* src0, const uint8* src1, uint8* dst, 728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBSubtractRow_C; 729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb0 == width * 4 && 740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1 == width * 4 && 741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSUBTRACTROW_SSE2) 747da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_Any_SSE2; 749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_SSE2; 751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSUBTRACTROW_AVX2) 755da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_Any_AVX2; 757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_AVX2; 759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSUBTRACTROW_NEON) 763da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_Any_NEON; 765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow = ARGBSubtractRow_NEON; 767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Subtract plane 772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSubtractRow(src_argb0, src_argb1, dst_argb, width); 774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb0 += src_stride_argb0; 775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1 += src_stride_argb1; 776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert I422 to BGRA. 782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I422ToBGRA(const uint8* src_y, int src_stride_y, 784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_bgra, int dst_stride_bgra, 787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*I422ToBGRARow)(const uint8* y_buf, 790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* u_buf, 791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* v_buf, 792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = I422ToBGRARow_C; 794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_bgra || 796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_bgra = dst_bgra + (height - 1) * dst_stride_bgra; 803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_bgra = -dst_stride_bgra; 804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u * 2 == width && 808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v * 2 == width && 809ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_bgra == width * 4) { 810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 812ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = src_stride_u = src_stride_v = dst_stride_bgra = 0; 813ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 814da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOBGRAROW_SSSE3) 815da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 816da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_Any_SSSE3; 817da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 818da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_SSSE3; 819da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 820da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 821da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 822da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOBGRAROW_AVX2) 823da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 824da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_Any_AVX2; 825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 826da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_AVX2; 827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 829da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 830da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOBGRAROW_NEON) 831da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 832da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_Any_NEON; 833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 834da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_NEON; 835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 837da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 838da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOBGRAROW_MIPS_DSPR2) 839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) && 840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && 841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && 842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && 843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_bgra, 4) && IS_ALIGNED(dst_stride_bgra, 4)) { 844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToBGRARow = I422ToBGRARow_MIPS_DSPR2; 845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToBGRARow(src_y, src_u, src_v, dst_bgra, width); 850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_bgra += dst_stride_bgra; 851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u += src_stride_u; 853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v += src_stride_v; 854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 855ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 858ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert I422 to ABGR. 859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I422ToABGR(const uint8* src_y, int src_stride_y, 861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 863ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_abgr, int dst_stride_abgr, 864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 866ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*I422ToABGRRow)(const uint8* y_buf, 867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* u_buf, 868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* v_buf, 869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = I422ToABGRRow_C; 871ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_abgr || 873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 879ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_abgr = dst_abgr + (height - 1) * dst_stride_abgr; 880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_abgr = -dst_stride_abgr; 881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u * 2 == width && 885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v * 2 == width && 886ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_abgr == width * 4) { 887ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = src_stride_u = src_stride_v = dst_stride_abgr = 0; 890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 891ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TOABGRROW_NEON) 892da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_Any_NEON; 894da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_NEON; 896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 898da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 899da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOABGRROW_SSSE3) 900da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_Any_SSSE3; 902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 903da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_SSSE3; 904da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 905da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 906da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 907da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TOABGRROW_AVX2) 908da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 909da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_Any_AVX2; 910da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 911da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToABGRRow = I422ToABGRRow_AVX2; 912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToABGRRow(src_y, src_u, src_v, dst_abgr, width); 918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_abgr += dst_stride_abgr; 919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u += src_stride_u; 921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v += src_stride_v; 922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert I422 to RGBA. 927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I422ToRGBA(const uint8* src_y, int src_stride_y, 929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_u, int src_stride_u, 930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_v, int src_stride_v, 931ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_rgba, int dst_stride_rgba, 932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*I422ToRGBARow)(const uint8* y_buf, 935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* u_buf, 936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* v_buf, 937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = I422ToRGBARow_C; 939ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_u || !src_v || 940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian !dst_rgba || 941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 942ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 947ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba; 948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_rgba = -dst_stride_rgba; 949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_u * 2 == width && 953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_v * 2 == width && 954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_rgba == width * 4) { 955ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = src_stride_u = src_stride_v = dst_stride_rgba = 0; 958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_I422TORGBAROW_NEON) 960da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_Any_NEON; 962da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_NEON; 964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 966da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 967da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TORGBAROW_SSSE3) 968da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_Any_SSSE3; 970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 971da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_SSSE3; 972da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 973da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 974da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 975da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_I422TORGBAROW_AVX2) 976da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 977da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_Any_AVX2; 978da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 979da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian I422ToRGBARow = I422ToRGBARow_AVX2; 980ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian I422ToRGBARow(src_y, src_u, src_v, dst_rgba, width); 986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgba += dst_stride_rgba; 987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_u += src_stride_u; 989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_v += src_stride_v; 990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert NV12 to RGB565. 995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 996ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint NV12ToRGB565(const uint8* src_y, int src_stride_y, 997ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_uv, int src_stride_uv, 998ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_rgb565, int dst_stride_rgb565, 999ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1000ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1001ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*NV12ToRGB565Row)(const uint8* y_buf, 1002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* uv_buf, 1003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 1004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = NV12ToRGB565Row_C; 1005ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_uv || !dst_rgb565 || 1006ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1007ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1008ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1009ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; 1013ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_rgb565 = -dst_stride_rgb565; 1014ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1015ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_NV12TORGB565ROW_SSSE3) 1016da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1017ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_Any_SSSE3; 1018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_SSSE3; 1020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1021ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1022da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1023da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV12TORGB565ROW_AVX2) 1024da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1025da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_Any_AVX2; 1026da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1027da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_AVX2; 1028da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1029da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1030da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1031da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV12TORGB565ROW_NEON) 1032da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_Any_NEON; 1034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV12ToRGB565Row = NV12ToRGB565Row_NEON; 1036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV12ToRGB565Row(src_y, src_uv, dst_rgb565, width); 1042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgb565 += dst_stride_rgb565; 1043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 1044ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y & 1) { 1045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_uv += src_stride_uv; 1046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert NV21 to RGB565. 1052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint NV21ToRGB565(const uint8* src_y, int src_stride_y, 1054ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_vu, int src_stride_vu, 1055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_rgb565, int dst_stride_rgb565, 1056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1057ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*NV21ToRGB565Row)(const uint8* y_buf, 1059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_vu, 1060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* rgb_buf, 1061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = NV21ToRGB565Row_C; 1062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !src_vu || !dst_rgb565 || 1063ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1067ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565; 1070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_rgb565 = -dst_stride_rgb565; 1071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_NV21TORGB565ROW_SSSE3) 1073da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_Any_SSSE3; 1075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_SSSE3; 1077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1079da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1080da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV21TORGB565ROW_AVX2) 1081da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1082da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_Any_AVX2; 1083da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1084da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_AVX2; 1085da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1086da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1087da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1088da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_NV21TORGB565ROW_NEON) 1089da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_Any_NEON; 1091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV21ToRGB565Row = NV21ToRGB565Row_NEON; 1093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1098ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian NV21ToRGB565Row(src_y, src_vu, dst_rgb565, width); 1099ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_rgb565 += dst_stride_rgb565; 1100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 1101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y & 1) { 1102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_vu += src_stride_vu; 1103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid SetPlane(uint8* dst_y, int dst_stride_y, 1110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, 1111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint32 value) { 1112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1113da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*SetRow)(uint8* dst, uint8 value, int pix) = SetRow_C; 1114da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height < 0) { 1115da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian height = -height; 1116da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_y = dst_y + (height - 1) * dst_stride_y; 1117da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_stride_y = -dst_stride_y; 1118da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_y == width) { 1121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_y = 0; 1124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SETROW_NEON) 1126da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1127da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow = SetRow_Any_NEON; 1128da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1129da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow = SetRow_NEON; 1130da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1133ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SETROW_X86) 1134da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasX86)) { 1135da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow = SetRow_Any_X86; 1136da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1137da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow = SetRow_X86; 1138da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1139da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1140da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1141da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SETROW_ERMS) 1142da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasERMS)) { 1143da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow = SetRow_ERMS; 1144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Set plane 1148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1149da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SetRow(dst_y, value, width); 1150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_y += dst_stride_y; 1151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1153ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1154ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Draw a rectangle into I420 1155ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1156ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint I420Rect(uint8* dst_y, int dst_stride_y, 1157ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_u, int dst_stride_u, 1158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_v, int dst_stride_v, 1159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x, int y, 1160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, 1161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int value_y, int value_u, int value_v) { 1162ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 1163ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int halfheight = (height + 1) >> 1; 1164ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* start_y = dst_y + y * dst_stride_y + x; 1165ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* start_u = dst_u + (y / 2) * dst_stride_u + (x / 2); 1166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* start_v = dst_v + (y / 2) * dst_stride_v + (x / 2); 1167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_y || !dst_u || !dst_v || 1168da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian width <= 0 || height == 0 || 1169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian x < 0 || y < 0 || 1170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian value_y < 0 || value_y > 255 || 1171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian value_u < 0 || value_u > 255 || 1172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian value_v < 0 || value_v > 255) { 1173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SetPlane(start_y, dst_stride_y, width, height, value_y); 1177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SetPlane(start_u, dst_stride_u, halfwidth, halfheight, value_u); 1178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SetPlane(start_v, dst_stride_v, halfwidth, halfheight, value_v); 1179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Draw a rectangle into ARGB 1183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBRect(uint8* dst_argb, int dst_stride_argb, 1185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, 1186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, 1187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint32 value) { 1188da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int y; 1189da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*ARGBSetRow)(uint8* dst_argb, uint32 value, int pix) = ARGBSetRow_C; 1190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || 1191da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian width <= 0 || height == 0 || 1192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_x < 0 || dst_y < 0) { 1193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1195da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height < 0) { 1196da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian height = -height; 1197da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 1198da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 1199da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_y * dst_stride_argb + dst_x * 4; 1201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1207da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 1208da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBSETROW_NEON) 1209da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1210da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBSetRow = ARGBSetRow_Any_NEON; 1211da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1212da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBSetRow = ARGBSetRow_NEON; 1213da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1216da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBSETROW_X86) 1217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasX86)) { 1218da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBSetRow = ARGBSetRow_X86; 1219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1221da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 1222da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Set plane 1223da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1224da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBSetRow(dst_argb, value, width); 1225da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1226da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 1227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert unattentuated ARGB to preattenuated ARGB. 1231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// An unattenutated ARGB alpha blend uses the formula 1232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// p = a * f + (1 - a) * b 1233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// where 1234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// p is output pixel 1235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// f is foreground pixel 1236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// b is background pixel 1237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// a is alpha value from foreground pixel 1238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// An preattenutated ARGB alpha blend uses the formula 1239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// p = f + (1 - a) * b 1240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// where 1241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// f is foreground pixel premultiplied by alpha 1242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBAttenuate(const uint8* src_argb, int src_stride_argb, 1245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBAttenuateRow)(const uint8* src_argb, uint8* dst_argb, 1249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBAttenuateRow_C; 1250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 1260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 1264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBATTENUATEROW_SSE2) 1266da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_Any_SSE2; 1268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_SSE2; 1270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBATTENUATEROW_SSSE3) 1274da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; 1276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_SSSE3; 1278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBATTENUATEROW_AVX2) 1282da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1283ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_Any_AVX2; 1284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_AVX2; 1286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBATTENUATEROW_NEON) 1290da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_Any_NEON; 1292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow = ARGBAttenuateRow_NEON; 1294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBAttenuateRow(src_argb, dst_argb, width); 1300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert preattentuated ARGB to unattenuated ARGB. 1307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBUnattenuate(const uint8* src_argb, int src_stride_argb, 1309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBUnattenuateRow)(const uint8* src_argb, uint8* dst_argb, 1313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBUnattenuateRow_C; 1314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 1324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1326ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 1328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBUNATTENUATEROW_SSE2) 1330da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBUnattenuateRow = ARGBUnattenuateRow_Any_SSE2; 1332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBUnattenuateRow = ARGBUnattenuateRow_SSE2; 1334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBUNATTENUATEROW_AVX2) 1338da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBUnattenuateRow = ARGBUnattenuateRow_Any_AVX2; 1340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBUnattenuateRow = ARGBUnattenuateRow_AVX2; 1342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1344ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1345ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// TODO(fbarchard): Neon version. 1346ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1347ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1348ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBUnattenuateRow(src_argb, dst_argb, width); 1349ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1350ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1351ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1352ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1353ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1354ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1355ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Convert ARGB to Grayed ARGB. 1356ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1357ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBGrayTo(const uint8* src_argb, int src_stride_argb, 1358ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1359ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1360ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1361ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, 1362ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBGrayRow_C; 1363ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1364ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1365ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1366ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1367ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1368ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1369ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1370ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1371ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1372ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 1373ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1374ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1375ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1376ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 1377ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1378ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBGRAYROW_SSSE3) 1379da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { 1380ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow = ARGBGrayRow_SSSE3; 1381ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1382da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1383da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBGRAYROW_NEON) 1384ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1385ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow = ARGBGrayRow_NEON; 1386ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1387ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1388ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1389ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1390ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow(src_argb, dst_argb, width); 1391ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1392ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1393ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1394ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1395ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1396ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1397ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Make a rectangle of ARGB gray scale. 1398ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1399ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBGray(uint8* dst_argb, int dst_stride_argb, 1400ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, 1401ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1402ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1403ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBGrayRow)(const uint8* src_argb, uint8* dst_argb, 1404ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBGrayRow_C; 1405ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1406ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { 1407ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1408ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1409ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1410ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1411ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1412ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1413ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1414ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1415ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBGRAYROW_SSSE3) 1416da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { 1417ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow = ARGBGrayRow_SSSE3; 1418ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1419da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1420da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBGRAYROW_NEON) 1421ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1422ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow = ARGBGrayRow_NEON; 1423ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1424ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1425ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1426ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBGrayRow(dst, dst, width); 1427ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride_argb; 1428ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1429ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1430ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1431ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1432ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Make a rectangle of ARGB Sepia tone. 1433ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1434ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBSepia(uint8* dst_argb, int dst_stride_argb, 1435ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, int width, int height) { 1436ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1437ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBSepiaRow)(uint8* dst_argb, int width) = ARGBSepiaRow_C; 1438ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1439ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0) { 1440ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1441ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1442ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1443ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1444ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1445ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1446ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1447ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1448ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSEPIAROW_SSSE3) 1449da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { 1450ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSepiaRow = ARGBSepiaRow_SSSE3; 1451ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1452da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1453da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBSEPIAROW_NEON) 1454ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1455ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSepiaRow = ARGBSepiaRow_NEON; 1456ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1457ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1458ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1459ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBSepiaRow(dst, width); 1460ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride_argb; 1461ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1462ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1463ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1464ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1465ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a 4x4 matrix to each ARGB pixel. 1466ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Note: Normally for shading, but can be used to swizzle or invert. 1467ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1468ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBColorMatrix(const uint8* src_argb, int src_stride_argb, 1469ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1470ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int8* matrix_argb, 1471ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1472ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1473ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBColorMatrixRow)(const uint8* src_argb, uint8* dst_argb, 1474ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int8* matrix_argb, int width) = ARGBColorMatrixRow_C; 1475ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || !matrix_argb || width <= 0 || height == 0) { 1476ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1477ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1478ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1479ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1480ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1481ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1482ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1483ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1484ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 1485ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1486ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1487ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1488ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 1489ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1490ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOLORMATRIXROW_SSSE3) 1491da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) { 1492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBColorMatrixRow = ARGBColorMatrixRow_SSSE3; 1493ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1494da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1495da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBCOLORMATRIXROW_NEON) 1496ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1497ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBColorMatrixRow = ARGBColorMatrixRow_NEON; 1498ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1499ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1500ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1501ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBColorMatrixRow(src_argb, dst_argb, matrix_argb, width); 1502ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1503ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1504ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1505ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1506ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1507ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a 4x3 matrix to each ARGB pixel. 1509ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Deprecated. 1510ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1511ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RGBColorMatrix(uint8* dst_argb, int dst_stride_argb, 1512ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int8* matrix_rgb, 1513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, int width, int height) { 1514ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SIMD_ALIGNED(int8 matrix_argb[16]); 1515ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1516ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || !matrix_rgb || width <= 0 || height <= 0 || 1517ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_x < 0 || dst_y < 0) { 1518ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1520ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1521ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Convert 4x3 7 bit matrix to 4x4 6 bit matrix. 1522ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[0] = matrix_rgb[0] / 2; 1523ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[1] = matrix_rgb[1] / 2; 1524ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[2] = matrix_rgb[2] / 2; 1525ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[3] = matrix_rgb[3] / 2; 1526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[4] = matrix_rgb[4] / 2; 1527ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[5] = matrix_rgb[5] / 2; 1528ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[6] = matrix_rgb[6] / 2; 1529ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[7] = matrix_rgb[7] / 2; 1530ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[8] = matrix_rgb[8] / 2; 1531ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[9] = matrix_rgb[9] / 2; 1532ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[10] = matrix_rgb[10] / 2; 1533ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[11] = matrix_rgb[11] / 2; 1534ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[14] = matrix_argb[13] = matrix_argb[12] = 0; 1535ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian matrix_argb[15] = 64; // 1.0 1536ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1537ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBColorMatrix((const uint8*)(dst), dst_stride_argb, 1538ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst, dst_stride_argb, 1539ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian &matrix_argb[0], width, height); 1540ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1541ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1542ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a color table each ARGB pixel. 1543ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Table contains 256 ARGB values. 1544ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1545ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBColorTable(uint8* dst_argb, int dst_stride_argb, 1546ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* table_argb, 1547ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, int width, int height) { 1548ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1549ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBColorTableRow)(uint8* dst_argb, const uint8* table_argb, 1550ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBColorTableRow_C; 1551ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || !table_argb || width <= 0 || height <= 0 || 1553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_x < 0 || dst_y < 0) { 1554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1556ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1557ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1558ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1559ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1560ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1561ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1562ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOLORTABLEROW_X86) 1563ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasX86)) { 1564ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBColorTableRow = ARGBColorTableRow_X86; 1565ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1566ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1567ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1568ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBColorTableRow(dst, table_argb, width); 1569ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride_argb; 1570ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1571ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1572ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1573ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1574ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a color table each ARGB pixel but preserve destination alpha. 1575ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Table contains 256 ARGB values. 1576ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1577ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint RGBColorTable(uint8* dst_argb, int dst_stride_argb, 1578ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* table_argb, 1579ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, int width, int height) { 1580ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1581ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*RGBColorTableRow)(uint8* dst_argb, const uint8* table_argb, 1582ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = RGBColorTableRow_C; 1583ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1584ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || !table_argb || width <= 0 || height <= 0 || 1585ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_x < 0 || dst_y < 0) { 1586ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1587ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1588ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1589ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1590ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1591ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1592ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1593ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1594ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_RGBCOLORTABLEROW_X86) 1595ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasX86)) { 1596ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBColorTableRow = RGBColorTableRow_X86; 1597ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1598ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1599ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1600ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RGBColorTableRow(dst, table_argb, width); 1601ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride_argb; 1602ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1603ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1604ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1605ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1606ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// ARGBQuantize is used to posterize art. 1607ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// e.g. rgb / qvalue * qvalue + qvalue / 2 1608ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// But the low levels implement efficiently with 3 parameters, and could be 1609ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// used for other high level operations. 1610ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// dst_argb[0] = (b * scale >> 16) * interval_size + interval_offset; 1611ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// where scale is 1 / interval_size as a fixed point value. 1612ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// The divide is replaces with a multiply by reciprocal fixed point multiply. 1613ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Caveat - although SSE2 saturates, the C function does not and should be used 1614ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// with care if doing anything but quantization. 1615ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1616ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBQuantize(uint8* dst_argb, int dst_stride_argb, 1617ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int scale, int interval_size, int interval_offset, 1618ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int dst_x, int dst_y, int width, int height) { 1619ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1620ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBQuantizeRow)(uint8* dst_argb, int scale, int interval_size, 1621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int interval_offset, int width) = ARGBQuantizeRow_C; 1622ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4; 1623ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_argb || width <= 0 || height <= 0 || dst_x < 0 || dst_y < 0 || 1624ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian interval_size < 1 || interval_size > 255) { 1625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1626ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (dst_stride_argb == width * 4) { 1629ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1630ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1631ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = 0; 1632ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1633ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBQUANTIZEROW_SSE2) 1634da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4)) { 1635ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBQuantizeRow = ARGBQuantizeRow_SSE2; 1636ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1637da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1638da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBQUANTIZEROW_NEON) 1639ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBQuantizeRow = ARGBQuantizeRow_NEON; 1641ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1642ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1643ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBQuantizeRow(dst, scale, interval_size, interval_offset, width); 1645ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst += dst_stride_argb; 1646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1648ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1649ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Computes table of cumulative sum for image where the value is the sum 1651ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// of all values above and to the left of the entry. Used by ARGBBlur. 1652ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBComputeCumulativeSum(const uint8* src_argb, int src_stride_argb, 1654ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* dst_cumsum, int dst_stride32_cumsum, 1655ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 1656ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1657ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum, 1658ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C; 1659ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* previous_cumsum = dst_cumsum; 1660ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!dst_cumsum || !src_argb || width <= 0 || height <= 0) { 1661ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1662ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1663ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) 1664ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1665ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; 1666ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1667ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1668ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian memset(dst_cumsum, 0, width * sizeof(dst_cumsum[0]) * 4); // 4 int per pixel. 1669ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1670ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ComputeCumulativeSumRow(src_argb, dst_cumsum, previous_cumsum, width); 1671ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian previous_cumsum = dst_cumsum; 1672ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_cumsum += dst_stride32_cumsum; 1673ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1674ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1675ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Blur ARGB image. 1679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Caller should allocate CumulativeSum table of width * height * 16 bytes 1680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// aligned to 16 byte boundary. height can be radius * 2 + 2 to save memory 1681ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// as the buffer is treated as circular. 1682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBBlur(const uint8* src_argb, int src_stride_argb, 1684ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1685ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* dst_cumsum, int dst_stride32_cumsum, 1686ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, int radius) { 1687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ComputeCumulativeSumRow)(const uint8 *row, int32 *cumsum, 1689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C; 1690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*CumulativeSumToAverageRow)(const int32* topleft, const int32* botleft, 1691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int area, uint8* dst, int count) = CumulativeSumToAverageRow_C; 1692ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* cumsum_bot_row; 1693ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* max_cumsum_bot_row; 1694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int32* cumsum_top_row; 1695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1700ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1701ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1702ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (radius > height) { 1705ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian radius = height; 1706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (radius > (width / 2 - 1)) { 1708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian radius = width / 2 - 1; 1709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1710ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (radius <= 0) { 1711ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1712ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1713ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_CUMULATIVESUMTOAVERAGEROW_SSE2) 1714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2; 1716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CumulativeSumToAverageRow = CumulativeSumToAverageRow_SSE2; 1717ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1718ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1719ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Compute enough CumulativeSum for first row to be blurred. After this 1720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // one row of CumulativeSum is updated at a time. 1721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBComputeCumulativeSum(src_argb, src_stride_argb, 1722ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_cumsum, dst_stride32_cumsum, 1723ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, radius); 1724ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1725ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + radius * src_stride_argb; 1726ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_bot_row = &dst_cumsum[(radius - 1) * dst_stride32_cumsum]; 1727ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1728ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian max_cumsum_bot_row = &dst_cumsum[(radius * 2 + 2) * dst_stride32_cumsum]; 1729ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_top_row = &dst_cumsum[0]; 1730ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1731ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1732ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int top_y = ((y - radius - 1) >= 0) ? (y - radius - 1) : 0; 1733ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int bot_y = ((y + radius) < height) ? (y + radius) : (height - 1); 1734ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int area = radius * (bot_y - top_y); 1735ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int boxwidth = radius * 4; 1736ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int x; 1737ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int n; 1738ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1739ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Increment cumsum_top_row pointer with circular buffer wrap around. 1740ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (top_y) { 1741ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_top_row += dst_stride32_cumsum; 1742ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cumsum_top_row >= max_cumsum_bot_row) { 1743ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_top_row = dst_cumsum; 1744ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1745ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1746ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Increment cumsum_bot_row pointer with circular buffer wrap around and 1747ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // then fill in a row of CumulativeSum. 1748ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if ((y + radius) < height) { 1749ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int32* prev_cumsum_bot_row = cumsum_bot_row; 1750ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_bot_row += dst_stride32_cumsum; 1751ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cumsum_bot_row >= max_cumsum_bot_row) { 1752ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_bot_row = dst_cumsum; 1753ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1754ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ComputeCumulativeSumRow(src_argb, cumsum_bot_row, prev_cumsum_bot_row, 1755ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width); 1756ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1757ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1758ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1759ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Left clipped. 1760ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (x = 0; x < radius + 1; ++x) { 1761ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, 1762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian boxwidth, area, &dst_argb[x * 4], 1); 1763ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian area += (bot_y - top_y); 1764ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian boxwidth += 4; 1765ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1766ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1767ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Middle unclipped. 1768ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian n = (width - 1) - radius - x + 1; 1769ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CumulativeSumToAverageRow(cumsum_top_row, cumsum_bot_row, 1770ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian boxwidth, area, &dst_argb[x * 4], n); 1771ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1772ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Right clipped. 1773ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (x += n; x <= width - 1; ++x) { 1774ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian area -= (bot_y - top_y); 1775ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian boxwidth -= 4; 1776ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian CumulativeSumToAverageRow(cumsum_top_row + (x - radius - 1) * 4, 1777ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian cumsum_bot_row + (x - radius - 1) * 4, 1778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian boxwidth, area, &dst_argb[x * 4], 1); 1779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1781ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1782ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1783ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1784ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1785ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Multiply ARGB image by a specified ARGB value. 1786ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1787ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBShade(const uint8* src_argb, int src_stride_argb, 1788ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1789ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, uint32 value) { 1790ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1791ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBShadeRow)(const uint8* src_argb, uint8* dst_argb, 1792ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, uint32 value) = ARGBShadeRow_C; 1793ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0 || value == 0u) { 1794ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1795ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1796ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1797ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1798ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1799ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1800ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1801ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1802ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 1803ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1804ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1805ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1806ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 1807ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1808ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSHADEROW_SSE2) 1809da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 4)) { 1810ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShadeRow = ARGBShadeRow_SSE2; 1811ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1812da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 1813da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBSHADEROW_NEON) 1814ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) { 1815ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShadeRow = ARGBShadeRow_NEON; 1816ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1817ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1818ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1819ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1820ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShadeRow(src_argb, dst_argb, width, value); 1821ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 1822ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1823ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1824ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1825ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1826ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1827ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Interpolate 2 ARGB images by specified amount (0 to 255). 1828ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1829ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBInterpolate(const uint8* src_argb0, int src_stride_argb0, 1830ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_argb1, int src_stride_argb1, 1831ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1832ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, int interpolation) { 1833ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1834ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 1835ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, 1836ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int source_y_fraction) = InterpolateRow_C; 1837ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb0 || !src_argb1 || !dst_argb || width <= 0 || height == 0) { 1838ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1839ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1840ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1841ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1842ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1843ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb = dst_argb + (height - 1) * dst_stride_argb; 1844ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb = -dst_stride_argb; 1845ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1846ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1847ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb0 == width * 4 && 1848ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb1 == width * 4 && 1849ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1850ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1851ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1852ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb0 = src_stride_argb1 = dst_stride_argb = 0; 1853ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1854ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 1855da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1856ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 1857ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1858da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 1859ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1860ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1861ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1862ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 1863da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1864ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 1865ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1866da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 1867ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1868ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1869ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1870ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 1871da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1872ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 1873ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1874ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 1875ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1876ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1877ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1878ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 1879da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1880ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 1881ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1882ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 1883ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1884ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1885ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1886da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_MIPS_DSPR2) 1887da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasMIPS_DSPR2) && 1888ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb0, 4) && IS_ALIGNED(src_stride_argb0, 4) && 1889ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(src_argb1, 4) && IS_ALIGNED(src_stride_argb1, 4) && 1890ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { 1891da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_MIPS_DSPR2; 1892ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1893ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1894ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1895ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1896ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian InterpolateRow(dst_argb, src_argb0, src_argb1 - src_argb0, 1897ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width * 4, interpolation); 1898ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb0 += src_stride_argb0; 1899ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb1 += src_stride_argb1; 1900ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1901ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1902ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1903ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1904ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1905ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Shuffle ARGB channel order. e.g. BGRA to ARGB. 1906ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 1907ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBShuffle(const uint8* src_bgra, int src_stride_bgra, 1908ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1909ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* shuffler, int width, int height) { 1910ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1911ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBShuffleRow)(const uint8* src_bgra, uint8* dst_argb, 1912ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* shuffler, int pix) = ARGBShuffleRow_C; 1913ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_bgra || !dst_argb || 1914ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width <= 0 || height == 0) { 1915ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1916ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1917ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1918ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1919ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1920ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_bgra = src_bgra + (height - 1) * src_stride_bgra; 1921ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_bgra = -src_stride_bgra; 1922ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1923ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 1924ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_bgra == width * 4 && 1925ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 1926ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 1927ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 1928ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_bgra = dst_stride_argb = 0; 1929ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1930ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSHUFFLEROW_SSE2) 1931da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 1932ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_Any_SSE2; 1933ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1934ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_SSE2; 1935ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1936ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1937ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1938ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSHUFFLEROW_SSSE3) 1939da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1940ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_Any_SSSE3; 1941ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 1942da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_SSSE3; 1943ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1944ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1945ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1946ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSHUFFLEROW_AVX2) 1947da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 1948ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_Any_AVX2; 1949ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 1950ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_AVX2; 1951ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1952ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1953ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1954ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBSHUFFLEROW_NEON) 1955da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 1956ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_Any_NEON; 1957ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 4)) { 1958ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow = ARGBShuffleRow_NEON; 1959ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1960ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1961ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 1962ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1963ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 1964ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBShuffleRow(src_bgra, dst_argb, shuffler, width); 1965ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_bgra += src_stride_bgra; 1966ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 1967ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1968ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 1969ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 1970ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 1971ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Sobel ARGB effect. 1972ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic int ARGBSobelize(const uint8* src_argb, int src_stride_argb, 1973ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 1974ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height, 1975ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelRow)(const uint8* src_sobelx, 1976ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_sobely, 1977ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst, int width)) { 1978ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 1979da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*ARGBToYJRow)(const uint8* src_argb, uint8* dst_g, int pix) = 1980da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow_C; 1981ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelYRow)(const uint8* src_y0, const uint8* src_y1, 1982ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_sobely, int width) = SobelYRow_C; 1983ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelXRow)(const uint8* src_y0, const uint8* src_y1, 1984ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* src_y2, uint8* dst_sobely, int width) = 1985ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelXRow_C; 1986ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int kEdge = 16; // Extra pixels at start of row for extrude/align. 1987ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 1988ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 1989ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1990ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 1991ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 1992ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 1993ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 1994ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 1995ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 1996da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 1997da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYJROW_SSSE3) 1998da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 1999da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_Any_SSSE3; 2000da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2001da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_SSSE3; 2002ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2003ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2004ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2005da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYJROW_AVX2) 2006da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 2007da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_Any_AVX2; 2008da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 2009da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_AVX2; 2010ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2011ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2012ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2013da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_ARGBTOYJROW_NEON) 2014da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2015da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_Any_NEON; 2016ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 2017da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow = ARGBToYJRow_NEON; 2018ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2019ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2020ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2021da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2022ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELYROW_SSE2) 2023ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2024ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelYRow = SobelYRow_SSE2; 2025ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2026ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2027ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELYROW_NEON) 2028ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2029ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelYRow = SobelYRow_NEON; 2030ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2031ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2032ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELXROW_SSE2) 2033ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2034ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelXRow = SobelXRow_SSE2; 2035ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2036ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2037ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELXROW_NEON) 2038ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2039ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelXRow = SobelXRow_NEON; 2040ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2041ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2042ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 2043ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // 3 rows with edges before/after. 2044da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian const int kRowSize = (width + kEdge + 31) & ~31; 2045ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian align_buffer_64(rows, kRowSize * 2 + (kEdge + kRowSize * 3 + kEdge)); 2046ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_sobelx = rows; 2047ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_sobely = rows + kRowSize; 2048ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_y = rows + kRowSize * 2; 2049ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2050ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Convert first row. 2051ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_y0 = row_y + kEdge; 2052ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_y1 = row_y0 + kRowSize; 2053ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_y2 = row_y1 + kRowSize; 2054da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow(src_argb, row_y0, width); 2055ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y0[-1] = row_y0[0]; 2056ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind. 2057da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow(src_argb, row_y1, width); 2058ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y1[-1] = row_y1[0]; 2059ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian memset(row_y1 + width, row_y1[width - 1], 16); 2060ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian memset(row_y2 + width, 0, 16); 2061ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2062ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 2063da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Convert next row of ARGB to G. 2064ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (y < (height - 1)) { 2065ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 2066ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2067da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ARGBToYJRow(src_argb, row_y2, width); 2068ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y2[-1] = row_y2[0]; 2069ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y2[width] = row_y2[width - 1]; 2070ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2071ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelXRow(row_y0 - 1, row_y1 - 1, row_y2 - 1, row_sobelx, width); 2072ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelYRow(row_y0 - 1, row_y2 - 1, row_sobely, width); 2073ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian SobelRow(row_sobelx, row_sobely, dst_argb, width); 2074ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2075ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Cycle thru circular queue of 3 row_y buffers. 2076ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian { 2077ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* row_yt = row_y0; 2078ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y0 = row_y1; 2079ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y1 = row_y2; 2080ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian row_y2 = row_yt; 2081ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2082ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2083ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 2084ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2085ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian free_aligned_buffer_64(rows); 2086ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2087ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 2088ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2089ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2090ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Sobel ARGB effect. 2091ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2092ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBSobel(const uint8* src_argb, int src_stride_argb, 2093ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2094ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2095ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelRow)(const uint8* src_sobelx, const uint8* src_sobely, 2096ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int width) = SobelRow_C; 2097ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELROW_SSE2) 2098da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2099da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelRow = SobelRow_Any_SSE2; 2100da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2101da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelRow = SobelRow_SSE2; 2102da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELROW_NEON) 2106da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2107da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelRow = SobelRow_Any_NEON; 2108da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 2109da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelRow = SobelRow_NEON; 2110da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 2114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, SobelRow); 2115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Sobel ARGB effect with planar output. 2118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBSobelToPlane(const uint8* src_argb, int src_stride_argb, 2120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 2121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2122ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelToPlaneRow)(const uint8* src_sobelx, const uint8* src_sobely, 2123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_, int width) = SobelToPlaneRow_C; 2124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELTOPLANEROW_SSE2) 2125da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2126da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelToPlaneRow = SobelToPlaneRow_Any_SSE2; 2127da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2128da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelToPlaneRow = SobelToPlaneRow_SSE2; 2129da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2131ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELTOPLANEROW_NEON) 2133da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2134da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelToPlaneRow = SobelToPlaneRow_Any_NEON; 2135da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2136da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelToPlaneRow = SobelToPlaneRow_NEON; 2137da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2138ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2139ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2140ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBSobelize(src_argb, src_stride_argb, dst_y, dst_stride_y, 2141ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, SobelToPlaneRow); 2142ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2143ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2144ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// SobelXY ARGB effect. 2145ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Similar to Sobel, but also stores Sobel X in R and Sobel Y in B. G = Sobel. 2146ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2147ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBSobelXY(const uint8* src_argb, int src_stride_argb, 2148ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2149ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2150ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*SobelXYRow)(const uint8* src_sobelx, const uint8* src_sobely, 2151ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int width) = SobelXYRow_C; 2152ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELXYROW_SSE2) 2153da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2154da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelXYRow = SobelXYRow_Any_SSE2; 2155da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2156da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelXYRow = SobelXYRow_SSE2; 2157da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2158ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2159ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2160ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_SOBELXYROW_NEON) 2161da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2162da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelXYRow = SobelXYRow_Any_NEON; 2163da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 8)) { 2164da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SobelXYRow = SobelXYRow_NEON; 2165da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2166ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2167ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2168ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return ARGBSobelize(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 2169ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width, height, SobelXYRow); 2170ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2171ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2172ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a 4x4 polynomial to each ARGB pixel. 2173ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2174ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBPolynomial(const uint8* src_argb, int src_stride_argb, 2175ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2176ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const float* poly, 2177ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2178ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 2179ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBPolynomialRow)(const uint8* src_argb, 2180ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, const float* poly, 2181ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width) = ARGBPolynomialRow_C; 2182ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || !poly || width <= 0 || height == 0) { 2183ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 2184ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2185ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 2186ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 2187ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 2188ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 2189ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 2190ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2191ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 2192ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 2193ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 2194ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 2195ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 2196ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 2197ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2198ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBPOLYNOMIALROW_SSE2) 2199ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 2)) { 2200ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBPolynomialRow = ARGBPolynomialRow_SSE2; 2201ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2202ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2203ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBPOLYNOMIALROW_AVX2) 2204ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && TestCpuFlag(kCpuHasFMA3) && 2205ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian IS_ALIGNED(width, 2)) { 2206ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBPolynomialRow = ARGBPolynomialRow_AVX2; 2207ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2208ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2209ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2210ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 2211ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBPolynomialRow(src_argb, dst_argb, poly, width); 2212ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 2213ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 2214ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2215ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 2216ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2217ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2218ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply a lumacolortable to each ARGB pixel. 2219ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2220ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBLumaColorTable(const uint8* src_argb, int src_stride_argb, 2221ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2222ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const uint8* luma, 2223ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2224ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 2225ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBLumaColorTableRow)(const uint8* src_argb, uint8* dst_argb, 2226ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, const uint8* luma, const uint32 lumacoeff) = 2227ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBLumaColorTableRow_C; 2228ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || !luma || width <= 0 || height == 0) { 2229ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 2230ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 2232ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 2233ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 2234ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 2235ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 2236ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2237ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 2238ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 2239ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 2240ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 2241ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 2242ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 2243ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2244ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBLUMACOLORTABLEROW_SSSE3) 2245ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4)) { 2246ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBLumaColorTableRow = ARGBLumaColorTableRow_SSSE3; 2247ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2248ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2249ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2250ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 2251ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBLumaColorTableRow(src_argb, dst_argb, width, luma, 0x00264b0f); 2252ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 2253ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 2254ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2255ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 2256ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2257ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy Alpha from one ARGB image to another. 2259ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2260ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBCopyAlpha(const uint8* src_argb, int src_stride_argb, 2261ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2262ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2263ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 2264ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBCopyAlphaRow)(const uint8* src_argb, uint8* dst_argb, int width) = 2265ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyAlphaRow_C; 2266ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_argb || !dst_argb || width <= 0 || height == 0) { 2267ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 2268ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2269ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 2270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 2271ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 2272ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb = src_argb + (height - 1) * src_stride_argb; 2273ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = -src_stride_argb; 2274ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2275ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 2276ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_argb == width * 4 && 2277ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 2278ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 2279ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 2280ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_argb = dst_stride_argb = 0; 2281ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2282ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOPYALPHAROW_SSE2) 2283da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 8)) { 2284ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyAlphaRow = ARGBCopyAlphaRow_SSE2; 2285ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2286ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2287ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOPYALPHAROW_AVX2) 2288ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 16)) { 2289ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyAlphaRow = ARGBCopyAlphaRow_AVX2; 2290ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2291ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2292ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2293ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 2294ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyAlphaRow(src_argb, dst_argb, width); 2295ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_argb += src_stride_argb; 2296ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 2297ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2298ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 2299ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2300ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2301ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Copy a planar Y channel to the alpha channel of a destination ARGB image. 2302ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianLIBYUV_API 2303ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint ARGBCopyYToAlpha(const uint8* src_y, int src_stride_y, 2304ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian uint8* dst_argb, int dst_stride_argb, 2305ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int width, int height) { 2306ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int y; 2307ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian void (*ARGBCopyYToAlphaRow)(const uint8* src_y, uint8* dst_argb, int width) = 2308ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyYToAlphaRow_C; 2309ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (!src_y || !dst_argb || width <= 0 || height == 0) { 2310ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return -1; 2311ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2312ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Negative height means invert the image. 2313ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (height < 0) { 2314ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = -height; 2315ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y = src_y + (height - 1) * src_stride_y; 2316ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = -src_stride_y; 2317ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2318ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Coalesce rows. 2319ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (src_stride_y == width && 2320ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_stride_argb == width * 4) { 2321ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian width *= height; 2322ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian height = 1; 2323ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_stride_y = dst_stride_argb = 0; 2324ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2325ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOPYYTOALPHAROW_SSE2) 2326da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 8)) { 2327ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_SSE2; 2328ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2329ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2330ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#if defined(HAS_ARGBCOPYYTOALPHAROW_AVX2) 2331ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 16)) { 2332ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyYToAlphaRow = ARGBCopyYToAlphaRow_AVX2; 2333ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2334ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2335ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2336ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (y = 0; y < height; ++y) { 2337ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian ARGBCopyYToAlphaRow(src_y, dst_argb, width); 2338ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian src_y += src_stride_y; 2339ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian dst_argb += dst_stride_argb; 2340ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 2341ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian return 0; 2342ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 2343ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 2344da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh VenkatasubramanianLIBYUV_API 2345da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianint YUY2ToNV12(const uint8* src_yuy2, int src_stride_yuy2, 2346da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 2347da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian uint8* dst_uv, int dst_stride_uv, 2348da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int width, int height) { 2349da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int y; 2350da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 2351da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) = 2352da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow_C; 2353da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2354da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, 2355da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int source_y_fraction) = InterpolateRow_C; 2356da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (!src_yuy2 || 2357da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian !dst_y || !dst_uv || 2358da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian width <= 0 || height == 0) { 2359da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian return -1; 2360da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2361da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Negative height means invert the image. 2362da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height < 0) { 2363da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian height = -height; 2364da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 2365da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_stride_yuy2 = -src_stride_yuy2; 2366da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2367da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_SSE2) 2368da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2369da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_SSE2; 2370da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2371da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_SSE2; 2372da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2373da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2374da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2375da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_AVX2) 2376da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 2377da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_AVX2; 2378da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 2379da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_AVX2; 2380da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2381da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2382da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2383da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_NEON) 2384da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2385da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_NEON; 2386da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2387da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_NEON; 2388da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2389da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2390da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2391da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 2392da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2393da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 2394da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2395da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 2396da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2397da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2398da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2399da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 2400da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 2401da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 2402da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2403da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 2404da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2405da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2406da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2407da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 2408da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 2409da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 2410da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 2411da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 2412da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2413da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2414da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2415da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 2416da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2417da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 2418da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2419da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 2420da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2421da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2422da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2423da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2424da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian { 2425da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int awidth = halfwidth * 2; 2426da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // 2 rows of uv 2427da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian align_buffer_64(rows, awidth * 2); 2428da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2429da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 2430da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Split Y from UV. 2431da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_yuy2, dst_y, rows, awidth); 2432da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, 2433da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian rows + awidth, awidth); 2434da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow(dst_uv, rows, awidth, awidth, 128); 2435da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_yuy2 += src_stride_yuy2 * 2; 2436da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 2437da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_uv += dst_stride_uv; 2438da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2439da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height & 1) { 2440da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Split Y from UV. 2441da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_yuy2, dst_y, dst_uv, width); 2442da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2443da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian free_aligned_buffer_64(rows); 2444da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2445da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian return 0; 2446da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian} 2447da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2448da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh VenkatasubramanianLIBYUV_API 2449da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianint UYVYToNV12(const uint8* src_uyvy, int src_stride_uyvy, 2450da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian uint8* dst_y, int dst_stride_y, 2451da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian uint8* dst_uv, int dst_stride_uv, 2452da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int width, int height) { 2453da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int y; 2454da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int halfwidth = (width + 1) >> 1; 2455da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) = 2456da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow_C; 2457da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, 2458da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian ptrdiff_t src_stride, int dst_width, 2459da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int source_y_fraction) = InterpolateRow_C; 2460da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (!src_uyvy || 2461da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian !dst_y || !dst_uv || 2462da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian width <= 0 || height == 0) { 2463da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian return -1; 2464da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2465da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Negative height means invert the image. 2466da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height < 0) { 2467da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian height = -height; 2468da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 2469da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_stride_uyvy = -src_stride_uyvy; 2470da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2471da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_SSE2) 2472da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2473da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_SSE2; 2474da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2475da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_SSE2; 2476da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2477da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2478da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2479da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_AVX2) 2480da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 2481da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_AVX2; 2482da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 2483da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_AVX2; 2484da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2485da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2486da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2487da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_SPLITUVROW_NEON) 2488da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2489da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_Any_NEON; 2490da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2491da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow = SplitUVRow_NEON; 2492da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2493da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2494da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2495da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSE2) 2496da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSE2)) { 2497da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSE2; 2498da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2499da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSE2; 2500da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2501da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2502da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2503da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_SSSE3) 2504da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasSSSE3)) { 2505da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_SSSE3; 2506da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2507da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_SSSE3; 2508da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2509da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2510da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2511da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_AVX2) 2512da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasAVX2)) { 2513da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_AVX2; 2514da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 32)) { 2515da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_AVX2; 2516da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2517da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2518da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2519da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#if defined(HAS_INTERPOLATEROW_NEON) 2520da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (TestCpuFlag(kCpuHasNEON)) { 2521da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_Any_NEON; 2522da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (IS_ALIGNED(width, 16)) { 2523da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow = InterpolateRow_NEON; 2524da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2525da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2526da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#endif 2527da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2528da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian { 2529da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian int awidth = halfwidth * 2; 2530da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // 2 rows of uv 2531da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian align_buffer_64(rows, awidth * 2); 2532da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2533da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian for (y = 0; y < height - 1; y += 2) { 2534da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Split Y from UV. 2535da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_uyvy, rows, dst_y, awidth); 2536da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_uyvy + src_stride_uyvy, rows + awidth, 2537da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_y + dst_stride_y, awidth); 2538da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian InterpolateRow(dst_uv, rows, awidth, awidth, 128); 2539da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian src_uyvy += src_stride_uyvy * 2; 2540da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_y += dst_stride_y * 2; 2541da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian dst_uv += dst_stride_uv; 2542da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2543da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian if (height & 1) { 2544da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian // Split Y from UV. 2545da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian SplitUVRow(src_uyvy, dst_y, dst_uv, width); 2546da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2547da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian free_aligned_buffer_64(rows); 2548da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian } 2549da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian return 0; 2550da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian} 2551da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian 2552ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#ifdef __cplusplus 2553ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // extern "C" 2554ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} // namespace libyuv 2555ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#endif 2556