mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 01:06:46 +08:00
Rotate functions ported to C. This completes all rotate functionality under c89, for overall 71% complete port.
BUG=303 TESTED=cl /c /TC /Iinclude source/rotate_argb.cc R=tpsiaki@google.com Review URL: https://webrtc-codereview.appspot.com/6959004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@963 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
5aa39953cc
commit
e28b2084d7
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 961
|
Version: 962
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,6 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 961
|
#define LIBYUV_VERSION 962
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||||
|
|||||||
@ -772,7 +772,8 @@ static void TransposeUVWx8_SSE2(const uint8* src, int src_stride,
|
|||||||
static void TransposeWx8_C(const uint8* src, int src_stride,
|
static void TransposeWx8_C(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width) {
|
int width) {
|
||||||
for (int i = 0; i < width; ++i) {
|
int i;
|
||||||
|
for (i = 0; i < width; ++i) {
|
||||||
dst[0] = src[0 * src_stride];
|
dst[0] = src[0 * src_stride];
|
||||||
dst[1] = src[1 * src_stride];
|
dst[1] = src[1 * src_stride];
|
||||||
dst[2] = src[2 * src_stride];
|
dst[2] = src[2 * src_stride];
|
||||||
@ -789,8 +790,10 @@ static void TransposeWx8_C(const uint8* src, int src_stride,
|
|||||||
static void TransposeWxH_C(const uint8* src, int src_stride,
|
static void TransposeWxH_C(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
for (int i = 0; i < width; ++i) {
|
int i;
|
||||||
for (int j = 0; j < height; ++j) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < height; ++j) {
|
||||||
dst[i * dst_stride + j] = src[j * src_stride + i];
|
dst[i * dst_stride + j] = src[j * src_stride + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -800,6 +803,7 @@ LIBYUV_API
|
|||||||
void TransposePlane(const uint8* src, int src_stride,
|
void TransposePlane(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
int i = height;
|
||||||
void (*TransposeWx8)(const uint8* src, int src_stride,
|
void (*TransposeWx8)(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width) = TransposeWx8_C;
|
int width) = TransposeWx8_C;
|
||||||
@ -832,7 +836,6 @@ void TransposePlane(const uint8* src, int src_stride,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Work across the source in 8x8 tiles
|
// Work across the source in 8x8 tiles
|
||||||
int i = height;
|
|
||||||
while (i >= 8) {
|
while (i >= 8) {
|
||||||
TransposeWx8(src, src_stride, dst, dst_stride, width);
|
TransposeWx8(src, src_stride, dst, dst_stride, width);
|
||||||
src += 8 * src_stride; // Go down 8 rows.
|
src += 8 * src_stride; // Go down 8 rows.
|
||||||
@ -871,7 +874,14 @@ LIBYUV_API
|
|||||||
void RotatePlane180(const uint8* src, int src_stride,
|
void RotatePlane180(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
// Swap first and last row and mirror the content. Uses a temporary row.
|
||||||
|
align_buffer_64(row, width);
|
||||||
|
const uint8* src_bot = src + src_stride * (height - 1);
|
||||||
|
uint8* dst_bot = dst + dst_stride * (height - 1);
|
||||||
|
int half_height = (height + 1) >> 1;
|
||||||
|
int y;
|
||||||
void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C;
|
void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C;
|
||||||
|
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
|
||||||
#if defined(HAS_MIRRORROW_NEON)
|
#if defined(HAS_MIRRORROW_NEON)
|
||||||
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) {
|
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 16)) {
|
||||||
MirrorRow = MirrorRow_NEON;
|
MirrorRow = MirrorRow_NEON;
|
||||||
@ -903,7 +913,6 @@ void RotatePlane180(const uint8* src, int src_stride,
|
|||||||
MirrorRow = MirrorRow_MIPS_DSPR2;
|
MirrorRow = MirrorRow_MIPS_DSPR2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
|
|
||||||
#if defined(HAS_COPYROW_NEON)
|
#if defined(HAS_COPYROW_NEON)
|
||||||
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) {
|
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) {
|
||||||
CopyRow = CopyRow_NEON;
|
CopyRow = CopyRow_NEON;
|
||||||
@ -932,13 +941,8 @@ void RotatePlane180(const uint8* src, int src_stride,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Swap first and last row and mirror the content. Uses a temporary row.
|
|
||||||
align_buffer_64(row, width);
|
|
||||||
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.
|
// Odd height will harmlessly mirror the middle row twice.
|
||||||
for (int y = 0; y < half_height; ++y) {
|
for (y = 0; y < half_height; ++y) {
|
||||||
MirrorRow(src, row, width); // Mirror first row into a buffer
|
MirrorRow(src, row, width); // Mirror first row into a buffer
|
||||||
src += src_stride;
|
src += src_stride;
|
||||||
MirrorRow(src_bot, dst, width); // Mirror last row into first row
|
MirrorRow(src_bot, dst, width); // Mirror last row into first row
|
||||||
@ -954,7 +958,8 @@ static void TransposeUVWx8_C(const uint8* src, int src_stride,
|
|||||||
uint8* dst_a, int dst_stride_a,
|
uint8* dst_a, int dst_stride_a,
|
||||||
uint8* dst_b, int dst_stride_b,
|
uint8* dst_b, int dst_stride_b,
|
||||||
int width) {
|
int width) {
|
||||||
for (int i = 0; i < width; ++i) {
|
int i;
|
||||||
|
for (i = 0; i < width; ++i) {
|
||||||
dst_a[0] = src[0 * src_stride + 0];
|
dst_a[0] = src[0 * src_stride + 0];
|
||||||
dst_b[0] = src[0 * src_stride + 1];
|
dst_b[0] = src[0 * src_stride + 1];
|
||||||
dst_a[1] = src[1 * src_stride + 0];
|
dst_a[1] = src[1 * src_stride + 0];
|
||||||
@ -981,18 +986,22 @@ static void TransposeUVWxH_C(const uint8* src, int src_stride,
|
|||||||
uint8* dst_a, int dst_stride_a,
|
uint8* dst_a, int dst_stride_a,
|
||||||
uint8* dst_b, int dst_stride_b,
|
uint8* dst_b, int dst_stride_b,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
for (int i = 0; i < width * 2; i += 2)
|
int i;
|
||||||
for (int j = 0; j < height; ++j) {
|
for (i = 0; i < width * 2; i += 2) {
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < height; ++j) {
|
||||||
dst_a[j + ((i >> 1) * dst_stride_a)] = src[i + (j * src_stride)];
|
dst_a[j + ((i >> 1) * dst_stride_a)] = src[i + (j * src_stride)];
|
||||||
dst_b[j + ((i >> 1) * dst_stride_b)] = src[i + (j * src_stride) + 1];
|
dst_b[j + ((i >> 1) * dst_stride_b)] = src[i + (j * src_stride) + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LIBYUV_API
|
LIBYUV_API
|
||||||
void TransposeUV(const uint8* src, int src_stride,
|
void TransposeUV(const uint8* src, int src_stride,
|
||||||
uint8* dst_a, int dst_stride_a,
|
uint8* dst_a, int dst_stride_a,
|
||||||
uint8* dst_b, int dst_stride_b,
|
uint8* dst_b, int dst_stride_b,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
int i = height;
|
||||||
void (*TransposeUVWx8)(const uint8* src, int src_stride,
|
void (*TransposeUVWx8)(const uint8* src, int src_stride,
|
||||||
uint8* dst_a, int dst_stride_a,
|
uint8* dst_a, int dst_stride_a,
|
||||||
uint8* dst_b, int dst_stride_b,
|
uint8* dst_b, int dst_stride_b,
|
||||||
@ -1015,7 +1024,6 @@ void TransposeUV(const uint8* src, int src_stride,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Work through the source in 8x8 tiles.
|
// Work through the source in 8x8 tiles.
|
||||||
int i = height;
|
|
||||||
while (i >= 8) {
|
while (i >= 8) {
|
||||||
TransposeUVWx8(src, src_stride,
|
TransposeUVWx8(src, src_stride,
|
||||||
dst_a, dst_stride_a,
|
dst_a, dst_stride_a,
|
||||||
@ -1069,6 +1077,7 @@ void RotateUV180(const uint8* src, int src_stride,
|
|||||||
uint8* dst_a, int dst_stride_a,
|
uint8* dst_a, int dst_stride_a,
|
||||||
uint8* dst_b, int dst_stride_b,
|
uint8* dst_b, int dst_stride_b,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
int i;
|
||||||
void (*MirrorRowUV)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) =
|
void (*MirrorRowUV)(const uint8* src, uint8* dst_u, uint8* dst_v, int width) =
|
||||||
MirrorUVRow_C;
|
MirrorUVRow_C;
|
||||||
#if defined(HAS_MIRRORUVROW_NEON)
|
#if defined(HAS_MIRRORUVROW_NEON)
|
||||||
@ -1090,7 +1099,7 @@ void RotateUV180(const uint8* src, int src_stride,
|
|||||||
dst_a += dst_stride_a * (height - 1);
|
dst_a += dst_stride_a * (height - 1);
|
||||||
dst_b += dst_stride_b * (height - 1);
|
dst_b += dst_stride_b * (height - 1);
|
||||||
|
|
||||||
for (int i = 0; i < height; ++i) {
|
for (i = 0; i < height; ++i) {
|
||||||
MirrorRowUV(src, dst_a, dst_b, width);
|
MirrorRowUV(src, dst_a, dst_b, width);
|
||||||
src += src_stride;
|
src += src_stride;
|
||||||
dst_a -= dst_stride_a;
|
dst_a -= dst_stride_a;
|
||||||
@ -1151,12 +1160,12 @@ int I420Rotate(const uint8* src_y, int src_stride_y,
|
|||||||
uint8* dst_v, int dst_stride_v,
|
uint8* dst_v, int dst_stride_v,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
enum RotationMode mode) {
|
enum RotationMode mode) {
|
||||||
|
int halfwidth = (width + 1) >> 1;
|
||||||
|
int halfheight = (height + 1) >> 1;
|
||||||
if (!src_y || !src_u || !src_v || width <= 0 || height == 0 ||
|
if (!src_y || !src_u || !src_v || width <= 0 || height == 0 ||
|
||||||
!dst_y || !dst_u || !dst_v) {
|
!dst_y || !dst_u || !dst_v) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int halfwidth = (width + 1) >> 1;
|
|
||||||
int halfheight = (height + 1) >> 1;
|
|
||||||
|
|
||||||
// Negative height means invert the image.
|
// Negative height means invert the image.
|
||||||
if (height < 0) {
|
if (height < 0) {
|
||||||
@ -1227,12 +1236,12 @@ int NV12ToI420Rotate(const uint8* src_y, int src_stride_y,
|
|||||||
uint8* dst_v, int dst_stride_v,
|
uint8* dst_v, int dst_stride_v,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
enum RotationMode mode) {
|
enum RotationMode mode) {
|
||||||
|
int halfwidth = (width + 1) >> 1;
|
||||||
|
int halfheight = (height + 1) >> 1;
|
||||||
if (!src_y || !src_uv || width <= 0 || height == 0 ||
|
if (!src_y || !src_uv || width <= 0 || height == 0 ||
|
||||||
!dst_y || !dst_u || !dst_v) {
|
!dst_y || !dst_u || !dst_v) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int halfwidth = (width + 1) >> 1;
|
|
||||||
int halfheight = (height + 1) >> 1;
|
|
||||||
|
|
||||||
// Negative height means invert the image.
|
// Negative height means invert the image.
|
||||||
if (height < 0) {
|
if (height < 0) {
|
||||||
|
|||||||
@ -45,6 +45,7 @@ void ScaleARGBRowDownEven_C(const uint8* src_ptr, int,
|
|||||||
static void ARGBTranspose(const uint8* src, int src_stride,
|
static void ARGBTranspose(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
int i;
|
||||||
int src_pixel_step = src_stride >> 2;
|
int src_pixel_step = src_stride >> 2;
|
||||||
void (*ScaleARGBRowDownEven)(const uint8* src_ptr, int src_stride,
|
void (*ScaleARGBRowDownEven)(const uint8* src_ptr, int src_stride,
|
||||||
int src_step, uint8* dst_ptr, int dst_width) = ScaleARGBRowDownEven_C;
|
int src_step, uint8* dst_ptr, int dst_width) = ScaleARGBRowDownEven_C;
|
||||||
@ -60,7 +61,7 @@ static void ARGBTranspose(const uint8* src, int src_stride,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < width; ++i) { // column of source to row of dest.
|
for (i = 0; i < width; ++i) { // column of source to row of dest.
|
||||||
ScaleARGBRowDownEven(src, 0, src_pixel_step, dst, height);
|
ScaleARGBRowDownEven(src, 0, src_pixel_step, dst, height);
|
||||||
dst += dst_stride;
|
dst += dst_stride;
|
||||||
src += 4;
|
src += 4;
|
||||||
@ -92,8 +93,15 @@ void ARGBRotate270(const uint8* src, int src_stride,
|
|||||||
void ARGBRotate180(const uint8* src, int src_stride,
|
void ARGBRotate180(const uint8* src, int src_stride,
|
||||||
uint8* dst, int dst_stride,
|
uint8* dst, int dst_stride,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
|
// Swap first and last row and mirror the content. Uses a temporary row.
|
||||||
|
align_buffer_64(row, width * 4);
|
||||||
|
const uint8* src_bot = src + src_stride * (height - 1);
|
||||||
|
uint8* dst_bot = dst + dst_stride * (height - 1);
|
||||||
|
int half_height = (height + 1) >> 1;
|
||||||
|
int y;
|
||||||
void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) =
|
void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) =
|
||||||
ARGBMirrorRow_C;
|
ARGBMirrorRow_C;
|
||||||
|
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
|
||||||
#if defined(HAS_ARGBMIRRORROW_SSSE3)
|
#if defined(HAS_ARGBMIRRORROW_SSSE3)
|
||||||
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) &&
|
if (TestCpuFlag(kCpuHasSSSE3) && IS_ALIGNED(width, 4) &&
|
||||||
IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16) &&
|
IS_ALIGNED(src, 16) && IS_ALIGNED(src_stride, 16) &&
|
||||||
@ -111,7 +119,6 @@ void ARGBRotate180(const uint8* src, int src_stride,
|
|||||||
ARGBMirrorRow = ARGBMirrorRow_NEON;
|
ARGBMirrorRow = ARGBMirrorRow_NEON;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C;
|
|
||||||
#if defined(HAS_COPYROW_NEON)
|
#if defined(HAS_COPYROW_NEON)
|
||||||
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width * 4, 32)) {
|
if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width * 4, 32)) {
|
||||||
CopyRow = CopyRow_NEON;
|
CopyRow = CopyRow_NEON;
|
||||||
@ -140,13 +147,8 @@ void ARGBRotate180(const uint8* src, int src_stride,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Swap first and last row and mirror the content. Uses a temporary row.
|
|
||||||
align_buffer_64(row, width * 4);
|
|
||||||
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.
|
// Odd height will harmlessly mirror the middle row twice.
|
||||||
for (int y = 0; y < half_height; ++y) {
|
for (y = 0; y < half_height; ++y) {
|
||||||
ARGBMirrorRow(src, row, width); // Mirror first row into a buffer
|
ARGBMirrorRow(src, row, width); // Mirror first row into a buffer
|
||||||
ARGBMirrorRow(src_bot, dst, width); // Mirror last row into first row
|
ARGBMirrorRow(src_bot, dst, width); // Mirror last row into first row
|
||||||
CopyRow(row, dst_bot, width * 4); // Copy first mirrored row into last
|
CopyRow(row, dst_bot, width * 4); // Copy first mirrored row into last
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user