Commit 0945c578 authored by fbarchard@google.com's avatar fbarchard@google.com

Rotate by 180 in place.

BUG=18
TEST=none
Review URL: https://webrtc-codereview.appspot.com/456010

git-svn-id: http://libyuv.googlecode.com/svn/trunk@227 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent 299c9741
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 226
Version: 227
License: BSD
License File: LICENSE
......
......@@ -11,7 +11,7 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION_H_
#define INCLUDE_LIBYUV_VERSION 226
#define INCLUDE_LIBYUV_VERSION 227
#endif // INCLUDE_LIBYUV_VERSION_H_
......@@ -1579,10 +1579,14 @@ int ConvertToI420(const uint8* sample, size_t sample_size,
}
int r = 0;
// For formats that need 2 pass rotation, convert into buffer first
bool need_rot = rotation && format != FOURCC_NV12 &&
// One pass rotation is available for some formats. For the rest, convert
// to I420 (with optional vertical flipping) into a temporary I420 buffer,
// and then rotate the I420 to the final destination buffer.
// For in-place conversion, if destination y is same as source sample,
// also enable temporary buffer.
bool need_buf = (rotation && format != FOURCC_NV12 &&
format != FOURCC_NV21 && format != FOURCC_I420 &&
format != FOURCC_YV12;
format != FOURCC_YV12) || y == sample;
uint8* tmp_y = y;
uint8* tmp_u = u;
uint8* tmp_v = v;
......@@ -1591,7 +1595,7 @@ int ConvertToI420(const uint8* sample, size_t sample_size,
int tmp_v_stride = v_stride;
uint8* buf = NULL;
int abs_dst_height = (dst_height < 0) ? -dst_height : dst_height;
if (need_rot) {
if (need_buf) {
int y_size = dst_width * abs_dst_height;
int uv_size = ((dst_width + 1) / 2) * ((abs_dst_height + 1) / 2);
buf = new uint8[y_size + uv_size * 2];
......@@ -1890,7 +1894,7 @@ int ConvertToI420(const uint8* sample, size_t sample_size,
r = -1; // unknown fourcc - return failure code.
}
if (need_rot) {
if (need_buf) {
if (!r) {
r = I420Rotate(y, y_stride,
u, u_stride,
......
......@@ -874,14 +874,40 @@ void RotatePlane180(const uint8* src, int src_stride,
{
MirrorRow = MirrorRow_C;
}
// Rotate by 180 is a mirror and vertical flip
src += src_stride * (height - 1);
for (int y = 0; y < height; ++y) {
MirrorRow(src, dst, width);
src -= src_stride;
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
#if defined(HAS_COPYROW_NEON)
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 64)) {
CopyRow = CopyRow_NEON;
}
#elif defined(HAS_COPYROW_X86)
if (IS_ALIGNED(width, 4)) {
CopyRow = CopyRow_X86;
#if defined(HAS_COPYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2) &&
IS_ALIGNED(width, 32) &&
IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) {
CopyRow = CopyRow_SSE2;
}
#endif
}
#endif
if (width > kMaxStride) {
return;
}
// Swap first and last row and mirror the content. Uses a temporary row.
SIMD_ALIGNED(uint8 row[kMaxStride]);
const uint8* src_bot = src + src_stride * (height - 1);
uint8* dst_bot = dst + dst_stride * (height - 1);
int half_height = (height + 1) >> 1;
// Odd height will harmlessly mirror the middle row twice.
for (int y = 0; y < half_height; ++y) {
MirrorRow(src, row, width); // Mirror first row into a buffer
src += src_stride;
MirrorRow(src_bot, dst, width); // Mirror last row into first row
dst += dst_stride;
CopyRow(row, dst_bot, width); // Copy first mirrored row into last
src_bot -= src_stride;
dst_bot -= dst_stride;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment