OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The LibYuv Project Authors. All rights reserved. | 2 * Copyright 2012 The LibYuv Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "libyuv/rotate.h" | 11 #include "libyuv/rotate.h" |
12 | 12 |
13 #include "libyuv/cpu_id.h" | 13 #include "libyuv/cpu_id.h" |
14 #include "libyuv/convert.h" | 14 #include "libyuv/convert.h" |
15 #include "libyuv/planar_functions.h" | 15 #include "libyuv/planar_functions.h" |
16 #include "libyuv/row.h" | 16 #include "libyuv/row.h" |
17 | 17 |
18 #ifdef __cplusplus | 18 #ifdef __cplusplus |
19 namespace libyuv { | 19 namespace libyuv { |
20 extern "C" { | 20 extern "C" { |
21 #endif | 21 #endif |
22 | 22 |
23 // ARGBScale has a function to copy pixels to a row, striding each source | 23 // ARGBScale has a function to copy pixels to a row, striding each source |
24 // pixel by a constant. | 24 // pixel by a constant. |
25 #if !defined(LIBYUV_DISABLE_X86) && \ | 25 #if !defined(LIBYUV_DISABLE_X86) && \ |
26 (defined(_M_IX86) || \ | 26 (defined(_M_IX86) || \ |
27 (defined(__x86_64__) && !defined(__native_client__)) || defined(__i386__)) | 27 (defined(__x86_64__) && !defined(__native_client__)) || defined(__i386__)) |
28 #define HAS_SCALEARGBROWDOWNEVEN_SSE2 | 28 #define HAS_SCALEARGBROWDOWNEVEN_SSE2 |
29 void ScaleARGBRowDownEven_SSE2(const uint8* src_ptr, int src_stride, | 29 void ScaleARGBRowDownEven_SSE2(const uint8* src_ptr, int src_stride, |
30 int src_stepx, | 30 int src_stepx, uint8* dst_ptr, int dst_width); |
31 uint8* dst_ptr, int dst_width); | |
32 #endif | 31 #endif |
33 #if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \ | 32 #if !defined(LIBYUV_DISABLE_NEON) && !defined(__native_client__) && \ |
34 (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) | 33 (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) |
35 #define HAS_SCALEARGBROWDOWNEVEN_NEON | 34 #define HAS_SCALEARGBROWDOWNEVEN_NEON |
36 void ScaleARGBRowDownEven_NEON(const uint8* src_ptr, int src_stride, | 35 void ScaleARGBRowDownEven_NEON(const uint8* src_ptr, int src_stride, |
37 int src_stepx, | 36 int src_stepx, uint8* dst_ptr, int dst_width); |
38 uint8* dst_ptr, int dst_width); | |
39 #endif | 37 #endif |
40 | 38 |
41 void ScaleARGBRowDownEven_C(const uint8* src_ptr, int, | 39 void ScaleARGBRowDownEven_C(const uint8* src_ptr, int, |
42 int src_stepx, | 40 int src_stepx, uint8* dst_ptr, int dst_width); |
43 uint8* dst_ptr, int dst_width); | |
44 | 41 |
45 static void ARGBTranspose(const uint8* src, int src_stride, | 42 static void ARGBTranspose(const uint8* src, int src_stride, |
46 uint8* dst, int dst_stride, | 43 uint8* dst, int dst_stride, int width, int height) { |
47 int width, int height) { | |
48 int i; | 44 int i; |
49 int src_pixel_step = src_stride >> 2; | 45 int src_pixel_step = src_stride >> 2; |
50 void (*ScaleARGBRowDownEven)(const uint8* src_ptr, int src_stride, | 46 void (*ScaleARGBRowDownEven)(const uint8* src_ptr, int src_stride, |
51 int src_step, uint8* dst_ptr, int dst_width) = ScaleARGBRowDownEven_C; | 47 int src_step, uint8* dst_ptr, int dst_width) = ScaleARGBRowDownEven_C; |
52 #if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) | 48 #if defined(HAS_SCALEARGBROWDOWNEVEN_SSE2) |
53 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(height, 4)) { // Width of dest. | 49 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(height, 4)) { // Width of dest. |
54 ScaleARGBRowDownEven = ScaleARGBRowDownEven_SSE2; | 50 ScaleARGBRowDownEven = ScaleARGBRowDownEven_SSE2; |
55 } | 51 } |
56 #endif | 52 #endif |
57 #if defined(HAS_SCALEARGBROWDOWNEVEN_NEON) | 53 #if defined(HAS_SCALEARGBROWDOWNEVEN_NEON) |
58 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(height, 4)) { // Width of dest. | 54 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(height, 4)) { // Width of dest. |
59 ScaleARGBRowDownEven = ScaleARGBRowDownEven_NEON; | 55 ScaleARGBRowDownEven = ScaleARGBRowDownEven_NEON; |
60 } | 56 } |
61 #endif | 57 #endif |
62 | 58 |
63 for (i = 0; i < width; ++i) { // column of source to row of dest. | 59 for (i = 0; i < width; ++i) { // column of source to row of dest. |
64 ScaleARGBRowDownEven(src, 0, src_pixel_step, dst, height); | 60 ScaleARGBRowDownEven(src, 0, src_pixel_step, dst, height); |
65 dst += dst_stride; | 61 dst += dst_stride; |
66 src += 4; | 62 src += 4; |
67 } | 63 } |
68 } | 64 } |
69 | 65 |
70 void ARGBRotate90(const uint8* src, int src_stride, | 66 void ARGBRotate90(const uint8* src, int src_stride, |
71 uint8* dst, int dst_stride, | 67 uint8* dst, int dst_stride, int width, int height) { |
72 int width, int height) { | |
73 // Rotate by 90 is a ARGBTranspose with the source read | 68 // Rotate by 90 is a ARGBTranspose with the source read |
74 // from bottom to top. So set the source pointer to the end | 69 // from bottom to top. So set the source pointer to the end |
75 // of the buffer and flip the sign of the source stride. | 70 // of the buffer and flip the sign of the source stride. |
76 src += src_stride * (height - 1); | 71 src += src_stride * (height - 1); |
77 src_stride = -src_stride; | 72 src_stride = -src_stride; |
78 ARGBTranspose(src, src_stride, dst, dst_stride, width, height); | 73 ARGBTranspose(src, src_stride, dst, dst_stride, width, height); |
79 } | 74 } |
80 | 75 |
81 void ARGBRotate270(const uint8* src, int src_stride, | 76 void ARGBRotate270(const uint8* src, int src_stride, |
82 uint8* dst, int dst_stride, | 77 uint8* dst, int dst_stride, int width, int height) { |
83 int width, int height) { | |
84 // Rotate by 270 is a ARGBTranspose with the destination written | 78 // Rotate by 270 is a ARGBTranspose with the destination written |
85 // from bottom to top. So set the destination pointer to the end | 79 // from bottom to top. So set the destination pointer to the end |
86 // of the buffer and flip the sign of the destination stride. | 80 // of the buffer and flip the sign of the destination stride. |
87 dst += dst_stride * (width - 1); | 81 dst += dst_stride * (width - 1); |
88 dst_stride = -dst_stride; | 82 dst_stride = -dst_stride; |
89 ARGBTranspose(src, src_stride, dst, dst_stride, width, height); | 83 ARGBTranspose(src, src_stride, dst, dst_stride, width, height); |
90 } | 84 } |
91 | 85 |
92 void ARGBRotate180(const uint8* src, int src_stride, | 86 void ARGBRotate180(const uint8* src, int src_stride, |
93 uint8* dst, int dst_stride, | 87 uint8* dst, int dst_stride, int width, int height) { |
94 int width, int height) { | |
95 // Swap first and last row and mirror the content. Uses a temporary row. | 88 // Swap first and last row and mirror the content. Uses a temporary row. |
96 align_buffer_64(row, width * 4); | 89 align_buffer_64(row, width * 4); |
97 const uint8* src_bot = src + src_stride * (height - 1); | 90 const uint8* src_bot = src + src_stride * (height - 1); |
98 uint8* dst_bot = dst + dst_stride * (height - 1); | 91 uint8* dst_bot = dst + dst_stride * (height - 1); |
99 int half_height = (height + 1) >> 1; | 92 int half_height = (height + 1) >> 1; |
100 int y; | 93 int y; |
101 void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = | 94 void (*ARGBMirrorRow)(const uint8* src, uint8* dst, int width) = |
102 ARGBMirrorRow_C; | 95 ARGBMirrorRow_C; |
103 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; | 96 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; |
104 #if defined(HAS_ARGBMIRRORROW_NEON) | 97 #if defined(HAS_ARGBMIRRORROW_NEON) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 src += src_stride; | 152 src += src_stride; |
160 dst += dst_stride; | 153 dst += dst_stride; |
161 src_bot -= src_stride; | 154 src_bot -= src_stride; |
162 dst_bot -= dst_stride; | 155 dst_bot -= dst_stride; |
163 } | 156 } |
164 free_aligned_buffer_64(row); | 157 free_aligned_buffer_64(row); |
165 } | 158 } |
166 | 159 |
167 LIBYUV_API | 160 LIBYUV_API |
168 int ARGBRotate(const uint8* src_argb, int src_stride_argb, | 161 int ARGBRotate(const uint8* src_argb, int src_stride_argb, |
169 uint8* dst_argb, int dst_stride_argb, | 162 uint8* dst_argb, int dst_stride_argb, int width, int height, |
170 int width, int height, | |
171 enum RotationMode mode) { | 163 enum RotationMode mode) { |
172 if (!src_argb || width <= 0 || height == 0 || !dst_argb) { | 164 if (!src_argb || width <= 0 || height == 0 || !dst_argb) { |
173 return -1; | 165 return -1; |
174 } | 166 } |
175 | 167 |
176 // Negative height means invert the image. | 168 // Negative height means invert the image. |
177 if (height < 0) { | 169 if (height < 0) { |
178 height = -height; | 170 height = -height; |
179 src_argb = src_argb + (height - 1) * src_stride_argb; | 171 src_argb = src_argb + (height - 1) * src_stride_argb; |
180 src_stride_argb = -src_stride_argb; | 172 src_stride_argb = -src_stride_argb; |
(...skipping 23 matching lines...) Expand all Loading... |
204 default: | 196 default: |
205 break; | 197 break; |
206 } | 198 } |
207 return -1; | 199 return -1; |
208 } | 200 } |
209 | 201 |
210 #ifdef __cplusplus | 202 #ifdef __cplusplus |
211 } // extern "C" | 203 } // extern "C" |
212 } // namespace libyuv | 204 } // namespace libyuv |
213 #endif | 205 #endif |
OLD | NEW |