141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org/*
241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *
441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  Use of this source code is governed by a BSD-style license
541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  that can be found in the LICENSE file in the root of the source
641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  tree. An additional intellectual property rights grant can be found
741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  in the file PATENTS. All contributing project authors may
841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *  be found in the AUTHORS file in the root of the source tree.
941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org */
1041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
1141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/rotate.h"
1241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
1341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/cpu_id.h"
1441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/convert.h"
1541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/planar_functions.h"
1641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#include "libyuv/row.h"
1741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
1841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus
1941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgnamespace libyuv {
2041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgextern "C" {
2141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
2241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
2341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if !defined(LIBYUV_DISABLE_X86) && \
2441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    (defined(_M_IX86) || defined(__x86_64__) || defined(__i386__))
2541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(__APPLE__) && defined(__i386__)
2641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define DECLARE_FUNCTION(name)                                                 \
2741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".text                                     \n"                             \
2841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".private_extern _" #name "                \n"                             \
2941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".align 4,0x90                             \n"                             \
3041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org"_" #name ":                                   \n"
3141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif defined(__MINGW32__) || defined(__CYGWIN__) && defined(__i386__)
3241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define DECLARE_FUNCTION(name)                                                 \
3341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".text                                     \n"                             \
3441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".align 4,0x90                             \n"                             \
3541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org"_" #name ":                                   \n"
3641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#else
3741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define DECLARE_FUNCTION(name)                                                 \
3841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".text                                     \n"                             \
3941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".align 4,0x90                             \n"                             \
4041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#name ":                                       \n"
4141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
4241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
4341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
4441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \
4541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    (defined(__ARM_NEON__) || defined(LIBYUV_NEON))
4641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_MIRRORROW_NEON
4741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid MirrorRow_NEON(const uint8* src, uint8* dst, int width);
4841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_MIRRORROW_UV_NEON
4941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid MirrorUVRow_NEON(const uint8* src, uint8* dst_a, uint8* dst_b, int width);
5041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_WX8_NEON
5141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeWx8_NEON(const uint8* src, int src_stride,
5241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                       uint8* dst, int dst_stride, int width);
5341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_UVWX8_NEON
5441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeUVWx8_NEON(const uint8* src, int src_stride,
5541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_a, int dst_stride_a,
5641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_b, int dst_stride_b,
5741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         int width);
5841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif  // defined(__ARM_NEON__)
5941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
6041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if !defined(LIBYUV_DISABLE_MIPS) && !defined(__native_client__) && \
6141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    defined(__mips__) && \
6241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    defined(__mips_dsp) && (__mips_dsp_rev >= 2)
6341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_WX8_MIPS_DSPR2
6441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeWx8_MIPS_DSPR2(const uint8* src, int src_stride,
6541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             uint8* dst, int dst_stride, int width);
6641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
6741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeWx8_FAST_MIPS_DSPR2(const uint8* src, int src_stride,
6841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                  uint8* dst, int dst_stride, int width);
6941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_UVWx8_MIPS_DSPR2
7041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeUVWx8_MIPS_DSPR2(const uint8* src, int src_stride,
7141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                               uint8* dst_a, int dst_stride_a,
7241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                               uint8* dst_b, int dst_stride_b,
7341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                               int width);
7441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif  // defined(__mips__)
7541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
7641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if !defined(LIBYUV_DISABLE_X86) && \
7741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    defined(_M_IX86) && defined(_MSC_VER)
7841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_WX8_SSSE3
7941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org__declspec(naked) __declspec(align(16))
8041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeWx8_SSSE3(const uint8* src, int src_stride,
8141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                               uint8* dst, int dst_stride, int width) {
8241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  __asm {
8341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      edi
8441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      esi
8541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      ebp
8641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       eax, [esp + 12 + 4]   // src
8741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       edi, [esp + 12 + 8]   // src_stride
8841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       edx, [esp + 12 + 12]  // dst
8941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       esi, [esp + 12 + 16]  // dst_stride
9041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       ecx, [esp + 12 + 20]  // width
9141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
9241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Read in the data from the source pointer.
9341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // First round of bit swap.
9441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    align      4
9541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org convertloop:
9641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm0, qword ptr [eax]
9741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       ebp, [eax + 8]
9841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm1, qword ptr [eax + edi]
9941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
10041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm0, xmm1
10141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm2, qword ptr [eax]
10241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm1, xmm0
10341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm1, xmm1, 8
10441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm3, qword ptr [eax + edi]
10541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
10641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm2, xmm3
10741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm3, xmm2
10841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm4, qword ptr [eax]
10941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm3, xmm3, 8
11041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm5, qword ptr [eax + edi]
11141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm4, xmm5
11241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
11341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm4
11441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm6, qword ptr [eax]
11541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm5, xmm5, 8
11641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      xmm7, qword ptr [eax + edi]
11741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm6, xmm7
11841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       eax, ebp
11941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm6
12041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm7, xmm7, 8
12141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Second round of bit swap.
12241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm0, xmm2
12341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm1, xmm3
12441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm2, xmm0
12541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm3, xmm1
12641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm2, xmm2, 8
12741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm3, xmm3, 8
12841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm4, xmm6
12941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm5, xmm7
13041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, xmm4
13141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm5
13241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm6, xmm6, 8
13341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm7, xmm7, 8
13441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Third round of bit swap.
13541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Write to the destination pointer.
13641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm0, xmm4
13741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx], xmm0
13841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm4, xmm0
13941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm4, xmm4, 8
14041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx + esi], xmm4
14141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
14241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm2, xmm6
14341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, xmm2
14441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm6, xmm6, 8
14541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx], xmm2
14641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm1, xmm5
14741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx + esi], xmm6
14841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
14941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm1
15041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx], xmm1
15141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm5, xmm5, 8
15241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm3, xmm7
15341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx + esi], xmm5
15441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
15541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx], xmm3
15641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm3
15741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    palignr   xmm7, xmm7, 8
15841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    sub       ecx, 8
15941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movq      qword ptr [edx + esi], xmm7
16041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
16141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    jg        convertloop
16241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
16341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       ebp
16441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       esi
16541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       edi
16641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ret
16741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
16841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
16941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
17041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_UVWX8_SSE2
17141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org__declspec(naked) __declspec(align(16))
17241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeUVWx8_SSE2(const uint8* src, int src_stride,
17341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                uint8* dst_a, int dst_stride_a,
17441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                uint8* dst_b, int dst_stride_b,
17541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                int w) {
17641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  __asm {
17741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      ebx
17841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      esi
17941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      edi
18041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    push      ebp
18141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       eax, [esp + 16 + 4]   // src
18241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       edi, [esp + 16 + 8]   // src_stride
18341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       edx, [esp + 16 + 12]  // dst_a
18441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       esi, [esp + 16 + 16]  // dst_stride_a
18541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       ebx, [esp + 16 + 20]  // dst_b
18641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       ebp, [esp + 16 + 24]  // dst_stride_b
18741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       ecx, esp
18841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    sub       esp, 4 + 16
18941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    and       esp, ~15
19041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       [esp + 16], ecx
19141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       ecx, [ecx + 16 + 28]  // w
19241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
19341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    align      4
19441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org convertloop:
19541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Read in the data from the source pointer.
19641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // First round of bit swap.
19741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm0, [eax]
19841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm1, [eax + edi]
19941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
20041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm0  // use xmm7 as temp register.
20141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm0, xmm1
20241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhbw xmm7, xmm1
20341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm1, xmm7
20441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm2, [eax]
20541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm3, [eax + edi]
20641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
20741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm2
20841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm2, xmm3
20941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhbw xmm7, xmm3
21041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm3, xmm7
21141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm4, [eax]
21241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, [eax + edi]
21341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
21441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm4
21541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm4, xmm5
21641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhbw xmm7, xmm5
21741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm7
21841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, [eax]
21941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, [eax + edi]
22041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 2 * edi]
22141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    [esp], xmm5  // backup xmm5
22241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    neg       edi
22341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm6   // use xmm5 as temp register.
22441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklbw xmm6, xmm7
22541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhbw xmm5, xmm7
22641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm5
22741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       eax, [eax + 8 * edi + 16]
22841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    neg       edi
22941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Second round of bit swap.
23041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm0
23141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm0, xmm2
23241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhwd xmm5, xmm2
23341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm2, xmm5
23441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm1
23541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm1, xmm3
23641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhwd xmm5, xmm3
23741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm3, xmm5
23841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, xmm4
23941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm4, xmm6
24041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhwd xmm5, xmm6
24141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, xmm5
24241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm5, [esp]  // restore xmm5
24341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    [esp], xmm6  // backup xmm6
24441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, xmm5    // use xmm6 as temp register.
24541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpcklwd xmm5, xmm7
24641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhwd xmm6, xmm7
24741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm7, xmm6
24841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Third round of bit swap.
24941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Write to the destination pointer.
25041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, xmm0
25141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm0, xmm4
25241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhdq xmm6, xmm4
25341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm4, xmm6
25441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm6, [esp]  // restore xmm6
25541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx], xmm0
25641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx], xmm0
25741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx + esi], xmm4
25841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
25941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx + ebp], xmm4
26041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       ebx, [ebx + 2 * ebp]
26141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm0, xmm2   // use xmm0 as the temp register.
26241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm2, xmm6
26341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx], xmm2
26441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx], xmm2
26541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhdq xmm0, xmm6
26641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx + esi], xmm0
26741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
26841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx + ebp], xmm0
26941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       ebx, [ebx + 2 * ebp]
27041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm0, xmm1   // use xmm0 as the temp register.
27141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm1, xmm5
27241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx], xmm1
27341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx], xmm1
27441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhdq xmm0, xmm5
27541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx + esi], xmm0
27641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
27741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx + ebp], xmm0
27841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       ebx, [ebx + 2 * ebp]
27941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movdqa    xmm0, xmm3   // use xmm0 as the temp register.
28041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckldq xmm3, xmm7
28141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx], xmm3
28241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx], xmm3
28341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    punpckhdq xmm0, xmm7
28441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    sub       ecx, 8
28541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movlpd    qword ptr [edx + esi], xmm0
28641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       edx, [edx + 2 * esi]
28741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    movhpd    qword ptr [ebx + ebp], xmm0
28841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    lea       ebx, [ebx + 2 * ebp]
28941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    jg        convertloop
29041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
29141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    mov       esp, [esp + 16]
29241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       ebp
29341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       edi
29441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       esi
29541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    pop       ebx
29641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ret
29741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
29841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
29941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif !defined(LIBYUV_DISABLE_X86) && \
30041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    (defined(__i386__) || (defined(__x86_64__) && !defined(__native_client__)))
30141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_WX8_SSSE3
30241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeWx8_SSSE3(const uint8* src, int src_stride,
30341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                               uint8* dst, int dst_stride, int width) {
30441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  asm volatile (
30541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Read in the data from the source pointer.
30641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // First round of bit swap.
30741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ".p2align  2                                 \n"
30841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "1:                                            \n"
30941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0),%%xmm0                      \n"
31041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0,%3),%%xmm1                   \n"
31141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%0,%3,2),%0                     \n"
31241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw  %%xmm1,%%xmm0                    \n"
31341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0),%%xmm2                      \n"
31441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm0,%%xmm1                    \n"
31541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm1,%%xmm1               \n"
31641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0,%3),%%xmm3                   \n"
31741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%0,%3,2),%0                     \n"
31841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw  %%xmm3,%%xmm2                    \n"
31941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm2,%%xmm3                    \n"
32041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0),%%xmm4                      \n"
32141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm3,%%xmm3               \n"
32241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0,%3),%%xmm5                   \n"
32341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%0,%3,2),%0                     \n"
32441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw  %%xmm5,%%xmm4                    \n"
32541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm4,%%xmm5                    \n"
32641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0),%%xmm6                      \n"
32741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm5,%%xmm5               \n"
32841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       (%0,%3),%%xmm7                   \n"
32941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%0,%3,2),%0                     \n"
33041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw  %%xmm7,%%xmm6                    \n"
33141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "neg        %3                               \n"
33241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm6,%%xmm7                    \n"
33341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        0x8(%0,%3,8),%0                  \n"
33441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm7,%%xmm7               \n"
33541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "neg        %3                               \n"
33641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org     // Second round of bit swap.
33741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd  %%xmm2,%%xmm0                    \n"
33841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd  %%xmm3,%%xmm1                    \n"
33941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm0,%%xmm2                    \n"
34041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm1,%%xmm3                    \n"
34141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm2,%%xmm2               \n"
34241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm3,%%xmm3               \n"
34341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd  %%xmm6,%%xmm4                    \n"
34441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd  %%xmm7,%%xmm5                    \n"
34541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm4,%%xmm6                    \n"
34641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm5,%%xmm7                    \n"
34741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm6,%%xmm6               \n"
34841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm7,%%xmm7               \n"
34941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Third round of bit swap.
35041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    // Write to the destination pointer.
35141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq  %%xmm4,%%xmm0                    \n"
35241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm0,(%1)                      \n"
35341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm0,%%xmm4                    \n"
35441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm4,%%xmm4               \n"
35541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm4,(%1,%4)                   \n"
35641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%1,%4,2),%1                     \n"
35741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq  %%xmm6,%%xmm2                    \n"
35841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm2,%%xmm6                    \n"
35941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm2,(%1)                      \n"
36041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm6,%%xmm6               \n"
36141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq  %%xmm5,%%xmm1                    \n"
36241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm6,(%1,%4)                   \n"
36341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%1,%4,2),%1                     \n"
36441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm1,%%xmm5                    \n"
36541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm1,(%1)                      \n"
36641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm5,%%xmm5               \n"
36741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm5,(%1,%4)                   \n"
36841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%1,%4,2),%1                     \n"
36941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq  %%xmm7,%%xmm3                    \n"
37041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm3,(%1)                      \n"
37141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa     %%xmm3,%%xmm7                    \n"
37241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "palignr    $0x8,%%xmm7,%%xmm7               \n"
37341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "sub        $0x8,%2                          \n"
37441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movq       %%xmm7,(%1,%4)                   \n"
37541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea        (%1,%4,2),%1                     \n"
37641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "jg         1b                               \n"
37741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    : "+r"(src),    // %0
37841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      "+r"(dst),    // %1
37941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      "+r"(width)   // %2
38041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    : "r"((intptr_t)(src_stride)),  // %3
38141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      "r"((intptr_t)(dst_stride))   // %4
38241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    : "memory", "cc"
38341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  #if defined(__SSE2__)
38441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      , "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
38541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  #endif
38641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  );
38741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
38841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
38941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if !defined(LIBYUV_DISABLE_X86) && defined(__i386__)
39041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_UVWX8_SSE2
39141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeUVWx8_SSE2(const uint8* src, int src_stride,
39241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_a, int dst_stride_a,
39341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_b, int dst_stride_b,
39441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         int w);
39541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  asm (
39641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    DECLARE_FUNCTION(TransposeUVWx8_SSE2)
39741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "push   %ebx                               \n"
39841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "push   %esi                               \n"
39941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "push   %edi                               \n"
40041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "push   %ebp                               \n"
40141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x14(%esp),%eax                    \n"
40241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x18(%esp),%edi                    \n"
40341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x1c(%esp),%edx                    \n"
40441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x20(%esp),%esi                    \n"
40541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x24(%esp),%ebx                    \n"
40641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x28(%esp),%ebp                    \n"
40741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    %esp,%ecx                          \n"
40841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "sub    $0x14,%esp                         \n"
40941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "and    $0xfffffff0,%esp                   \n"
41041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    %ecx,0x10(%esp)                    \n"
41141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x2c(%ecx),%ecx                    \n"
41241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
41341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org"1:                                            \n"
41441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax),%xmm0                       \n"
41541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax,%edi,1),%xmm1                \n"
41641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%eax,%edi,2),%eax                 \n"
41741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm0,%xmm7                        \n"
41841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw %xmm1,%xmm0                     \n"
41941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhbw %xmm1,%xmm7                     \n"
42041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm7,%xmm1                        \n"
42141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax),%xmm2                       \n"
42241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax,%edi,1),%xmm3                \n"
42341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%eax,%edi,2),%eax                 \n"
42441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm2,%xmm7                        \n"
42541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw %xmm3,%xmm2                     \n"
42641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhbw %xmm3,%xmm7                     \n"
42741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm7,%xmm3                        \n"
42841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax),%xmm4                       \n"
42941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax,%edi,1),%xmm5                \n"
43041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%eax,%edi,2),%eax                 \n"
43141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm4,%xmm7                        \n"
43241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw %xmm5,%xmm4                     \n"
43341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhbw %xmm5,%xmm7                     \n"
43441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm7,%xmm5                        \n"
43541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax),%xmm6                       \n"
43641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%eax,%edi,1),%xmm7                \n"
43741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%eax,%edi,2),%eax                 \n"
43841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,(%esp)                       \n"
43941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "neg    %edi                               \n"
44041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm6,%xmm5                        \n"
44141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklbw %xmm7,%xmm6                     \n"
44241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhbw %xmm7,%xmm5                     \n"
44341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,%xmm7                        \n"
44441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    0x10(%eax,%edi,8),%eax             \n"
44541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "neg    %edi                               \n"
44641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm0,%xmm5                        \n"
44741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd %xmm2,%xmm0                     \n"
44841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhwd %xmm2,%xmm5                     \n"
44941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,%xmm2                        \n"
45041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm1,%xmm5                        \n"
45141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd %xmm3,%xmm1                     \n"
45241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhwd %xmm3,%xmm5                     \n"
45341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,%xmm3                        \n"
45441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm4,%xmm5                        \n"
45541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd %xmm6,%xmm4                     \n"
45641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhwd %xmm6,%xmm5                     \n"
45741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,%xmm6                        \n"
45841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%esp),%xmm5                       \n"
45941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm6,(%esp)                       \n"
46041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm5,%xmm6                        \n"
46141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpcklwd %xmm7,%xmm5                     \n"
46241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhwd %xmm7,%xmm6                     \n"
46341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm6,%xmm7                        \n"
46441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm0,%xmm6                        \n"
46541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq %xmm4,%xmm0                     \n"
46641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhdq %xmm4,%xmm6                     \n"
46741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm6,%xmm4                        \n"
46841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa (%esp),%xmm6                       \n"
46941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm0,(%edx)                       \n"
47041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm0,(%ebx)                       \n"
47141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm4,(%edx,%esi,1)                \n"
47241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%edx,%esi,2),%edx                 \n"
47341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm4,(%ebx,%ebp,1)                \n"
47441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%ebx,%ebp,2),%ebx                 \n"
47541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm2,%xmm0                        \n"
47641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq %xmm6,%xmm2                     \n"
47741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm2,(%edx)                       \n"
47841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm2,(%ebx)                       \n"
47941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhdq %xmm6,%xmm0                     \n"
48041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm0,(%edx,%esi,1)                \n"
48141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%edx,%esi,2),%edx                 \n"
48241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm0,(%ebx,%ebp,1)                \n"
48341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%ebx,%ebp,2),%ebx                 \n"
48441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm1,%xmm0                        \n"
48541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq %xmm5,%xmm1                     \n"
48641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm1,(%edx)                       \n"
48741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm1,(%ebx)                       \n"
48841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhdq %xmm5,%xmm0                     \n"
48941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm0,(%edx,%esi,1)                \n"
49041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%edx,%esi,2),%edx                 \n"
49141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm0,(%ebx,%ebp,1)                \n"
49241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%ebx,%ebp,2),%ebx                 \n"
49341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movdqa %xmm3,%xmm0                        \n"
49441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckldq %xmm7,%xmm3                     \n"
49541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm3,(%edx)                       \n"
49641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm3,(%ebx)                       \n"
49741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "punpckhdq %xmm7,%xmm0                     \n"
49841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "sub    $0x8,%ecx                          \n"
49941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movlpd %xmm0,(%edx,%esi,1)                \n"
50041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%edx,%esi,2),%edx                 \n"
50141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "movhpd %xmm0,(%ebx,%ebp,1)                \n"
50241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "lea    (%ebx,%ebp,2),%ebx                 \n"
50341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "jg     1b                                 \n"
50441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "mov    0x10(%esp),%esp                    \n"
50541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "pop    %ebp                               \n"
50641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "pop    %edi                               \n"
50741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "pop    %esi                               \n"
50841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "pop    %ebx                               \n"
50941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(__native_client__)
51041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "pop    %ecx                               \n"
51141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "and    $0xffffffe0,%ecx                   \n"
51241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "jmp    *%ecx                              \n"
51341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#else
51441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "ret                                       \n"
51541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
51641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org);
51741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif !defined(LIBYUV_DISABLE_X86) && !defined(__native_client__) && \
51841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    defined(__x86_64__)
51941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// 64 bit version has enough registers to do 16x8 to 8x16 at a time.
52041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_WX8_FAST_SSSE3
52141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeWx8_FAST_SSSE3(const uint8* src, int src_stride,
52241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                    uint8* dst, int dst_stride, int width) {
52341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  asm volatile (
52441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Read in the data from the source pointer.
52541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // First round of bit swap.
52641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  ".p2align  2                                 \n"
52741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org"1:                                            \n"
52841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm0                      \n"
52941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%3),%%xmm1                   \n"
53041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%3,2),%0                     \n"
53141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm8                    \n"
53241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm1,%%xmm0                    \n"
53341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm1,%%xmm8                    \n"
53441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm2                      \n"
53541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm1                    \n"
53641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm9                    \n"
53741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm1,%%xmm1               \n"
53841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm9,%%xmm9               \n"
53941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%3),%%xmm3                   \n"
54041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%3,2),%0                     \n"
54141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm2,%%xmm10                   \n"
54241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm3,%%xmm2                    \n"
54341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm3,%%xmm10                   \n"
54441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm2,%%xmm3                    \n"
54541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm10,%%xmm11                  \n"
54641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm4                      \n"
54741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm3,%%xmm3               \n"
54841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm11,%%xmm11             \n"
54941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%3),%%xmm5                   \n"
55041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%3,2),%0                     \n"
55141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm4,%%xmm12                   \n"
55241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm5,%%xmm4                    \n"
55341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm5,%%xmm12                   \n"
55441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm4,%%xmm5                    \n"
55541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm12,%%xmm13                  \n"
55641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm6                      \n"
55741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm5,%%xmm5               \n"
55841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm13,%%xmm13             \n"
55941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%3),%%xmm7                   \n"
56041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%3,2),%0                     \n"
56141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm6,%%xmm14                   \n"
56241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm7,%%xmm6                    \n"
56341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm7,%%xmm14                   \n"
56441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "neg        %3                               \n"
56541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm6,%%xmm7                    \n"
56641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm14,%%xmm15                  \n"
56741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        0x10(%0,%3,8),%0                 \n"
56841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm7,%%xmm7               \n"
56941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm15,%%xmm15             \n"
57041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "neg        %3                               \n"
57141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org   // Second round of bit swap.
57241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm2,%%xmm0                    \n"
57341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm3,%%xmm1                    \n"
57441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm2                    \n"
57541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm1,%%xmm3                    \n"
57641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm2,%%xmm2               \n"
57741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm3,%%xmm3               \n"
57841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm6,%%xmm4                    \n"
57941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm7,%%xmm5                    \n"
58041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm4,%%xmm6                    \n"
58141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm5,%%xmm7                    \n"
58241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm6,%%xmm6               \n"
58341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm7,%%xmm7               \n"
58441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm10,%%xmm8                   \n"
58541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm11,%%xmm9                   \n"
58641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm10                   \n"
58741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm9,%%xmm11                   \n"
58841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm10,%%xmm10             \n"
58941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm11,%%xmm11             \n"
59041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm14,%%xmm12                  \n"
59141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm15,%%xmm13                  \n"
59241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm12,%%xmm14                  \n"
59341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm13,%%xmm15                  \n"
59441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm14,%%xmm14             \n"
59541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm15,%%xmm15             \n"
59641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Third round of bit swap.
59741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Write to the destination pointer.
59841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm4,%%xmm0                    \n"
59941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm0,(%1)                      \n"
60041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm4                    \n"
60141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm4,%%xmm4               \n"
60241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm4,(%1,%4)                   \n"
60341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
60441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm6,%%xmm2                    \n"
60541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm2,%%xmm6                    \n"
60641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm2,(%1)                      \n"
60741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm6,%%xmm6               \n"
60841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm5,%%xmm1                    \n"
60941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm6,(%1,%4)                   \n"
61041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
61141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm1,%%xmm5                    \n"
61241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm1,(%1)                      \n"
61341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm5,%%xmm5               \n"
61441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm5,(%1,%4)                   \n"
61541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
61641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm7,%%xmm3                    \n"
61741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm3,(%1)                      \n"
61841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm3,%%xmm7                    \n"
61941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm7,%%xmm7               \n"
62041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm7,(%1,%4)                   \n"
62141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
62241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm12,%%xmm8                   \n"
62341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm8,(%1)                      \n"
62441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm12                   \n"
62541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm12,%%xmm12             \n"
62641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm12,(%1,%4)                  \n"
62741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
62841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm14,%%xmm10                  \n"
62941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm10,%%xmm14                  \n"
63041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm10,(%1)                     \n"
63141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm14,%%xmm14             \n"
63241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm13,%%xmm9                   \n"
63341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm14,(%1,%4)                  \n"
63441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
63541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm9,%%xmm13                   \n"
63641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm9,(%1)                      \n"
63741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm13,%%xmm13             \n"
63841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm13,(%1,%4)                  \n"
63941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
64041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm15,%%xmm11                  \n"
64141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm11,(%1)                     \n"
64241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm11,%%xmm15                  \n"
64341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "palignr    $0x8,%%xmm15,%%xmm15             \n"
64441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "sub        $0x10,%2                         \n"
64541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movq       %%xmm15,(%1,%4)                  \n"
64641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%4,2),%1                     \n"
64741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "jg         1b                               \n"
64841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "+r"(src),    // %0
64941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "+r"(dst),    // %1
65041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "+r"(width)   // %2
65141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "r"((intptr_t)(src_stride)),  // %3
65241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "r"((intptr_t)(dst_stride))   // %4
65341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "memory", "cc",
65441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
65541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13",  "xmm14",  "xmm15"
65641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org);
65741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
65841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
65941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#define HAS_TRANSPOSE_UVWX8_SSE2
66041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeUVWx8_SSE2(const uint8* src, int src_stride,
66141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                uint8* dst_a, int dst_stride_a,
66241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                uint8* dst_b, int dst_stride_b,
66341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                                int w) {
66441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  asm volatile (
66541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Read in the data from the source pointer.
66641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // First round of bit swap.
66741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  ".p2align  2                                 \n"
66841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org"1:                                            \n"
66941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm0                      \n"
67041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%4),%%xmm1                   \n"
67141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%4,2),%0                     \n"
67241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm8                    \n"
67341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm1,%%xmm0                    \n"
67441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm1,%%xmm8                    \n"
67541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm1                    \n"
67641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm2                      \n"
67741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%4),%%xmm3                   \n"
67841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%4,2),%0                     \n"
67941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm2,%%xmm8                    \n"
68041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm3,%%xmm2                    \n"
68141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm3,%%xmm8                    \n"
68241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm3                    \n"
68341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm4                      \n"
68441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%4),%%xmm5                   \n"
68541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%4,2),%0                     \n"
68641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm4,%%xmm8                    \n"
68741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm5,%%xmm4                    \n"
68841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm5,%%xmm8                    \n"
68941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm5                    \n"
69041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0),%%xmm6                      \n"
69141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     (%0,%4),%%xmm7                   \n"
69241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%0,%4,2),%0                     \n"
69341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm6,%%xmm8                    \n"
69441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklbw  %%xmm7,%%xmm6                    \n"
69541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "neg        %4                               \n"
69641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        0x10(%0,%4,8),%0                 \n"
69741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhbw  %%xmm7,%%xmm8                    \n"
69841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm7                    \n"
69941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "neg        %4                               \n"
70041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org   // Second round of bit swap.
70141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm8                    \n"
70241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm1,%%xmm9                    \n"
70341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhwd  %%xmm2,%%xmm8                    \n"
70441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhwd  %%xmm3,%%xmm9                    \n"
70541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm2,%%xmm0                    \n"
70641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm3,%%xmm1                    \n"
70741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm2                    \n"
70841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm9,%%xmm3                    \n"
70941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm4,%%xmm8                    \n"
71041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm5,%%xmm9                    \n"
71141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhwd  %%xmm6,%%xmm8                    \n"
71241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhwd  %%xmm7,%%xmm9                    \n"
71341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm6,%%xmm4                    \n"
71441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpcklwd  %%xmm7,%%xmm5                    \n"
71541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm8,%%xmm6                    \n"
71641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm9,%%xmm7                    \n"
71741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Third round of bit swap.
71841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Write to the destination pointer.
71941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm0,%%xmm8                    \n"
72041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm4,%%xmm0                    \n"
72141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm0,(%1)                      \n"  // Write back U channel
72241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm0,(%2)                      \n"  // Write back V channel
72341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhdq  %%xmm4,%%xmm8                    \n"
72441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm8,(%1,%5)                   \n"
72541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%5,2),%1                     \n"
72641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm8,(%2,%6)                   \n"
72741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%2,%6,2),%2                     \n"
72841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm2,%%xmm8                    \n"
72941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm6,%%xmm2                    \n"
73041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm2,(%1)                      \n"
73141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm2,(%2)                      \n"
73241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhdq  %%xmm6,%%xmm8                    \n"
73341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm8,(%1,%5)                   \n"
73441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%5,2),%1                     \n"
73541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm8,(%2,%6)                   \n"
73641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%2,%6,2),%2                     \n"
73741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm1,%%xmm8                    \n"
73841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm5,%%xmm1                    \n"
73941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm1,(%1)                      \n"
74041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm1,(%2)                      \n"
74141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhdq  %%xmm5,%%xmm8                    \n"
74241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm8,(%1,%5)                   \n"
74341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%5,2),%1                     \n"
74441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm8,(%2,%6)                   \n"
74541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%2,%6,2),%2                     \n"
74641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movdqa     %%xmm3,%%xmm8                    \n"
74741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckldq  %%xmm7,%%xmm3                    \n"
74841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm3,(%1)                      \n"
74941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm3,(%2)                      \n"
75041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "punpckhdq  %%xmm7,%%xmm8                    \n"
75141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "sub        $0x8,%3                          \n"
75241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movlpd     %%xmm8,(%1,%5)                   \n"
75341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%1,%5,2),%1                     \n"
75441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "movhpd     %%xmm8,(%2,%6)                   \n"
75541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "lea        (%2,%6,2),%2                     \n"
75641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  "jg         1b                               \n"
75741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "+r"(src),    // %0
75841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "+r"(dst_a),  // %1
75941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "+r"(dst_b),  // %2
76041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "+r"(w)   // %3
76141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "r"((intptr_t)(src_stride)),    // %4
76241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "r"((intptr_t)(dst_stride_a)),  // %5
76341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "r"((intptr_t)(dst_stride_b))   // %6
76441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  : "memory", "cc",
76541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
76641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    "xmm8", "xmm9"
76741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org);
76841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
76941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
77041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
77141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
77241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeWx8_C(const uint8* src, int src_stride,
77341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                           uint8* dst, int dst_stride,
77441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                           int width) {
77541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i;
77641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (i = 0; i < width; ++i) {
77741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[0] = src[0 * src_stride];
77841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[1] = src[1 * src_stride];
77941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[2] = src[2 * src_stride];
78041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[3] = src[3 * src_stride];
78141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[4] = src[4 * src_stride];
78241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[5] = src[5 * src_stride];
78341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[6] = src[6 * src_stride];
78441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst[7] = src[7 * src_stride];
78541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    ++src;
78641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst += dst_stride;
78741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
78841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
78941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
79041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeWxH_C(const uint8* src, int src_stride,
79141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                           uint8* dst, int dst_stride,
79241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                           int width, int height) {
79341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i;
79441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (i = 0; i < width; ++i) {
79541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    int j;
79641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    for (j = 0; j < height; ++j) {
79741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      dst[i * dst_stride + j] = src[j * src_stride + i];
79841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    }
79941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
80041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
80141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
80241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
80341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposePlane(const uint8* src, int src_stride,
80441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    uint8* dst, int dst_stride,
80541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    int width, int height) {
80641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i = height;
80741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  void (*TransposeWx8)(const uint8* src, int src_stride,
80841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                       uint8* dst, int dst_stride,
80941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                       int width) = TransposeWx8_C;
81041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_TRANSPOSE_WX8_NEON)
81141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasNEON)) {
81241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeWx8 = TransposeWx8_NEON;
81341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
81441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
81541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_TRANSPOSE_WX8_SSSE3)
81641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 8)) {
81741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeWx8 = TransposeWx8_SSSE3;
81841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
81941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
82041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_TRANSPOSE_WX8_FAST_SSSE3)
82141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSSE3) &&
82241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(width, 16) &&
82341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16)) {
82441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeWx8 = TransposeWx8_FAST_SSSE3;
82541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
82641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
82741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_TRANSPOSE_WX8_MIPS_DSPR2)
82841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasMIPS_DSPR2)) {
82941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    if (IS_ALIGNED(width, 4) &&
83041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org        IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
83141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      TransposeWx8 = TransposeWx8_FAST_MIPS_DSPR2;
83241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    } else {
83341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      TransposeWx8 = TransposeWx8_MIPS_DSPR2;
83441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    }
83541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
83641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
83741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
83841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Work across the source in 8x8 tiles
83941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  while (i >= 8) {
84041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeWx8(src, src_stride, dst, dst_stride, width);
84141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src += 8 * src_stride;    // Go down 8 rows.
84241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst += 8;                 // Move over 8 columns.
84341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    i -= 8;
84441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
84541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
84641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposeWxH_C(src, src_stride, dst, dst_stride, width, i);
84741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
84841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
84941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
85041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotatePlane90(const uint8* src, int src_stride,
85141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   uint8* dst, int dst_stride,
85241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   int width, int height) {
85341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Rotate by 90 is a transpose with the source read
85441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // from bottom to top. So set the source pointer to the end
85541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // of the buffer and flip the sign of the source stride.
85641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  src += src_stride * (height - 1);
85741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  src_stride = -src_stride;
85841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposePlane(src, src_stride, dst, dst_stride, width, height);
85941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
86041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
86141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
86241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotatePlane270(const uint8* src, int src_stride,
86341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    uint8* dst, int dst_stride,
86441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    int width, int height) {
86541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Rotate by 270 is a transpose with the destination written
86641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // from bottom to top. So set the destination pointer to the end
86741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // of the buffer and flip the sign of the destination stride.
86841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst += dst_stride * (width - 1);
86941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_stride = -dst_stride;
87041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposePlane(src, src_stride, dst, dst_stride, width, height);
87141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
87241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
87341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
87441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotatePlane180(const uint8* src, int src_stride,
87541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    uint8* dst, int dst_stride,
87641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    int width, int height) {
87741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Swap first and last row and mirror the content. Uses a temporary row.
87841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  align_buffer_64(row, width);
87941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  const uint8* src_bot = src + src_stride * (height - 1);
88041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  uint8* dst_bot = dst + dst_stride * (height - 1);
88141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int half_height = (height + 1) >> 1;
88241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int y;
88341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C;
88441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
88541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORROW_NEON)
88641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) {
88741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow = MirrorRow_NEON;
88841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
88941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
89041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORROW_SSE2)
89141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 16) &&
89241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16) &&
89341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) {
89441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow = MirrorRow_SSE2;
89541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
89641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
89741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORROW_SSSE3)
89841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16) &&
89941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16) &&
90041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) {
90141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow = MirrorRow_SSSE3;
90241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
90341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
90441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORROW_AVX2)
90541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasAVX2) && IS_ALIGNED(width, 32)) {
90641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow = MirrorRow_AVX2;
90741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
90841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
90941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORROW_MIPS_DSPR2)
91041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
91141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4) &&
91241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(dst, 4) && IS_ALIGNED(dst_stride, 4)) {
91341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow = MirrorRow_MIPS_DSPR2;
91441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
91541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
91641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_COPYROW_NEON)
91741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) {
91841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow = CopyRow_NEON;
91941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
92041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
92141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_COPYROW_X86)
92241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) {
92341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow = CopyRow_X86;
92441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
92541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
92641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_COPYROW_SSE2)
92741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) &&
92841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16) &&
92941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) {
93041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow = CopyRow_SSE2;
93141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
93241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
93341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_COPYROW_ERMS)
93441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasERMS)) {
93541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow = CopyRow_ERMS;
93641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
93741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
93841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_COPYROW_MIPS)
93941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasMIPS)) {
94041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow = CopyRow_MIPS;
94141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
94241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
94341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
94441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Odd height will harmlessly mirror the middle row twice.
94541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (y = 0; y < half_height; ++y) {
94641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow(src, row, width);  // Mirror first row into a buffer
94741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src += src_stride;
94841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRow(src_bot, dst, width);  // Mirror last row into first row
94941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst += dst_stride;
95041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    CopyRow(row, dst_bot, width);  // Copy first mirrored row into last
95141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_bot -= src_stride;
95241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_bot -= dst_stride;
95341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
95441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  free_aligned_buffer_64(row);
95541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
95641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
95741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeUVWx8_C(const uint8* src, int src_stride,
95841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             uint8* dst_a, int dst_stride_a,
95941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             uint8* dst_b, int dst_stride_b,
96041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             int width) {
96141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i;
96241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (i = 0; i < width; ++i) {
96341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[0] = src[0 * src_stride + 0];
96441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[0] = src[0 * src_stride + 1];
96541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[1] = src[1 * src_stride + 0];
96641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[1] = src[1 * src_stride + 1];
96741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[2] = src[2 * src_stride + 0];
96841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[2] = src[2 * src_stride + 1];
96941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[3] = src[3 * src_stride + 0];
97041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[3] = src[3 * src_stride + 1];
97141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[4] = src[4 * src_stride + 0];
97241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[4] = src[4 * src_stride + 1];
97341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[5] = src[5 * src_stride + 0];
97441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[5] = src[5 * src_stride + 1];
97541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[6] = src[6 * src_stride + 0];
97641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[6] = src[6 * src_stride + 1];
97741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a[7] = src[7 * src_stride + 0];
97841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b[7] = src[7 * src_stride + 1];
97941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src += 2;
98041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a += dst_stride_a;
98141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b += dst_stride_b;
98241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
98341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
98441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
98541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgstatic void TransposeUVWxH_C(const uint8* src, int src_stride,
98641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             uint8* dst_a, int dst_stride_a,
98741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             uint8* dst_b, int dst_stride_b,
98841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                             int width, int height) {
98941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i;
99041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (i = 0; i < width * 2; i += 2) {
99141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    int j;
99241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    for (j = 0; j < height; ++j) {
99341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      dst_a[j + ((i >> 1) * dst_stride_a)] = src[i + (j * src_stride)];
99441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      dst_b[j + ((i >> 1) * dst_stride_b)] = src[i + (j * src_stride) + 1];
99541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    }
99641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
99741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
99841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
99941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
100041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid TransposeUV(const uint8* src, int src_stride,
100141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_a, int dst_stride_a,
100241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_b, int dst_stride_b,
100341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 int width, int height) {
100441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i = height;
100541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  void (*TransposeUVWx8)(const uint8* src, int src_stride,
100641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_a, int dst_stride_a,
100741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         uint8* dst_b, int dst_stride_b,
100841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                         int width) = TransposeUVWx8_C;
100941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_TRANSPOSE_UVWX8_NEON)
101041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasNEON)) {
101141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeUVWx8 = TransposeUVWx8_NEON;
101241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
101341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif defined(HAS_TRANSPOSE_UVWX8_SSE2)
101441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSE2) &&
101541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(width, 8) &&
101641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16)) {
101741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeUVWx8 = TransposeUVWx8_SSE2;
101841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
101941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif defined(HAS_TRANSPOSE_UVWx8_MIPS_DSPR2)
102041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 2) &&
102141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
102241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeUVWx8 = TransposeUVWx8_MIPS_DSPR2;
102341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
102441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
102541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
102641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Work through the source in 8x8 tiles.
102741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  while (i >= 8) {
102841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    TransposeUVWx8(src, src_stride,
102941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   dst_a, dst_stride_a,
103041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   dst_b, dst_stride_b,
103141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   width);
103241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src += 8 * src_stride;    // Go down 8 rows.
103341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a += 8;               // Move over 8 columns.
103441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b += 8;               // Move over 8 columns.
103541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    i -= 8;
103641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
103741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
103841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposeUVWxH_C(src, src_stride,
103941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   dst_a, dst_stride_a,
104041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   dst_b, dst_stride_b,
104141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                   width, i);
104241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
104341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
104441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
104541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotateUV90(const uint8* src, int src_stride,
104641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                uint8* dst_a, int dst_stride_a,
104741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                uint8* dst_b, int dst_stride_b,
104841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                int width, int height) {
104941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  src += src_stride * (height - 1);
105041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  src_stride = -src_stride;
105141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
105241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposeUV(src, src_stride,
105341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              dst_a, dst_stride_a,
105441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              dst_b, dst_stride_b,
105541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              width, height);
105641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
105741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
105841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
105941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotateUV270(const uint8* src, int src_stride,
106041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_a, int dst_stride_a,
106141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_b, int dst_stride_b,
106241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 int width, int height) {
106341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_a += dst_stride_a * (width - 1);
106441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_b += dst_stride_b * (width - 1);
106541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_stride_a = -dst_stride_a;
106641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_stride_b = -dst_stride_b;
106741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
106841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  TransposeUV(src, src_stride,
106941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              dst_a, dst_stride_a,
107041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              dst_b, dst_stride_b,
107141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org              width, height);
107241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
107341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
107441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org// Rotate 180 is a horizontal and vertical flip.
107541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
107641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgvoid RotateUV180(const uint8* src, int src_stride,
107741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_a, int dst_stride_a,
107841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 uint8* dst_b, int dst_stride_b,
107941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 int width, int height) {
108041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int i;
108141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  void (*MirrorRowUV)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) =
108241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      MirrorUVRow_C;
108341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#if defined(HAS_MIRRORUVROW_NEON)
108441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 8)) {
108541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRowUV = MirrorUVRow_NEON;
108641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
108741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif defined(HAS_MIRRORROW_UV_SSSE3)
108841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 16) &&
108941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16)) {
109041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRowUV = MirrorUVRow_SSSE3;
109141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
109241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#elif defined(HAS_MIRRORUVROW_MIPS_DSPR2)
109341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (TestCpuFlag(kCpuHasMIPS_DSPR2) &&
109441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      IS_ALIGNED(src, 4) && IS_ALIGNED(src_stride, 4)) {
109541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRowUV = MirrorUVRow_MIPS_DSPR2;
109641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
109741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
109841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
109941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_a += dst_stride_a * (height - 1);
110041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  dst_b += dst_stride_b * (height - 1);
110141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
110241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  for (i = 0; i < height; ++i) {
110341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    MirrorRowUV(src, dst_a, dst_b, width);
110441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src += src_stride;
110541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_a -= dst_stride_a;
110641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    dst_b -= dst_stride_b;
110741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
110841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
110941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
111041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
111141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint RotatePlane(const uint8* src, int src_stride,
111241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                uint8* dst, int dst_stride,
111341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                int width, int height,
111441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                enum RotationMode mode) {
111541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (!src || width <= 0 || height == 0 || !dst) {
111641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    return -1;
111741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
111841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
111941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Negative height means invert the image.
112041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (height < 0) {
112141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    height = -height;
112241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src = src + (height - 1) * src_stride;
112341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride = -src_stride;
112441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
112541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
112641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  switch (mode) {
112741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate0:
112841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      // copy frame
112941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      CopyPlane(src, src_stride,
113041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                dst, dst_stride,
113141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                width, height);
113241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
113341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate90:
113441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane90(src, src_stride,
113541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    dst, dst_stride,
113641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    width, height);
113741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
113841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate270:
113941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane270(src, src_stride,
114041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst, dst_stride,
114141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
114241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
114341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate180:
114441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane180(src, src_stride,
114541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst, dst_stride,
114641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
114741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
114841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    default:
114941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      break;
115041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
115141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  return -1;
115241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
115341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
115441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
115541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint I420Rotate(const uint8* src_y, int src_stride_y,
115641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               const uint8* src_u, int src_stride_u,
115741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               const uint8* src_v, int src_stride_v,
115841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               uint8* dst_y, int dst_stride_y,
115941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               uint8* dst_u, int dst_stride_u,
116041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               uint8* dst_v, int dst_stride_v,
116141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               int width, int height,
116241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org               enum RotationMode mode) {
116341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int halfwidth = (width + 1) >> 1;
116441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int halfheight = (height + 1) >> 1;
116541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (!src_y || !src_u || !src_v || width <= 0 || height == 0 ||
116641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      !dst_y || !dst_u || !dst_v) {
116741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    return -1;
116841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
116941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
117041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Negative height means invert the image.
117141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (height < 0) {
117241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    height = -height;
117341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    halfheight = (height + 1) >> 1;
117441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_y = src_y + (height - 1) * src_stride_y;
117541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_u = src_u + (halfheight - 1) * src_stride_u;
117641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_v = src_v + (halfheight - 1) * src_stride_v;
117741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride_y = -src_stride_y;
117841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride_u = -src_stride_u;
117941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride_v = -src_stride_v;
118041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
118141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
118241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  switch (mode) {
118341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate0:
118441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      // copy frame
118541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return I420Copy(src_y, src_stride_y,
118641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      src_u, src_stride_u,
118741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      src_v, src_stride_v,
118841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      dst_y, dst_stride_y,
118941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      dst_u, dst_stride_u,
119041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      dst_v, dst_stride_v,
119141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                      width, height);
119241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate90:
119341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane90(src_y, src_stride_y,
119441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    dst_y, dst_stride_y,
119541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    width, height);
119641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane90(src_u, src_stride_u,
119741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    dst_u, dst_stride_u,
119841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    halfwidth, halfheight);
119941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane90(src_v, src_stride_v,
120041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    dst_v, dst_stride_v,
120141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    halfwidth, halfheight);
120241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
120341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate270:
120441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane270(src_y, src_stride_y,
120541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_y, dst_stride_y,
120641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
120741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane270(src_u, src_stride_u,
120841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_u, dst_stride_u,
120941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     halfwidth, halfheight);
121041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane270(src_v, src_stride_v,
121141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_v, dst_stride_v,
121241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     halfwidth, halfheight);
121341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
121441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate180:
121541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane180(src_y, src_stride_y,
121641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_y, dst_stride_y,
121741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
121841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane180(src_u, src_stride_u,
121941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_u, dst_stride_u,
122041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     halfwidth, halfheight);
122141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane180(src_v, src_stride_v,
122241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_v, dst_stride_v,
122341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     halfwidth, halfheight);
122441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
122541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    default:
122641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      break;
122741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
122841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  return -1;
122941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
123041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
123141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgLIBYUV_API
123241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.orgint NV12ToI420Rotate(const uint8* src_y, int src_stride_y,
123341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     const uint8* src_uv, int src_stride_uv,
123441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     uint8* dst_y, int dst_stride_y,
123541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     uint8* dst_u, int dst_stride_u,
123641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     uint8* dst_v, int dst_stride_v,
123741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     int width, int height,
123841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     enum RotationMode mode) {
123941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int halfwidth = (width + 1) >> 1;
124041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  int halfheight = (height + 1) >> 1;
124141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (!src_y || !src_uv || width <= 0 || height == 0 ||
124241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      !dst_y || !dst_u || !dst_v) {
124341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    return -1;
124441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
124541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
124641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  // Negative height means invert the image.
124741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (height < 0) {
124841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    height = -height;
124941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    halfheight = (height + 1) >> 1;
125041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_y = src_y + (height - 1) * src_stride_y;
125141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_uv = src_uv + (halfheight - 1) * src_stride_uv;
125241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride_y = -src_stride_y;
125341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    src_stride_uv = -src_stride_uv;
125441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
125541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
125641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  switch (mode) {
125741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate0:
125841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      // copy frame
125941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return NV12ToI420(src_y, src_stride_y,
126041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                        src_uv, src_stride_uv,
126141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                        dst_y, dst_stride_y,
126241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                        dst_u, dst_stride_u,
126341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                        dst_v, dst_stride_v,
126441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                        width, height);
126541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate90:
126641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane90(src_y, src_stride_y,
126741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    dst_y, dst_stride_y,
126841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                    width, height);
126941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotateUV90(src_uv, src_stride_uv,
127041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 dst_u, dst_stride_u,
127141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 dst_v, dst_stride_v,
127241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                 halfwidth, halfheight);
127341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
127441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate270:
127541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane270(src_y, src_stride_y,
127641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_y, dst_stride_y,
127741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
127841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotateUV270(src_uv, src_stride_uv,
127941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  dst_u, dst_stride_u,
128041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  dst_v, dst_stride_v,
128141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  halfwidth, halfheight);
128241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
128341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    case kRotate180:
128441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotatePlane180(src_y, src_stride_y,
128541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     dst_y, dst_stride_y,
128641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                     width, height);
128741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      RotateUV180(src_uv, src_stride_uv,
128841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  dst_u, dst_stride_u,
128941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  dst_v, dst_stride_v,
129041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org                  halfwidth, halfheight);
129141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      return 0;
129241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    default:
129341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      break;
129441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  }
129541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  return -1;
129641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}
129741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org
129841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#ifdef __cplusplus
129941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}  // extern "C"
130041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org}  // namespace libyuv
130141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org#endif
1302