1c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com/* 2b0c97975894a5eebebf9d93147cdd941a3accb63fbarchard@google.com * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com * 4c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com * Use of this source code is governed by a BSD-style license 5c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com * that can be found in the LICENSE file in the root of the source 6c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com * tree. An additional intellectual property rights grant can be found 7cde587092fef0dbed2c35602f30b79e7b892e766fbarchard@google.com * in the file PATENTS. All contributing project authors may 8c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com * be found in the AUTHORS file in the root of the source tree. 9c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com */ 10c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 11c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#include "libyuv/convert_argb.h" 12c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 13c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#include "libyuv/cpu_id.h" 14c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#include "libyuv/format_conversion.h" 15c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#ifdef HAVE_JPEG 16c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#include "libyuv/mjpeg_decoder.h" 17c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 18c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#include "libyuv/rotate_argb.h" 19142f6c4ed5eaeec0176f255e64bac8d8c70b42e1fbarchard@google.com#include "libyuv/row.h" 20d7c7bfac57ce1775d6424865d8d4ec8b278070bafbarchard@google.com#include "libyuv/video_common.h" 21c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 22c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#ifdef __cplusplus 23c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comnamespace libyuv { 24c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comextern "C" { 25c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 26c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 27c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Copy ARGB with optional flipping 28fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 29c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint ARGBCopy(const uint8* src_argb, int src_stride_argb, 30c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 31c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 3225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_argb || !dst_argb || 33c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com width <= 0 || height == 0) { 34c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return -1; 35c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 36c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 37c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 38c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 39c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_argb = src_argb + (height - 1) * src_stride_argb; 40c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_argb = -src_stride_argb; 41c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 42c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 43c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb, 44c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com width * 4, height); 45c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 46c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 47c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 48c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert I444 to ARGB. 49fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 50c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint I444ToARGB(const uint8* src_y, int src_stride_y, 51c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_u, int src_stride_u, 52c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_v, int src_stride_v, 53c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 54c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 558798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 568798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*I444ToARGBRow)(const uint8* y_buf, 578798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* u_buf, 588798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* v_buf, 598798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 608798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = I444ToARGBRow_C; 6125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_u || !src_v || 6225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_argb || 6325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 64bc81e2dc0547addddfa75c938cf17380fd0980a6fbarchard@google.com return -1; 65bc81e2dc0547addddfa75c938cf17380fd0980a6fbarchard@google.com } 66c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 67c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 68c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 69c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 70c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 71c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 72095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 73518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_y == width && 74518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_u == width && 75518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_v == width && 76518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 77095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 78095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 79095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0; 80518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 81c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_I444TOARGBROW_SSSE3) 82c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 83c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I444ToARGBRow = I444ToARGBRow_Any_SSSE3; 84c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 85c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I444ToARGBRow = I444ToARGBRow_Unaligned_SSSE3; 86c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 87c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I444ToARGBRow = I444ToARGBRow_SSSE3; 88c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 89c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 90c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 91b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com#elif defined(HAS_I444TOARGBROW_NEON) 92b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 93b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com I444ToARGBRow = I444ToARGBRow_Any_NEON; 94b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com if (IS_ALIGNED(width, 8)) { 95b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com I444ToARGBRow = I444ToARGBRow_NEON; 96b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com } 97b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com } 98c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 99c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 1008798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 101c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I444ToARGBRow(src_y, src_u, src_v, dst_argb, width); 102c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 103c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 104c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_u += src_stride_u; 105c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_v += src_stride_v; 106c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 107c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 108c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 109c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 110c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert I422 to ARGB. 111fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 112c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint I422ToARGB(const uint8* src_y, int src_stride_y, 113c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_u, int src_stride_u, 114c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_v, int src_stride_v, 115c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 116c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 1178798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 1188798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*I422ToARGBRow)(const uint8* y_buf, 1198798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* u_buf, 1208798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* v_buf, 1218798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 1228798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = I422ToARGBRow_C; 12325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_u || !src_v || 12425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_argb || 12525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 12625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 12725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 128c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 129c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 130c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 131c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 132c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 133c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 134095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 135518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_y == width && 136518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_u * 2 == width && 137518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_v * 2 == width && 138518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 139095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 140095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 141095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0; 142518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 1438d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com#if defined(HAS_I422TOARGBROW_SSSE3) 144c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 145c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I422ToARGBRow = I422ToARGBRow_Any_SSSE3; 146c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 147c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I422ToARGBRow = I422ToARGBRow_Unaligned_SSSE3; 148c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 149c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I422ToARGBRow = I422ToARGBRow_SSSE3; 150c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 151c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 152c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 153c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#endif 154c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#if defined(HAS_I422TOARGBROW_AVX2) 155c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && width >= 16) { 156c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com I422ToARGBRow = I422ToARGBRow_Any_AVX2; 157c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com if (IS_ALIGNED(width, 16)) { 158c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com I422ToARGBRow = I422ToARGBRow_AVX2; 159c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com } 160c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com } 161c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#endif 162c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#if defined(HAS_I422TOARGBROW_NEON) 1638d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1648d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com I422ToARGBRow = I422ToARGBRow_Any_NEON; 1658d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (IS_ALIGNED(width, 8)) { 1668d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com I422ToARGBRow = I422ToARGBRow_NEON; 1678d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 1688d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 169c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#endif 170c297d103f199dc8c9565ea0f35bdb0832a9d10b8fbarchard@google.com#if defined(HAS_I422TOARGBROW_MIPS_DSPR2) 1716c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) && 1726c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) && 1736c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) && 1746c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) && 1756c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) { 1766c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2; 1776c1b2d38c685e769cf7db2806e27c8ec4c028fe3fbarchard@google.com } 178c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 179c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 1808798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 181c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I422ToARGBRow(src_y, src_u, src_v, dst_argb, width); 182c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 183c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 184c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_u += src_stride_u; 185c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_v += src_stride_v; 186c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 187c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 188c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 189c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 190c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert I411 to ARGB. 191fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 192c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint I411ToARGB(const uint8* src_y, int src_stride_y, 193c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_u, int src_stride_u, 194c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_v, int src_stride_v, 195c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 196c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 1978798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 1988798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*I411ToARGBRow)(const uint8* y_buf, 1998798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* u_buf, 2008798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* v_buf, 2018798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 2028798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = I411ToARGBRow_C; 20325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_u || !src_v || 20425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_argb || 20525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 20625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 20725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 208c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 209c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 210c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 211c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 212c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 213c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 214095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 215518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_y == width && 216518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_u * 4 == width && 217518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com src_stride_v * 4 == width && 218518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 219095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 220095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 221095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0; 222518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 223c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_I411TOARGBROW_SSSE3) 224c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 225c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I411ToARGBRow = I411ToARGBRow_Any_SSSE3; 226c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 227c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I411ToARGBRow = I411ToARGBRow_Unaligned_SSSE3; 228c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 229c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I411ToARGBRow = I411ToARGBRow_SSSE3; 230c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 231c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 232c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 233b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com#elif defined(HAS_I411TOARGBROW_NEON) 234b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 235b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com I411ToARGBRow = I411ToARGBRow_Any_NEON; 236b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com if (IS_ALIGNED(width, 8)) { 237b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com I411ToARGBRow = I411ToARGBRow_NEON; 238b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com } 239b883ce6e2c15627ab9fa95e1bb6eca0dc399d364fbarchard@google.com } 240c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 241c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 2428798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 243c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I411ToARGBRow(src_y, src_u, src_v, dst_argb, width); 244c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 245c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 246c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_u += src_stride_u; 247c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_v += src_stride_v; 248c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 249c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 250c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 251c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 252c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert I400 to ARGB. 253fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 254c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint I400ToARGB_Reference(const uint8* src_y, int src_stride_y, 255c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 256c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 2578798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 2588798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*YToARGBRow)(const uint8* y_buf, 2598798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 2608798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = YToARGBRow_C; 26125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !dst_argb || 26225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 26325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 26425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 265c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 266c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 267c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 268c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 269c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 270c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 271095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 272518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_y == width && 273518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 274095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 275095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 276095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y = dst_stride_argb = 0; 277518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 278c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_YTOARGBROW_SSE2) 2791d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8 && 280c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 2811d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com YToARGBRow = YToARGBRow_Any_SSE2; 2821d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com if (IS_ALIGNED(width, 8)) { 2831d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com YToARGBRow = YToARGBRow_SSE2; 2841d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com } 285c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 28630859f75f28c2435753d33eb7a48ccab169feb6dfbarchard@google.com#elif defined(HAS_YTOARGBROW_NEON) 2871d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 2881d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com YToARGBRow = YToARGBRow_Any_NEON; 2891d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com if (IS_ALIGNED(width, 8)) { 2901d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com YToARGBRow = YToARGBRow_NEON; 2911d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com } 29230859f75f28c2435753d33eb7a48ccab169feb6dfbarchard@google.com } 293c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 294c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 2958798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 296c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com YToARGBRow(src_y, dst_argb, width); 297c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 298c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 299c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 300c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 301c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 302c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 303c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert I400 to ARGB. 304fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 305c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint I400ToARGB(const uint8* src_y, int src_stride_y, 306c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 307c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 3088798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 3098798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*I400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix) = 3108798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com I400ToARGBRow_C; 31125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !dst_argb || 31225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 31325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 31425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 31525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 316c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 317c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 318c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y = src_y + (height - 1) * src_stride_y; 319c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_y = -src_stride_y; 320c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 321095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 322518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_y == width && 323518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 324095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 325095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 326095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y = dst_stride_argb = 0; 327518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 328c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_I400TOARGBROW_SSE2) 32900b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 33000b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com I400ToARGBRow = I400ToARGBRow_Any_SSE2; 33100b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com if (IS_ALIGNED(width, 8)) { 33200b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com I400ToARGBRow = I400ToARGBRow_Unaligned_SSE2; 33300b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 33400b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com I400ToARGBRow = I400ToARGBRow_SSE2; 33500b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com } 33600b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com } 33700b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com } 33800b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com#elif defined(HAS_I400TOARGBROW_NEON) 33900b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 34000b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com I400ToARGBRow = I400ToARGBRow_Any_NEON; 34100b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com if (IS_ALIGNED(width, 8)) { 34200b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com I400ToARGBRow = I400ToARGBRow_NEON; 34300b69a2fe66183be5f72cb80c59f22e137b45359fbarchard@google.com } 344c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 345c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 3468798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 347c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com I400ToARGBRow(src_y, dst_argb, width); 348c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 349c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 350c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 351c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 352c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 353c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 3541096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com// Shuffle table for converting BGRA to ARGB. 355f2aa91a1ac08703d5a22af7fa48c59eba8eb397afbarchard@google.comstatic uvec8 kShuffleMaskBGRAToARGB = { 3561096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u 3571096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com}; 3581096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 3591096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com// Shuffle table for converting ABGR to ARGB. 360f2aa91a1ac08703d5a22af7fa48c59eba8eb397afbarchard@google.comstatic uvec8 kShuffleMaskABGRToARGB = { 3611096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u 3621096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com}; 3631096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 3641096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com// Shuffle table for converting RGBA to ARGB. 365f2aa91a1ac08703d5a22af7fa48c59eba8eb397afbarchard@google.comstatic uvec8 kShuffleMaskRGBAToARGB = { 3661096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u 3671096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com}; 3681096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com 369d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com// Convert BGRA to ARGB. 370fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 371d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.comint BGRAToARGB(const uint8* src_bgra, int src_stride_bgra, 372c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 373c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 3741096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com return ARGBShuffle(src_bgra, src_stride_bgra, 3751096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com dst_argb, dst_stride_argb, 376a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com (const uint8*)(&kShuffleMaskBGRAToARGB), 3771096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com width, height); 378c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 379c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 3802a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com// Convert ARGB to BGRA (same as BGRAToARGB). 3812a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.comLIBYUV_API 3822a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.comint ARGBToBGRA(const uint8* src_bgra, int src_stride_bgra, 3832a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com uint8* dst_argb, int dst_stride_argb, 3842a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com int width, int height) { 3852a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com return ARGBShuffle(src_bgra, src_stride_bgra, 3862a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com dst_argb, dst_stride_argb, 3872a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com (const uint8*)(&kShuffleMaskBGRAToARGB), 3882a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com width, height); 3892a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com} 3902a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com 391d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com// Convert ABGR to ARGB. 392fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 393d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.comint ABGRToARGB(const uint8* src_abgr, int src_stride_abgr, 394c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 395c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 3961096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com return ARGBShuffle(src_abgr, src_stride_abgr, 3971096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com dst_argb, dst_stride_argb, 398a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com (const uint8*)(&kShuffleMaskABGRToARGB), 3991096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com width, height); 400c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 401c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 4022a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com// Convert ARGB to ABGR to (same as ABGRToARGB). 4032a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.comLIBYUV_API 4042a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.comint ARGBToABGR(const uint8* src_abgr, int src_stride_abgr, 4052a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com uint8* dst_argb, int dst_stride_argb, 4062a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com int width, int height) { 4072a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com return ARGBShuffle(src_abgr, src_stride_abgr, 4082a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com dst_argb, dst_stride_argb, 4092a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com (const uint8*)(&kShuffleMaskABGRToARGB), 4102a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com width, height); 4112a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com} 4122a35da39126a2dd3d5725c37e7326eb52521291dfbarchard@google.com 413b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.com// Convert RGBA to ARGB. 414fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 415b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.comint RGBAToARGB(const uint8* src_rgba, int src_stride_rgba, 416b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.com uint8* dst_argb, int dst_stride_argb, 417b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.com int width, int height) { 4181096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com return ARGBShuffle(src_rgba, src_stride_rgba, 4191096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com dst_argb, dst_stride_argb, 420a1f5254a955c5c32484b56822596a4e3368e8eb7fbarchard@google.com (const uint8*)(&kShuffleMaskRGBAToARGB), 4211096543eaa1e596a93ba5d3863e637dc489e32ccfbarchard@google.com width, height); 422b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.com} 423b8eabfea6487a4be3c1497a7ba7c9e2ab2f5f46dfbarchard@google.com 424c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com// Convert RGB24 to ARGB. 425fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 426c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.comint RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24, 427bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 428bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com int width, int height) { 4298798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 4308798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 4318798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com RGB24ToARGBRow_C; 432c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com if (!src_rgb24 || !dst_argb || 43325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 43425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 43525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 43625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 437c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 438c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 439c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; 440c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_stride_rgb24 = -src_stride_rgb24; 441c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 442095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 443518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_rgb24 == width * 3 && 444518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 445095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 446095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 447095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_rgb24 = dst_stride_argb = 0; 448518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 449c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com#if defined(HAS_RGB24TOARGBROW_SSSE3) 450bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 && 451c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 452bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; 453bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 454bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; 455bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 456c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com } 457c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com#elif defined(HAS_RGB24TOARGBROW_NEON) 458bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 459bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_Any_NEON; 460bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 461bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_NEON; 462bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 463c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 464c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 465c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 4668798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 467c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com RGB24ToARGBRow(src_rgb24, dst_argb, width); 468c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_rgb24 += src_stride_rgb24; 469c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 470c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 471c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 472c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 473c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 474c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com// Convert RAW to ARGB. 475fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 476c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.comint RAWToARGB(const uint8* src_raw, int src_stride_raw, 477bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 478bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com int width, int height) { 4798798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 4808798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 4818798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com RAWToARGBRow_C; 482c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com if (!src_raw || !dst_argb || 48325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 48425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 48525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 48625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 487c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 488c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 489c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_raw = src_raw + (height - 1) * src_stride_raw; 490c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_stride_raw = -src_stride_raw; 491c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 492095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 493518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_raw == width * 3 && 494518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 495095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 496095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 497095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_raw = dst_stride_argb = 0; 498518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 499c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com#if defined(HAS_RAWTOARGBROW_SSSE3) 500bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 && 501c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 502bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_Any_SSSE3; 503bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 504bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_SSSE3; 505bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 506c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com } 507c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com#elif defined(HAS_RAWTOARGBROW_NEON) 508bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 509bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_Any_NEON; 510bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 511bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_NEON; 512bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 513c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 514c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 515c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 5168798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 517c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com RAWToARGBRow(src_raw, dst_argb, width); 518c7277d08e8d33d470b0f4a5e9c3c58f5f250f114fbarchard@google.com src_raw += src_stride_raw; 519c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 520c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 521c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 522c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 523c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 524c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert RGB565 to ARGB. 525fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 526c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint RGB565ToARGB(const uint8* src_rgb565, int src_stride_rgb565, 527c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 528c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 5298798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 5308798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int pix) = 5318798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com RGB565ToARGBRow_C; 53225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_rgb565 || !dst_argb || 53325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 53425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 53525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 53625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 537c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 538c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 539c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; 540c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_rgb565 = -src_stride_rgb565; 541c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 542095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 543518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_rgb565 == width * 2 && 544518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 545095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 546095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 547095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_rgb565 = dst_stride_argb = 0; 548518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 549c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_RGB565TOARGBROW_SSE2) 550bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8 && 551c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 552bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; 553bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 554bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_SSE2; 555bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 556bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 557bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#elif defined(HAS_RGB565TOARGBROW_NEON) 558bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 559bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_Any_NEON; 560bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 561bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_NEON; 562bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 563c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 564c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 565c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 5668798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 567c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com RGB565ToARGBRow(src_rgb565, dst_argb, width); 568c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_rgb565 += src_stride_rgb565; 569c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 570c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 571c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 572c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 573c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 574c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert ARGB1555 to ARGB. 575fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 576c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint ARGB1555ToARGB(const uint8* src_argb1555, int src_stride_argb1555, 577c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 578c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 5798798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 5808798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*ARGB1555ToARGBRow)(const uint8* src_argb1555, uint8* dst_argb, 5818798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int pix) = ARGB1555ToARGBRow_C; 58225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_argb1555 || !dst_argb || 5834b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com width <= 0 || height == 0) { 58425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 58525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 58625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 587c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 588c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 589c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; 590c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_argb1555 = -src_stride_argb1555; 591c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 592095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 593518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_argb1555 == width * 2 && 594518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 595095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 596095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 597095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_argb1555 = dst_stride_argb = 0; 598518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 599c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_ARGB1555TOARGBROW_SSE2) 6004b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8 && 601c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 6024b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; 6034b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (IS_ALIGNED(width, 8)) { 6044b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; 6054b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 6064b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 6074b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com#elif defined(HAS_ARGB1555TOARGBROW_NEON) 6084b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 6094b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_NEON; 6104b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (IS_ALIGNED(width, 8)) { 6114b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_NEON; 6124b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 613c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 614c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 615c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 6168798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 617c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com ARGB1555ToARGBRow(src_argb1555, dst_argb, width); 618c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_argb1555 += src_stride_argb1555; 619c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 620c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 621c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 622c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 623c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 624c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert ARGB4444 to ARGB. 625fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 626c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint ARGB4444ToARGB(const uint8* src_argb4444, int src_stride_argb4444, 627c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 628c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 6298798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 6308798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*ARGB4444ToARGBRow)(const uint8* src_argb4444, uint8* dst_argb, 6318798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int pix) = ARGB4444ToARGBRow_C; 63225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_argb4444 || !dst_argb || 63325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 63425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 63525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 63625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 637c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 638c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 639c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; 640c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_argb4444 = -src_stride_argb4444; 641c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 642095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 643518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com if (src_stride_argb4444 == width * 2 && 644518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 645095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 646095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 647095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_argb4444 = dst_stride_argb = 0; 648518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 649c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_ARGB4444TOARGBROW_SSE2) 6504b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8 && 651c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 6524b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; 6534b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (IS_ALIGNED(width, 8)) { 6544b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; 6554b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 6564b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 6574b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com#elif defined(HAS_ARGB4444TOARGBROW_NEON) 6584b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 6594b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_NEON; 6604b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com if (IS_ALIGNED(width, 8)) { 6614b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_NEON; 6624b4a32cb17596321ccee7ba3179bcd3ad6e2c81efbarchard@google.com } 663c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 664c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 665c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 6668798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 667c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com ARGB4444ToARGBRow(src_argb4444, dst_argb, width); 668c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_argb4444 += src_stride_argb4444; 669c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 670c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 671c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 672c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 673c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 674c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert NV12 to ARGB. 675fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 676c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint NV12ToARGB(const uint8* src_y, int src_stride_y, 677c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com const uint8* src_uv, int src_stride_uv, 678c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 679c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 6808798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 6818798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*NV12ToARGBRow)(const uint8* y_buf, 6828798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* uv_buf, 6838798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 6848798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = NV12ToARGBRow_C; 68525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_uv || !dst_argb || 68625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 68725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 68825ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 689c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 690c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 691c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 692c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 693c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 694c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 695c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_NV12TOARGBROW_SSSE3) 696c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 697c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3; 698c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 699c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Unaligned_SSSE3; 700c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 701c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_SSSE3; 702c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 703c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 704c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 70515449263c4bba75bc396dc3d60266efee6ab6c66fbarchard@google.com#elif defined(HAS_NV12TOARGBROW_NEON) 70664ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 70764ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Any_NEON; 70864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (IS_ALIGNED(width, 8)) { 70964ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_NEON; 71064ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 71164ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 71264ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com#endif 713c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 7148798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 715c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow(src_y, src_uv, dst_argb, width); 716c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 717c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 718c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (y & 1) { 719c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_uv += src_stride_uv; 720c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 721c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 722c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 723c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 724c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 725c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert NV21 to ARGB. 726fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 727c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint NV21ToARGB(const uint8* src_y, int src_stride_y, 72864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com const uint8* src_uv, int src_stride_uv, 729c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 730c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 7318798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 7328798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*NV21ToARGBRow)(const uint8* y_buf, 7338798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* uv_buf, 7348798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 7358798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = NV21ToARGBRow_C; 73664ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (!src_y || !src_uv || !dst_argb || 73725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 73825ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 73925ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 740c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 741c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 742c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 743c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 744c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 745c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 746c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_NV21TOARGBROW_SSSE3) 747c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 748c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV21ToARGBRow = NV21ToARGBRow_Any_SSSE3; 749c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 750c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV21ToARGBRow = NV21ToARGBRow_Unaligned_SSSE3; 751c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 752c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV21ToARGBRow = NV21ToARGBRow_SSSE3; 753c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 754c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 755c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 756c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 75764ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com#if defined(HAS_NV21TOARGBROW_NEON) 75864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 75964ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com NV21ToARGBRow = NV21ToARGBRow_Any_NEON; 76064ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com if (IS_ALIGNED(width, 8)) { 76164ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com NV21ToARGBRow = NV21ToARGBRow_NEON; 76264ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 76364ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com } 76464ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com#endif 765c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 7668798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 76764ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com NV21ToARGBRow(src_y, src_uv, dst_argb, width); 768c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 769c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_y += src_stride_y; 770c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (y & 1) { 77164ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com src_uv += src_stride_uv; 772c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 773c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 774c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 775c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 776c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 777c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert M420 to ARGB. 778fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 779c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint M420ToARGB(const uint8* src_m420, int src_stride_m420, 780c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 781c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 7828798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 7838798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*NV12ToARGBRow)(const uint8* y_buf, 7848798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com const uint8* uv_buf, 7858798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* rgb_buf, 7868798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width) = NV12ToARGBRow_C; 78725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_m420 || !dst_argb || 78825ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 78925ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 79025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 791c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 792c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 793c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 794c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb = dst_argb + (height - 1) * dst_stride_argb; 795c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_stride_argb = -dst_stride_argb; 796c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 797c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#if defined(HAS_NV12TOARGBROW_SSSE3) 798c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) { 799c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3; 800c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(width, 8)) { 801c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Unaligned_SSSE3; 802c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 803c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_SSSE3; 804c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 805c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 806c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 807fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com#elif defined(HAS_NV12TOARGBROW_NEON) 808fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 809fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_Any_NEON; 810fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com if (IS_ALIGNED(width, 8)) { 811fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com NV12ToARGBRow = NV12ToARGBRow_NEON; 812fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com } 813fe44ff67817a50ec50987c369558467696ab08f3fbarchard@google.com } 814c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 815c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 8168798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height - 1; y += 2) { 817c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width); 818c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2, 819c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb + dst_stride_argb, width); 820c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb * 2; 821c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_m420 += src_stride_m420 * 3; 822c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 823c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height & 1) { 824c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width); 825c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 826c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 827c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 828c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 829c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert YUY2 to ARGB. 830fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 831c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2, 832c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 833c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 8348798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 8358798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb, int pix) = 8368798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com YUY2ToARGBRow_C; 83725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_yuy2 || !dst_argb || 83825ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 83925ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 84025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 841c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 842c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 843c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 844c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 845c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_yuy2 = -src_stride_yuy2; 846c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 847095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 848d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com if (src_stride_yuy2 == width * 2 && 849518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 850095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 851095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 852095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_yuy2 = dst_stride_argb = 0; 853518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 854793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com#if defined(HAS_YUY2TOARGBROW_SSSE3) 855735f9921e912e3c19846f01143d3978b47b02aa6fbarchard@google.com // Posix is 16, Windows is 8. 856d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 857793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3; 858f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (IS_ALIGNED(width, 16)) { 859793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow = YUY2ToARGBRow_Unaligned_SSSE3; 860d8427fd50a65f99376420ecfc8e4dd6781ea843cfbarchard@google.com if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16) && 8616784e4b4140e7e59bf73208f5a6565f7af6408affbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 862793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow = YUY2ToARGBRow_SSSE3; 8638d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 8648d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 8658d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 866793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com#elif defined(HAS_YUY2TOARGBROW_NEON) 8678d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 868793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON; 8698d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (IS_ALIGNED(width, 8)) { 870793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow = YUY2ToARGBRow_NEON; 871c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 872c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 873c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 8748798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 875793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com YUY2ToARGBRow(src_yuy2, dst_argb, width); 876c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_yuy2 += src_stride_yuy2; 877c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 878c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 879c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 880c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 881c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 882c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com// Convert UYVY to ARGB. 883fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 884c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.comint UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy, 885c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com uint8* dst_argb, int dst_stride_argb, 886c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com int width, int height) { 8878798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int y; 8888798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb, int pix) = 8898798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com UYVYToARGBRow_C; 89025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_uyvy || !dst_argb || 89125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 89225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 89325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 894c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com // Negative height means invert the image. 895c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com if (height < 0) { 896c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com height = -height; 897c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 898c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_stride_uyvy = -src_stride_uyvy; 899c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 900095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 901d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com if (src_stride_uyvy == width * 2 && 902518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com dst_stride_argb == width * 4) { 903095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 904095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com height = 1; 905095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_uyvy = dst_stride_argb = 0; 906518833b9833a52b715b487445e6ccfe4f8881903fbarchard@google.com } 907793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com#if defined(HAS_UYVYTOARGBROW_SSSE3) 908735f9921e912e3c19846f01143d3978b47b02aa6fbarchard@google.com // Posix is 16, Windows is 8. 909d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 910793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow = UYVYToARGBRow_Any_SSSE3; 911f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (IS_ALIGNED(width, 16)) { 912793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow = UYVYToARGBRow_Unaligned_SSSE3; 913d8427fd50a65f99376420ecfc8e4dd6781ea843cfbarchard@google.com if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16) && 9146784e4b4140e7e59bf73208f5a6565f7af6408affbarchard@google.com IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) { 915793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow = UYVYToARGBRow_SSSE3; 9168d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 9178d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 9188d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com } 919793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com#elif defined(HAS_UYVYTOARGBROW_NEON) 9208d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 921793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow = UYVYToARGBRow_Any_NEON; 9228d37dd5c205216e0ad13c5091061908cb981c5f9fbarchard@google.com if (IS_ALIGNED(width, 8)) { 923793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow = UYVYToARGBRow_NEON; 924c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 925c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 926c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 9278798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com for (y = 0; y < height; ++y) { 928793e5a06ffe55a911f8aa3f4731ae681039952bcfbarchard@google.com UYVYToARGBRow(src_uyvy, dst_argb, width); 929c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com src_uyvy += src_stride_uyvy; 930c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com dst_argb += dst_stride_argb; 931c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com } 932c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com return 0; 933c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} 934c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com 935c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#ifdef __cplusplus 936c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} // extern "C" 937c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com} // namespace libyuv 938c4500c9f7957f24021250a056f099300aa6f0476fbarchard@google.com#endif 939