OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The LibYuv Project Authors. All rights reserved. | 2 * Copyright 2011 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 |
(...skipping 13 matching lines...) Expand all Loading... |
24 extern "C" { | 24 extern "C" { |
25 #endif | 25 #endif |
26 | 26 |
27 // Copy a plane of data | 27 // Copy a plane of data |
28 LIBYUV_API | 28 LIBYUV_API |
29 void CopyPlane(const uint8* src_y, int src_stride_y, | 29 void CopyPlane(const uint8* src_y, int src_stride_y, |
30 uint8* dst_y, int dst_stride_y, | 30 uint8* dst_y, int dst_stride_y, |
31 int width, int height) { | 31 int width, int height) { |
32 int y; | 32 int y; |
33 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; | 33 void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; |
| 34 // Negative height means invert the image. |
| 35 if (height < 0) { |
| 36 height = -height; |
| 37 dst_y = dst_y + (height - 1) * dst_stride_y; |
| 38 dst_stride_y = -dst_stride_y; |
| 39 } |
34 // Coalesce rows. | 40 // Coalesce rows. |
35 if (src_stride_y == width && | 41 if (src_stride_y == width && |
36 dst_stride_y == width) { | 42 dst_stride_y == width) { |
37 width *= height; | 43 width *= height; |
38 height = 1; | 44 height = 1; |
39 src_stride_y = dst_stride_y = 0; | 45 src_stride_y = dst_stride_y = 0; |
40 } | 46 } |
41 // Nothing to do. | 47 // Nothing to do. |
42 if (src_y == dst_y && src_stride_y == dst_stride_y) { | 48 if (src_y == dst_y && src_stride_y == dst_stride_y) { |
43 return; | 49 return; |
(...skipping 25 matching lines...) Expand all Loading... |
69 #endif | 75 #endif |
70 | 76 |
71 // Copy plane | 77 // Copy plane |
72 for (y = 0; y < height; ++y) { | 78 for (y = 0; y < height; ++y) { |
73 CopyRow(src_y, dst_y, width); | 79 CopyRow(src_y, dst_y, width); |
74 src_y += src_stride_y; | 80 src_y += src_stride_y; |
75 dst_y += dst_stride_y; | 81 dst_y += dst_stride_y; |
76 } | 82 } |
77 } | 83 } |
78 | 84 |
| 85 // TODO(fbarchard): Consider support for negative height. |
79 LIBYUV_API | 86 LIBYUV_API |
80 void CopyPlane_16(const uint16* src_y, int src_stride_y, | 87 void CopyPlane_16(const uint16* src_y, int src_stride_y, |
81 uint16* dst_y, int dst_stride_y, | 88 uint16* dst_y, int dst_stride_y, |
82 int width, int height) { | 89 int width, int height) { |
83 int y; | 90 int y; |
84 void (*CopyRow)(const uint16* src, uint16* dst, int width) = CopyRow_16_C; | 91 void (*CopyRow)(const uint16* src, uint16* dst, int width) = CopyRow_16_C; |
85 // Coalesce rows. | 92 // Coalesce rows. |
86 if (src_stride_y == width && | 93 if (src_stride_y == width && |
87 dst_stride_y == width) { | 94 dst_stride_y == width) { |
88 width *= height; | 95 width *= height; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 if (height < 0) { | 224 if (height < 0) { |
218 height = -height; | 225 height = -height; |
219 src_y = src_y + (height - 1) * src_stride_y; | 226 src_y = src_y + (height - 1) * src_stride_y; |
220 src_stride_y = -src_stride_y; | 227 src_stride_y = -src_stride_y; |
221 } | 228 } |
222 | 229 |
223 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); | 230 CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); |
224 return 0; | 231 return 0; |
225 } | 232 } |
226 | 233 |
| 234 // Support function for NV12 etc UV channels. |
| 235 // Width and height are plane sizes (typically half pixel width). |
| 236 LIBYUV_API |
| 237 void SplitUVPlane(const uint8* src_uv, int src_stride_uv, |
| 238 uint8* dst_u, int dst_stride_u, |
| 239 uint8* dst_v, int dst_stride_v, |
| 240 int width, int height) { |
| 241 int y; |
| 242 void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, |
| 243 int width) = SplitUVRow_C; |
| 244 // Negative height means invert the image. |
| 245 if (height < 0) { |
| 246 height = -height; |
| 247 dst_u = dst_u + (height - 1) * dst_stride_u; |
| 248 dst_v = dst_v + (height - 1) * dst_stride_v; |
| 249 dst_stride_u = -dst_stride_u; |
| 250 dst_stride_v = -dst_stride_v; |
| 251 } |
| 252 // Coalesce rows. |
| 253 if (src_stride_uv == width * 2 && |
| 254 dst_stride_u == width && |
| 255 dst_stride_v == width) { |
| 256 width *= height; |
| 257 height = 1; |
| 258 src_stride_uv = dst_stride_u = dst_stride_v = 0; |
| 259 } |
| 260 #if defined(HAS_SPLITUVROW_SSE2) |
| 261 if (TestCpuFlag(kCpuHasSSE2)) { |
| 262 SplitUVRow = SplitUVRow_Any_SSE2; |
| 263 if (IS_ALIGNED(width, 16)) { |
| 264 SplitUVRow = SplitUVRow_SSE2; |
| 265 } |
| 266 } |
| 267 #endif |
| 268 #if defined(HAS_SPLITUVROW_AVX2) |
| 269 if (TestCpuFlag(kCpuHasAVX2)) { |
| 270 SplitUVRow = SplitUVRow_Any_AVX2; |
| 271 if (IS_ALIGNED(width, 32)) { |
| 272 SplitUVRow = SplitUVRow_AVX2; |
| 273 } |
| 274 } |
| 275 #endif |
| 276 #if defined(HAS_SPLITUVROW_NEON) |
| 277 if (TestCpuFlag(kCpuHasNEON)) { |
| 278 SplitUVRow = SplitUVRow_Any_NEON; |
| 279 if (IS_ALIGNED(width, 16)) { |
| 280 SplitUVRow = SplitUVRow_NEON; |
| 281 } |
| 282 } |
| 283 #endif |
| 284 #if defined(HAS_SPLITUVROW_DSPR2) |
| 285 if (TestCpuFlag(kCpuHasDSPR2) && |
| 286 IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) && |
| 287 IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) { |
| 288 SplitUVRow = SplitUVRow_Any_DSPR2; |
| 289 if (IS_ALIGNED(width, 16)) { |
| 290 SplitUVRow = SplitUVRow_DSPR2; |
| 291 } |
| 292 } |
| 293 #endif |
| 294 |
| 295 for (y = 0; y < height; ++y) { |
| 296 // Copy a row of UV. |
| 297 SplitUVRow(src_uv, dst_u, dst_v, width); |
| 298 dst_u += dst_stride_u; |
| 299 dst_v += dst_stride_v; |
| 300 src_uv += src_stride_uv; |
| 301 } |
| 302 } |
| 303 |
| 304 LIBYUV_API |
| 305 void MergeUVPlane(const uint8* src_u, int src_stride_u, |
| 306 const uint8* src_v, int src_stride_v, |
| 307 uint8* dst_uv, int dst_stride_uv, |
| 308 int width, int height) { |
| 309 int y; |
| 310 void (*MergeUVRow)(const uint8* src_u, const uint8* src_v, uint8* dst_uv, |
| 311 int width) = MergeUVRow_C; |
| 312 // Coalesce rows. |
| 313 // Negative height means invert the image. |
| 314 if (height < 0) { |
| 315 height = -height; |
| 316 dst_uv = dst_uv + (height - 1) * dst_stride_uv; |
| 317 dst_stride_uv = -dst_stride_uv; |
| 318 } |
| 319 // Coalesce rows. |
| 320 if (src_stride_u == width && |
| 321 src_stride_v == width && |
| 322 dst_stride_uv == width * 2) { |
| 323 width *= height; |
| 324 height = 1; |
| 325 src_stride_u = src_stride_v = dst_stride_uv = 0; |
| 326 } |
| 327 #if defined(HAS_MERGEUVROW_SSE2) |
| 328 if (TestCpuFlag(kCpuHasSSE2)) { |
| 329 MergeUVRow = MergeUVRow_Any_SSE2; |
| 330 if (IS_ALIGNED(width, 16)) { |
| 331 MergeUVRow = MergeUVRow_SSE2; |
| 332 } |
| 333 } |
| 334 #endif |
| 335 #if defined(HAS_MERGEUVROW_AVX2) |
| 336 if (TestCpuFlag(kCpuHasAVX2)) { |
| 337 MergeUVRow = MergeUVRow_Any_AVX2; |
| 338 if (IS_ALIGNED(width, 32)) { |
| 339 MergeUVRow = MergeUVRow_AVX2; |
| 340 } |
| 341 } |
| 342 #endif |
| 343 #if defined(HAS_MERGEUVROW_NEON) |
| 344 if (TestCpuFlag(kCpuHasNEON)) { |
| 345 MergeUVRow = MergeUVRow_Any_NEON; |
| 346 if (IS_ALIGNED(width, 16)) { |
| 347 MergeUVRow = MergeUVRow_NEON; |
| 348 } |
| 349 } |
| 350 #endif |
| 351 |
| 352 for (y = 0; y < height; ++y) { |
| 353 // Merge a row of U and V into a row of UV. |
| 354 MergeUVRow(src_u, src_v, dst_uv, width); |
| 355 src_u += src_stride_u; |
| 356 src_v += src_stride_v; |
| 357 dst_uv += dst_stride_uv; |
| 358 } |
| 359 } |
| 360 |
227 // Mirror a plane of data. | 361 // Mirror a plane of data. |
228 void MirrorPlane(const uint8* src_y, int src_stride_y, | 362 void MirrorPlane(const uint8* src_y, int src_stride_y, |
229 uint8* dst_y, int dst_stride_y, | 363 uint8* dst_y, int dst_stride_y, |
230 int width, int height) { | 364 int width, int height) { |
231 int y; | 365 int y; |
232 void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; | 366 void (*MirrorRow)(const uint8* src, uint8* dst, int width) = MirrorRow_C; |
233 // Negative height means invert the image. | 367 // Negative height means invert the image. |
234 if (height < 0) { | 368 if (height < 0) { |
235 height = -height; | 369 height = -height; |
236 src_y = src_y + (height - 1) * src_stride_y; | 370 src_y = src_y + (height - 1) * src_stride_y; |
(...skipping 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 } | 2802 } |
2669 free_aligned_buffer_64(rows); | 2803 free_aligned_buffer_64(rows); |
2670 } | 2804 } |
2671 return 0; | 2805 return 0; |
2672 } | 2806 } |
2673 | 2807 |
2674 #ifdef __cplusplus | 2808 #ifdef __cplusplus |
2675 } // extern "C" | 2809 } // extern "C" |
2676 } // namespace libyuv | 2810 } // namespace libyuv |
2677 #endif | 2811 #endif |
OLD | NEW |