/* * Copyright 2011 The LibYuv Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
LIBYUV_API void TransposePlane(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) { int i = height; #ifdefined(HAS_TRANSPOSEWX16_MSA) void (*TransposeWx16)(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width) = TransposeWx16_C; #else void (*TransposeWx8)(const uint8_t* src, int src_stride, uint8_t* dst, int dst_stride, int width) = TransposeWx8_C; #endif
#ifdefined(HAS_TRANSPOSEWX16_MSA) if (TestCpuFlag(kCpuHasMSA)) {
TransposeWx16 = TransposeWx16_Any_MSA; if (IS_ALIGNED(width, 16)) {
TransposeWx16 = TransposeWx16_MSA;
}
} #else #ifdefined(HAS_TRANSPOSEWX8_NEON) if (TestCpuFlag(kCpuHasNEON)) {
TransposeWx8 = TransposeWx8_NEON;
} #endif #ifdefined(HAS_TRANSPOSEWX8_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) {
TransposeWx8 = TransposeWx8_Any_SSSE3; if (IS_ALIGNED(width, 8)) {
TransposeWx8 = TransposeWx8_SSSE3;
}
} #endif #ifdefined(HAS_TRANSPOSEWX8_MMI) if (TestCpuFlag(kCpuHasMMI)) {
TransposeWx8 = TransposeWx8_MMI;
} #endif #ifdefined(HAS_TRANSPOSEWX8_FAST_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) {
TransposeWx8 = TransposeWx8_Fast_Any_SSSE3; if (IS_ALIGNED(width, 16)) {
TransposeWx8 = TransposeWx8_Fast_SSSE3;
}
} #endif #endif/* defined(HAS_TRANSPOSEWX16_MSA) */
#ifdefined(HAS_TRANSPOSEWX16_MSA) // Work across the source in 16x16 tiles while (i >= 16) {
TransposeWx16(src, src_stride, dst, dst_stride, width);
src += 16 * src_stride; // Go down 16 rows.
dst += 16; // Move over 16 columns.
i -= 16;
} #else // Work across the source in 8x8 tiles while (i >= 8) {
TransposeWx8(src, src_stride, dst, dst_stride, width);
src += 8 * src_stride; // Go down 8 rows.
dst += 8; // Move over 8 columns.
i -= 8;
} #endif
if (i > 0) {
TransposeWxH_C(src, src_stride, dst, dst_stride, width, i);
}
}
LIBYUV_API void RotatePlane90(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) { // Rotate by 90 is a transpose with the source read // from bottom to top. So set the source pointer to the end // of the buffer and flip the sign of the source stride.
src += src_stride * (height - 1);
src_stride = -src_stride;
TransposePlane(src, src_stride, dst, dst_stride, width, height);
}
LIBYUV_API void RotatePlane270(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) { // Rotate by 270 is a transpose with the destination written // from bottom to top. So set the destination pointer to the end // of the buffer and flip the sign of the destination stride.
dst += dst_stride * (width - 1);
dst_stride = -dst_stride;
TransposePlane(src, src_stride, dst, dst_stride, width, height);
}
LIBYUV_API void RotatePlane180(const uint8_t* src, int src_stride,
uint8_t* dst, int dst_stride, int width, int height) { // Swap first and last row and mirror the content. Uses a temporary row.
align_buffer_64(row, width); const uint8_t* src_bot = src + src_stride * (height - 1);
uint8_t* dst_bot = dst + dst_stride * (height - 1); int half_height = (height + 1) >> 1; int y; void (*MirrorRow)(const uint8_t* src, uint8_t* dst, int width) = MirrorRow_C; void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C; #ifdefined(HAS_MIRRORROW_NEON) if (TestCpuFlag(kCpuHasNEON)) {
MirrorRow = MirrorRow_Any_NEON; if (IS_ALIGNED(width, 32)) {
MirrorRow = MirrorRow_NEON;
}
} #endif #ifdefined(HAS_MIRRORROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) {
MirrorRow = MirrorRow_Any_SSSE3; if (IS_ALIGNED(width, 16)) {
MirrorRow = MirrorRow_SSSE3;
}
} #endif #ifdefined(HAS_MIRRORROW_AVX2) if (TestCpuFlag(kCpuHasAVX2)) {
MirrorRow = MirrorRow_Any_AVX2; if (IS_ALIGNED(width, 32)) {
MirrorRow = MirrorRow_AVX2;
}
} #endif #ifdefined(HAS_MIRRORROW_MMI) if (TestCpuFlag(kCpuHasMMI)) {
MirrorRow = MirrorRow_Any_MMI; if (IS_ALIGNED(width, 8)) {
MirrorRow = MirrorRow_MMI;
}
} #endif #ifdefined(HAS_MIRRORROW_MSA) if (TestCpuFlag(kCpuHasMSA)) {
MirrorRow = MirrorRow_Any_MSA; if (IS_ALIGNED(width, 64)) {
MirrorRow = MirrorRow_MSA;
}
} #endif #ifdefined(HAS_COPYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) {
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;
} #endif #ifdefined(HAS_COPYROW_AVX) if (TestCpuFlag(kCpuHasAVX)) {
CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX;
} #endif #ifdefined(HAS_COPYROW_ERMS) if (TestCpuFlag(kCpuHasERMS)) {
CopyRow = CopyRow_ERMS;
} #endif #ifdefined(HAS_COPYROW_NEON) if (TestCpuFlag(kCpuHasNEON)) {
CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON;
} #endif #ifdefined(HAS_COPYROW_MMI) if (TestCpuFlag(kCpuHasMMI)) {
CopyRow = IS_ALIGNED(width, 8) ? CopyRow_MMI : CopyRow_Any_MMI;
} #endif
// Odd height will harmlessly mirror the middle row twice. for (y = 0; y < half_height; ++y) {
CopyRow(src, row, width); // Copy first row into buffer
MirrorRow(src_bot, dst, width); // Mirror last row into first row
MirrorRow(row, dst_bot, width); // Mirror buffer into last row
src += src_stride;
dst += dst_stride;
src_bot -= src_stride;
dst_bot -= dst_stride;
}
free_aligned_buffer_64(row);
}
LIBYUV_API void TransposeUV(const uint8_t* src, int src_stride,
uint8_t* dst_a, int dst_stride_a,
uint8_t* dst_b, int dst_stride_b, int width, int height) { int i = height; #ifdefined(HAS_TRANSPOSEUVWX16_MSA) void (*TransposeUVWx16)(const uint8_t* src, int src_stride, uint8_t* dst_a, int dst_stride_a, uint8_t* dst_b, int dst_stride_b, int width) = TransposeUVWx16_C; #else void (*TransposeUVWx8)(const uint8_t* src, int src_stride, uint8_t* dst_a, int dst_stride_a, uint8_t* dst_b, int dst_stride_b, int width) = TransposeUVWx8_C; #endif
#ifdefined(HAS_TRANSPOSEUVWX16_MSA) if (TestCpuFlag(kCpuHasMSA)) {
TransposeUVWx16 = TransposeUVWx16_Any_MSA; if (IS_ALIGNED(width, 8)) {
TransposeUVWx16 = TransposeUVWx16_MSA;
}
} #else #ifdefined(HAS_TRANSPOSEUVWX8_NEON) if (TestCpuFlag(kCpuHasNEON)) {
TransposeUVWx8 = TransposeUVWx8_NEON;
} #endif #ifdefined(HAS_TRANSPOSEUVWX8_SSE2) if (TestCpuFlag(kCpuHasSSE2)) {
TransposeUVWx8 = TransposeUVWx8_Any_SSE2; if (IS_ALIGNED(width, 8)) {
TransposeUVWx8 = TransposeUVWx8_SSE2;
}
} #endif #ifdefined(HAS_TRANSPOSEUVWX8_MMI) if (TestCpuFlag(kCpuHasMMI)) {
TransposeUVWx8 = TransposeUVWx8_Any_MMI; if (IS_ALIGNED(width, 4)) {
TransposeUVWx8 = TransposeUVWx8_MMI;
}
} #endif #endif/* defined(HAS_TRANSPOSEUVWX16_MSA) */
#ifdefined(HAS_TRANSPOSEUVWX16_MSA) // Work through the source in 8x8 tiles. while (i >= 16) {
TransposeUVWx16(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
width);
src += 16 * src_stride; // Go down 16 rows.
dst_a += 16; // Move over 8 columns.
dst_b += 16; // Move over 8 columns.
i -= 16;
} #else // Work through the source in 8x8 tiles. while (i >= 8) {
TransposeUVWx8(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
width);
src += 8 * src_stride; // Go down 8 rows.
dst_a += 8; // Move over 8 columns.
dst_b += 8; // Move over 8 columns.
i -= 8;
} #endif
if (i > 0) {
TransposeUVWxH_C(src, src_stride, dst_a, dst_stride_a, dst_b, dst_stride_b,
width, i);
}
}
LIBYUV_API void RotateUV90(const uint8_t* src, int src_stride,
uint8_t* dst_a, int dst_stride_a,
uint8_t* dst_b, int dst_stride_b, int width, int height) {
src += src_stride * (height - 1);
src_stride = -src_stride;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.