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