| 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 |
| 11 #include "libyuv/scale.h" | 11 #include "libyuv/scale.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 | 15 |
| 16 #include "libyuv/cpu_id.h" | 16 #include "libyuv/cpu_id.h" |
| 17 #include "libyuv/planar_functions.h" // For CopyPlane | 17 #include "libyuv/planar_functions.h" // For CopyPlane |
| 18 #include "libyuv/row.h" | 18 #include "libyuv/row.h" |
| 19 #include "libyuv/scale_row.h" | 19 #include "libyuv/scale_row.h" |
| 20 | 20 |
| 21 #ifdef __cplusplus | 21 #ifdef __cplusplus |
| 22 namespace libyuv { | 22 namespace libyuv { |
| 23 extern "C" { | 23 extern "C" { |
| 24 #endif | 24 #endif |
| 25 | 25 |
| 26 // Remove this macro if OVERREAD is safe. | |
| 27 #define AVOID_OVERREAD 1 | |
| 28 | |
| 29 static __inline int Abs(int v) { | 26 static __inline int Abs(int v) { |
| 30 return v >= 0 ? v : -v; | 27 return v >= 0 ? v : -v; |
| 31 } | 28 } |
| 32 | 29 |
| 33 #define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) | 30 #define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) |
| 34 | 31 |
| 35 // Scale plane, 1/2 | 32 // Scale plane, 1/2 |
| 36 // This is an optimized version for scaling down a plane to 1/2 of | 33 // This is an optimized version for scaling down a plane to 1/2 of |
| 37 // its original size. | 34 // its original size. |
| 38 | 35 |
| 39 static void ScalePlaneDown2(int src_width, int src_height, | 36 static void ScalePlaneDown2(int src_width, int src_height, |
| 40 int dst_width, int dst_height, | 37 int dst_width, int dst_height, |
| 41 int src_stride, int dst_stride, | 38 int src_stride, int dst_stride, |
| 42 const uint8* src_ptr, uint8* dst_ptr, | 39 const uint8* src_ptr, uint8* dst_ptr, |
| 43 enum FilterMode filtering) { | 40 enum FilterMode filtering) { |
| 44 int y; | 41 int y; |
| 45 void (*ScaleRowDown2)(const uint8* src_ptr, ptrdiff_t src_stride, | 42 void (*ScaleRowDown2)(const uint8* src_ptr, ptrdiff_t src_stride, |
| 46 uint8* dst_ptr, int dst_width) = | 43 uint8* dst_ptr, int dst_width) = |
| 47 filtering == kFilterNone ? ScaleRowDown2_C : | 44 filtering == kFilterNone ? ScaleRowDown2_C : |
| 48 (filtering == kFilterLinear ? ScaleRowDown2Linear_C : | 45 (filtering == kFilterLinear ? ScaleRowDown2Linear_C : ScaleRowDown2Box_C); |
| 49 ScaleRowDown2Box_C); | |
| 50 int row_stride = src_stride << 1; | 46 int row_stride = src_stride << 1; |
| 51 if (!filtering) { | 47 if (!filtering) { |
| 52 src_ptr += src_stride; // Point to odd rows. | 48 src_ptr += src_stride; // Point to odd rows. |
| 53 src_stride = 0; | 49 src_stride = 0; |
| 54 } | 50 } |
| 55 | 51 |
| 56 #if defined(HAS_SCALEROWDOWN2_NEON) | 52 #if defined(HAS_SCALEROWDOWN2_NEON) |
| 57 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 16)) { | 53 if (TestCpuFlag(kCpuHasNEON)) { |
| 58 ScaleRowDown2 = filtering ? ScaleRowDown2Box_NEON : ScaleRowDown2_NEON; | 54 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_Any_NEON : |
| 55 (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_NEON : |
| 56 ScaleRowDown2Box_Any_NEON); |
| 57 if (IS_ALIGNED(dst_width, 16)) { |
| 58 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_NEON : |
| 59 (filtering == kFilterLinear ? ScaleRowDown2Linear_NEON : |
| 60 ScaleRowDown2Box_NEON); |
| 61 } |
| 59 } | 62 } |
| 60 #endif | 63 #endif |
| 61 #if defined(HAS_SCALEROWDOWN2_SSE2) | 64 #if defined(HAS_SCALEROWDOWN2_SSE2) |
| 62 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 16)) { | 65 if (TestCpuFlag(kCpuHasSSE2)) { |
| 63 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_SSE2 : | 66 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_Any_SSE2 : |
| 64 (filtering == kFilterLinear ? ScaleRowDown2Linear_SSE2 : | 67 (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_SSE2 : |
| 65 ScaleRowDown2Box_SSE2); | 68 ScaleRowDown2Box_Any_SSE2); |
| 69 if (IS_ALIGNED(dst_width, 16)) { |
| 70 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_SSE2 : |
| 71 (filtering == kFilterLinear ? ScaleRowDown2Linear_SSE2 : |
| 72 ScaleRowDown2Box_SSE2); |
| 73 } |
| 74 } |
| 75 #endif |
| 76 #if defined(HAS_SCALEROWDOWN2_AVX2) |
| 77 if (TestCpuFlag(kCpuHasAVX2)) { |
| 78 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_Any_AVX2 : |
| 79 (filtering == kFilterLinear ? ScaleRowDown2Linear_Any_AVX2 : |
| 80 ScaleRowDown2Box_Any_AVX2); |
| 81 if (IS_ALIGNED(dst_width, 32)) { |
| 82 ScaleRowDown2 = filtering == kFilterNone ? ScaleRowDown2_AVX2 : |
| 83 (filtering == kFilterLinear ? ScaleRowDown2Linear_AVX2 : |
| 84 ScaleRowDown2Box_AVX2); |
| 85 } |
| 66 } | 86 } |
| 67 #endif | 87 #endif |
| 68 #if defined(HAS_SCALEROWDOWN2_MIPS_DSPR2) | 88 #if defined(HAS_SCALEROWDOWN2_MIPS_DSPR2) |
| 69 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_ptr, 4) && | 89 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(src_ptr, 4) && |
| 70 IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) && | 90 IS_ALIGNED(src_stride, 4) && IS_ALIGNED(row_stride, 4) && |
| 71 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { | 91 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { |
| 72 ScaleRowDown2 = filtering ? | 92 ScaleRowDown2 = filtering ? |
| 73 ScaleRowDown2Box_MIPS_DSPR2 : ScaleRowDown2_MIPS_DSPR2; | 93 ScaleRowDown2Box_MIPS_DSPR2 : ScaleRowDown2_MIPS_DSPR2; |
| 74 } | 94 } |
| 75 #endif | 95 #endif |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 int y; | 167 int y; |
| 148 void (*ScaleRowDown4)(const uint8* src_ptr, ptrdiff_t src_stride, | 168 void (*ScaleRowDown4)(const uint8* src_ptr, ptrdiff_t src_stride, |
| 149 uint8* dst_ptr, int dst_width) = | 169 uint8* dst_ptr, int dst_width) = |
| 150 filtering ? ScaleRowDown4Box_C : ScaleRowDown4_C; | 170 filtering ? ScaleRowDown4Box_C : ScaleRowDown4_C; |
| 151 int row_stride = src_stride << 2; | 171 int row_stride = src_stride << 2; |
| 152 if (!filtering) { | 172 if (!filtering) { |
| 153 src_ptr += src_stride * 2; // Point to row 2. | 173 src_ptr += src_stride * 2; // Point to row 2. |
| 154 src_stride = 0; | 174 src_stride = 0; |
| 155 } | 175 } |
| 156 #if defined(HAS_SCALEROWDOWN4_NEON) | 176 #if defined(HAS_SCALEROWDOWN4_NEON) |
| 157 if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(dst_width, 8)) { | 177 if (TestCpuFlag(kCpuHasNEON)) { |
| 158 ScaleRowDown4 = filtering ? ScaleRowDown4Box_NEON : ScaleRowDown4_NEON; | 178 ScaleRowDown4 = filtering ? |
| 179 ScaleRowDown4Box_Any_NEON : ScaleRowDown4_Any_NEON; |
| 180 if (IS_ALIGNED(dst_width, 8)) { |
| 181 ScaleRowDown4 = filtering ? ScaleRowDown4Box_NEON : ScaleRowDown4_NEON; |
| 182 } |
| 159 } | 183 } |
| 160 #endif | 184 #endif |
| 161 #if defined(HAS_SCALEROWDOWN4_SSE2) | 185 #if defined(HAS_SCALEROWDOWN4_SSE2) |
| 162 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { | 186 if (TestCpuFlag(kCpuHasSSE2)) { |
| 163 ScaleRowDown4 = filtering ? ScaleRowDown4Box_SSE2 : ScaleRowDown4_SSE2; | 187 ScaleRowDown4 = filtering ? |
| 188 ScaleRowDown4Box_Any_SSE2 : ScaleRowDown4_Any_SSE2; |
| 189 if (IS_ALIGNED(dst_width, 8)) { |
| 190 ScaleRowDown4 = filtering ? ScaleRowDown4Box_SSE2 : ScaleRowDown4_SSE2; |
| 191 } |
| 192 } |
| 193 #endif |
| 194 #if defined(HAS_SCALEROWDOWN4_AVX2) |
| 195 if (TestCpuFlag(kCpuHasAVX2)) { |
| 196 ScaleRowDown4 = filtering ? |
| 197 ScaleRowDown4Box_Any_AVX2 : ScaleRowDown4_Any_AVX2; |
| 198 if (IS_ALIGNED(dst_width, 16)) { |
| 199 ScaleRowDown4 = filtering ? ScaleRowDown4Box_AVX2 : ScaleRowDown4_AVX2; |
| 200 } |
| 164 } | 201 } |
| 165 #endif | 202 #endif |
| 166 #if defined(HAS_SCALEROWDOWN4_MIPS_DSPR2) | 203 #if defined(HAS_SCALEROWDOWN4_MIPS_DSPR2) |
| 167 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(row_stride, 4) && | 204 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(row_stride, 4) && |
| 168 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && | 205 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && |
| 169 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { | 206 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { |
| 170 ScaleRowDown4 = filtering ? | 207 ScaleRowDown4 = filtering ? |
| 171 ScaleRowDown4Box_MIPS_DSPR2 : ScaleRowDown4_MIPS_DSPR2; | 208 ScaleRowDown4Box_MIPS_DSPR2 : ScaleRowDown4_MIPS_DSPR2; |
| 172 } | 209 } |
| 173 #endif | 210 #endif |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; | 279 const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; |
| 243 assert(dst_width % 3 == 0); | 280 assert(dst_width % 3 == 0); |
| 244 if (!filtering) { | 281 if (!filtering) { |
| 245 ScaleRowDown34_0 = ScaleRowDown34_C; | 282 ScaleRowDown34_0 = ScaleRowDown34_C; |
| 246 ScaleRowDown34_1 = ScaleRowDown34_C; | 283 ScaleRowDown34_1 = ScaleRowDown34_C; |
| 247 } else { | 284 } else { |
| 248 ScaleRowDown34_0 = ScaleRowDown34_0_Box_C; | 285 ScaleRowDown34_0 = ScaleRowDown34_0_Box_C; |
| 249 ScaleRowDown34_1 = ScaleRowDown34_1_Box_C; | 286 ScaleRowDown34_1 = ScaleRowDown34_1_Box_C; |
| 250 } | 287 } |
| 251 #if defined(HAS_SCALEROWDOWN34_NEON) | 288 #if defined(HAS_SCALEROWDOWN34_NEON) |
| 252 if (TestCpuFlag(kCpuHasNEON) && (dst_width % 24 == 0)) { | 289 if (TestCpuFlag(kCpuHasNEON)) { |
| 253 if (!filtering) { | 290 if (!filtering) { |
| 254 ScaleRowDown34_0 = ScaleRowDown34_NEON; | 291 ScaleRowDown34_0 = ScaleRowDown34_Any_NEON; |
| 255 ScaleRowDown34_1 = ScaleRowDown34_NEON; | 292 ScaleRowDown34_1 = ScaleRowDown34_Any_NEON; |
| 256 } else { | 293 } else { |
| 257 ScaleRowDown34_0 = ScaleRowDown34_0_Box_NEON; | 294 ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_NEON; |
| 258 ScaleRowDown34_1 = ScaleRowDown34_1_Box_NEON; | 295 ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_NEON; |
| 296 } |
| 297 if (dst_width % 24 == 0) { |
| 298 if (!filtering) { |
| 299 ScaleRowDown34_0 = ScaleRowDown34_NEON; |
| 300 ScaleRowDown34_1 = ScaleRowDown34_NEON; |
| 301 } else { |
| 302 ScaleRowDown34_0 = ScaleRowDown34_0_Box_NEON; |
| 303 ScaleRowDown34_1 = ScaleRowDown34_1_Box_NEON; |
| 304 } |
| 259 } | 305 } |
| 260 } | 306 } |
| 261 #endif | 307 #endif |
| 262 #if defined(HAS_SCALEROWDOWN34_SSSE3) | 308 #if defined(HAS_SCALEROWDOWN34_SSSE3) |
| 263 if (TestCpuFlag(kCpuHasSSSE3) && (dst_width % 24 == 0)) { | 309 if (TestCpuFlag(kCpuHasSSSE3)) { |
| 264 if (!filtering) { | 310 if (!filtering) { |
| 265 ScaleRowDown34_0 = ScaleRowDown34_SSSE3; | 311 ScaleRowDown34_0 = ScaleRowDown34_Any_SSSE3; |
| 266 ScaleRowDown34_1 = ScaleRowDown34_SSSE3; | 312 ScaleRowDown34_1 = ScaleRowDown34_Any_SSSE3; |
| 267 } else { | 313 } else { |
| 268 ScaleRowDown34_0 = ScaleRowDown34_0_Box_SSSE3; | 314 ScaleRowDown34_0 = ScaleRowDown34_0_Box_Any_SSSE3; |
| 269 ScaleRowDown34_1 = ScaleRowDown34_1_Box_SSSE3; | 315 ScaleRowDown34_1 = ScaleRowDown34_1_Box_Any_SSSE3; |
| 316 } |
| 317 if (dst_width % 24 == 0) { |
| 318 if (!filtering) { |
| 319 ScaleRowDown34_0 = ScaleRowDown34_SSSE3; |
| 320 ScaleRowDown34_1 = ScaleRowDown34_SSSE3; |
| 321 } else { |
| 322 ScaleRowDown34_0 = ScaleRowDown34_0_Box_SSSE3; |
| 323 ScaleRowDown34_1 = ScaleRowDown34_1_Box_SSSE3; |
| 324 } |
| 270 } | 325 } |
| 271 } | 326 } |
| 272 #endif | 327 #endif |
| 273 #if defined(HAS_SCALEROWDOWN34_MIPS_DSPR2) | 328 #if defined(HAS_SCALEROWDOWN34_MIPS_DSPR2) |
| 274 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 24 == 0) && | 329 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 24 == 0) && |
| 275 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && | 330 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && |
| 276 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { | 331 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { |
| 277 if (!filtering) { | 332 if (!filtering) { |
| 278 ScaleRowDown34_0 = ScaleRowDown34_MIPS_DSPR2; | 333 ScaleRowDown34_0 = ScaleRowDown34_MIPS_DSPR2; |
| 279 ScaleRowDown34_1 = ScaleRowDown34_MIPS_DSPR2; | 334 ScaleRowDown34_1 = ScaleRowDown34_MIPS_DSPR2; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 uint8* dst_ptr, int dst_width); | 470 uint8* dst_ptr, int dst_width); |
| 416 const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; | 471 const int filter_stride = (filtering == kFilterLinear) ? 0 : src_stride; |
| 417 assert(dst_width % 3 == 0); | 472 assert(dst_width % 3 == 0); |
| 418 if (!filtering) { | 473 if (!filtering) { |
| 419 ScaleRowDown38_3 = ScaleRowDown38_C; | 474 ScaleRowDown38_3 = ScaleRowDown38_C; |
| 420 ScaleRowDown38_2 = ScaleRowDown38_C; | 475 ScaleRowDown38_2 = ScaleRowDown38_C; |
| 421 } else { | 476 } else { |
| 422 ScaleRowDown38_3 = ScaleRowDown38_3_Box_C; | 477 ScaleRowDown38_3 = ScaleRowDown38_3_Box_C; |
| 423 ScaleRowDown38_2 = ScaleRowDown38_2_Box_C; | 478 ScaleRowDown38_2 = ScaleRowDown38_2_Box_C; |
| 424 } | 479 } |
| 480 |
| 425 #if defined(HAS_SCALEROWDOWN38_NEON) | 481 #if defined(HAS_SCALEROWDOWN38_NEON) |
| 426 if (TestCpuFlag(kCpuHasNEON) && (dst_width % 12 == 0)) { | 482 if (TestCpuFlag(kCpuHasNEON)) { |
| 427 if (!filtering) { | 483 if (!filtering) { |
| 428 ScaleRowDown38_3 = ScaleRowDown38_NEON; | 484 ScaleRowDown38_3 = ScaleRowDown38_Any_NEON; |
| 429 ScaleRowDown38_2 = ScaleRowDown38_NEON; | 485 ScaleRowDown38_2 = ScaleRowDown38_Any_NEON; |
| 430 } else { | 486 } else { |
| 431 ScaleRowDown38_3 = ScaleRowDown38_3_Box_NEON; | 487 ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_NEON; |
| 432 ScaleRowDown38_2 = ScaleRowDown38_2_Box_NEON; | 488 ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_NEON; |
| 489 } |
| 490 if (dst_width % 12 == 0) { |
| 491 if (!filtering) { |
| 492 ScaleRowDown38_3 = ScaleRowDown38_NEON; |
| 493 ScaleRowDown38_2 = ScaleRowDown38_NEON; |
| 494 } else { |
| 495 ScaleRowDown38_3 = ScaleRowDown38_3_Box_NEON; |
| 496 ScaleRowDown38_2 = ScaleRowDown38_2_Box_NEON; |
| 497 } |
| 433 } | 498 } |
| 434 } | 499 } |
| 435 #endif | 500 #endif |
| 436 #if defined(HAS_SCALEROWDOWN38_SSSE3) | 501 #if defined(HAS_SCALEROWDOWN38_SSSE3) |
| 437 if (TestCpuFlag(kCpuHasSSSE3) && (dst_width % 24 == 0)) { | 502 if (TestCpuFlag(kCpuHasSSSE3)) { |
| 438 if (!filtering) { | 503 if (!filtering) { |
| 504 ScaleRowDown38_3 = ScaleRowDown38_Any_SSSE3; |
| 505 ScaleRowDown38_2 = ScaleRowDown38_Any_SSSE3; |
| 506 } else { |
| 507 ScaleRowDown38_3 = ScaleRowDown38_3_Box_Any_SSSE3; |
| 508 ScaleRowDown38_2 = ScaleRowDown38_2_Box_Any_SSSE3; |
| 509 } |
| 510 if (dst_width % 12 == 0 && !filtering) { |
| 439 ScaleRowDown38_3 = ScaleRowDown38_SSSE3; | 511 ScaleRowDown38_3 = ScaleRowDown38_SSSE3; |
| 440 ScaleRowDown38_2 = ScaleRowDown38_SSSE3; | 512 ScaleRowDown38_2 = ScaleRowDown38_SSSE3; |
| 441 } else { | 513 } |
| 514 if (dst_width % 6 == 0 && filtering) { |
| 442 ScaleRowDown38_3 = ScaleRowDown38_3_Box_SSSE3; | 515 ScaleRowDown38_3 = ScaleRowDown38_3_Box_SSSE3; |
| 443 ScaleRowDown38_2 = ScaleRowDown38_2_Box_SSSE3; | 516 ScaleRowDown38_2 = ScaleRowDown38_2_Box_SSSE3; |
| 444 } | 517 } |
| 445 } | 518 } |
| 446 #endif | 519 #endif |
| 447 #if defined(HAS_SCALEROWDOWN38_MIPS_DSPR2) | 520 #if defined(HAS_SCALEROWDOWN38_MIPS_DSPR2) |
| 448 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 12 == 0) && | 521 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && (dst_width % 12 == 0) && |
| 449 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && | 522 IS_ALIGNED(src_ptr, 4) && IS_ALIGNED(src_stride, 4) && |
| 450 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { | 523 IS_ALIGNED(dst_ptr, 4) && IS_ALIGNED(dst_stride, 4)) { |
| 451 if (!filtering) { | 524 if (!filtering) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 if ((dst_height % 3) == 2) { | 625 if ((dst_height % 3) == 2) { |
| 553 ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); | 626 ScaleRowDown38_3(src_ptr, filter_stride, dst_ptr, dst_width); |
| 554 src_ptr += src_stride * 3; | 627 src_ptr += src_stride * 3; |
| 555 dst_ptr += dst_stride; | 628 dst_ptr += dst_stride; |
| 556 ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); | 629 ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); |
| 557 } else if ((dst_height % 3) == 1) { | 630 } else if ((dst_height % 3) == 1) { |
| 558 ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); | 631 ScaleRowDown38_3(src_ptr, 0, dst_ptr, dst_width); |
| 559 } | 632 } |
| 560 } | 633 } |
| 561 | 634 |
| 562 static __inline uint32 SumBox(int iboxwidth, int iboxheight, | 635 #define MIN1(x) ((x) < 1 ? 1 : (x)) |
| 563 ptrdiff_t src_stride, const uint8* src_ptr) { | |
| 564 uint32 sum = 0u; | |
| 565 int y; | |
| 566 assert(iboxwidth > 0); | |
| 567 assert(iboxheight > 0); | |
| 568 for (y = 0; y < iboxheight; ++y) { | |
| 569 int x; | |
| 570 for (x = 0; x < iboxwidth; ++x) { | |
| 571 sum += src_ptr[x]; | |
| 572 } | |
| 573 src_ptr += src_stride; | |
| 574 } | |
| 575 return sum; | |
| 576 } | |
| 577 | |
| 578 static __inline uint32 SumBox_16(int iboxwidth, int iboxheight, | |
| 579 ptrdiff_t src_stride, const uint16* src_ptr) { | |
| 580 uint32 sum = 0u; | |
| 581 int y; | |
| 582 assert(iboxwidth > 0); | |
| 583 assert(iboxheight > 0); | |
| 584 for (y = 0; y < iboxheight; ++y) { | |
| 585 int x; | |
| 586 for (x = 0; x < iboxwidth; ++x) { | |
| 587 sum += src_ptr[x]; | |
| 588 } | |
| 589 src_ptr += src_stride; | |
| 590 } | |
| 591 return sum; | |
| 592 } | |
| 593 | |
| 594 static void ScalePlaneBoxRow_C(int dst_width, int boxheight, | |
| 595 int x, int dx, ptrdiff_t src_stride, | |
| 596 const uint8* src_ptr, uint8* dst_ptr) { | |
| 597 int i; | |
| 598 int boxwidth; | |
| 599 for (i = 0; i < dst_width; ++i) { | |
| 600 int ix = x >> 16; | |
| 601 x += dx; | |
| 602 boxwidth = (x >> 16) - ix; | |
| 603 *dst_ptr++ = SumBox(boxwidth, boxheight, src_stride, src_ptr + ix) / | |
| 604 (boxwidth * boxheight); | |
| 605 } | |
| 606 } | |
| 607 | |
| 608 static void ScalePlaneBoxRow_16_C(int dst_width, int boxheight, | |
| 609 int x, int dx, ptrdiff_t src_stride, | |
| 610 const uint16* src_ptr, uint16* dst_ptr) { | |
| 611 int i; | |
| 612 int boxwidth; | |
| 613 for (i = 0; i < dst_width; ++i) { | |
| 614 int ix = x >> 16; | |
| 615 x += dx; | |
| 616 boxwidth = (x >> 16) - ix; | |
| 617 *dst_ptr++ = SumBox_16(boxwidth, boxheight, src_stride, src_ptr + ix) / | |
| 618 (boxwidth * boxheight); | |
| 619 } | |
| 620 } | |
| 621 | 636 |
| 622 static __inline uint32 SumPixels(int iboxwidth, const uint16* src_ptr) { | 637 static __inline uint32 SumPixels(int iboxwidth, const uint16* src_ptr) { |
| 623 uint32 sum = 0u; | 638 uint32 sum = 0u; |
| 624 int x; | 639 int x; |
| 625 assert(iboxwidth > 0); | 640 assert(iboxwidth > 0); |
| 626 for (x = 0; x < iboxwidth; ++x) { | 641 for (x = 0; x < iboxwidth; ++x) { |
| 627 sum += src_ptr[x]; | 642 sum += src_ptr[x]; |
| 628 } | 643 } |
| 629 return sum; | 644 return sum; |
| 630 } | 645 } |
| 631 | 646 |
| 632 static __inline uint32 SumPixels_16(int iboxwidth, const uint32* src_ptr) { | 647 static __inline uint32 SumPixels_16(int iboxwidth, const uint32* src_ptr) { |
| 633 uint32 sum = 0u; | 648 uint32 sum = 0u; |
| 634 int x; | 649 int x; |
| 635 assert(iboxwidth > 0); | 650 assert(iboxwidth > 0); |
| 636 for (x = 0; x < iboxwidth; ++x) { | 651 for (x = 0; x < iboxwidth; ++x) { |
| 637 sum += src_ptr[x]; | 652 sum += src_ptr[x]; |
| 638 } | 653 } |
| 639 return sum; | 654 return sum; |
| 640 } | 655 } |
| 641 | 656 |
| 642 static void ScaleAddCols2_C(int dst_width, int boxheight, int x, int dx, | 657 static void ScaleAddCols2_C(int dst_width, int boxheight, int x, int dx, |
| 643 const uint16* src_ptr, uint8* dst_ptr) { | 658 const uint16* src_ptr, uint8* dst_ptr) { |
| 644 int i; | 659 int i; |
| 645 int scaletbl[2]; | 660 int scaletbl[2]; |
| 646 int minboxwidth = (dx >> 16); | 661 int minboxwidth = dx >> 16; |
| 647 int* scaleptr = scaletbl - minboxwidth; | 662 int* scaleptr = scaletbl - minboxwidth; |
| 648 int boxwidth; | 663 int boxwidth; |
| 649 scaletbl[0] = 65536 / (minboxwidth * boxheight); | 664 scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight); |
| 650 scaletbl[1] = 65536 / ((minboxwidth + 1) * boxheight); | 665 scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight); |
| 651 for (i = 0; i < dst_width; ++i) { | 666 for (i = 0; i < dst_width; ++i) { |
| 652 int ix = x >> 16; | 667 int ix = x >> 16; |
| 653 x += dx; | 668 x += dx; |
| 654 boxwidth = (x >> 16) - ix; | 669 boxwidth = MIN1((x >> 16) - ix); |
| 655 *dst_ptr++ = SumPixels(boxwidth, src_ptr + ix) * scaleptr[boxwidth] >> 16; | 670 *dst_ptr++ = SumPixels(boxwidth, src_ptr + ix) * scaleptr[boxwidth] >> 16; |
| 656 } | 671 } |
| 657 } | 672 } |
| 658 | 673 |
| 659 static void ScaleAddCols2_16_C(int dst_width, int boxheight, int x, int dx, | 674 static void ScaleAddCols2_16_C(int dst_width, int boxheight, int x, int dx, |
| 660 const uint32* src_ptr, uint16* dst_ptr) { | 675 const uint32* src_ptr, uint16* dst_ptr) { |
| 661 int i; | 676 int i; |
| 662 int scaletbl[2]; | 677 int scaletbl[2]; |
| 663 int minboxwidth = (dx >> 16); | 678 int minboxwidth = dx >> 16; |
| 664 int* scaleptr = scaletbl - minboxwidth; | 679 int* scaleptr = scaletbl - minboxwidth; |
| 665 int boxwidth; | 680 int boxwidth; |
| 666 scaletbl[0] = 65536 / (minboxwidth * boxheight); | 681 scaletbl[0] = 65536 / (MIN1(minboxwidth) * boxheight); |
| 667 scaletbl[1] = 65536 / ((minboxwidth + 1) * boxheight); | 682 scaletbl[1] = 65536 / (MIN1(minboxwidth + 1) * boxheight); |
| 668 for (i = 0; i < dst_width; ++i) { | 683 for (i = 0; i < dst_width; ++i) { |
| 669 int ix = x >> 16; | 684 int ix = x >> 16; |
| 670 x += dx; | 685 x += dx; |
| 671 boxwidth = (x >> 16) - ix; | 686 boxwidth = MIN1((x >> 16) - ix); |
| 672 *dst_ptr++ = SumPixels_16(boxwidth, src_ptr + ix) * | 687 *dst_ptr++ = |
| 673 scaleptr[boxwidth] >> 16; | 688 SumPixels_16(boxwidth, src_ptr + ix) * scaleptr[boxwidth] >> 16; |
| 689 } |
| 690 } |
| 691 |
| 692 static void ScaleAddCols0_C(int dst_width, int boxheight, int x, int, |
| 693 const uint16* src_ptr, uint8* dst_ptr) { |
| 694 int scaleval = 65536 / boxheight; |
| 695 int i; |
| 696 src_ptr += (x >> 16); |
| 697 for (i = 0; i < dst_width; ++i) { |
| 698 *dst_ptr++ = src_ptr[i] * scaleval >> 16; |
| 674 } | 699 } |
| 675 } | 700 } |
| 676 | 701 |
| 677 static void ScaleAddCols1_C(int dst_width, int boxheight, int x, int dx, | 702 static void ScaleAddCols1_C(int dst_width, int boxheight, int x, int dx, |
| 678 const uint16* src_ptr, uint8* dst_ptr) { | 703 const uint16* src_ptr, uint8* dst_ptr) { |
| 679 int boxwidth = (dx >> 16); | 704 int boxwidth = MIN1(dx >> 16); |
| 680 int scaleval = 65536 / (boxwidth * boxheight); | 705 int scaleval = 65536 / (boxwidth * boxheight); |
| 681 int i; | 706 int i; |
| 707 x >>= 16; |
| 682 for (i = 0; i < dst_width; ++i) { | 708 for (i = 0; i < dst_width; ++i) { |
| 683 *dst_ptr++ = SumPixels(boxwidth, src_ptr + x) * scaleval >> 16; | 709 *dst_ptr++ = SumPixels(boxwidth, src_ptr + x) * scaleval >> 16; |
| 684 x += boxwidth; | 710 x += boxwidth; |
| 685 } | 711 } |
| 686 } | 712 } |
| 687 | 713 |
| 688 static void ScaleAddCols1_16_C(int dst_width, int boxheight, int x, int dx, | 714 static void ScaleAddCols1_16_C(int dst_width, int boxheight, int x, int dx, |
| 689 const uint32* src_ptr, uint16* dst_ptr) { | 715 const uint32* src_ptr, uint16* dst_ptr) { |
| 690 int boxwidth = (dx >> 16); | 716 int boxwidth = MIN1(dx >> 16); |
| 691 int scaleval = 65536 / (boxwidth * boxheight); | 717 int scaleval = 65536 / (boxwidth * boxheight); |
| 692 int i; | 718 int i; |
| 693 for (i = 0; i < dst_width; ++i) { | 719 for (i = 0; i < dst_width; ++i) { |
| 694 *dst_ptr++ = SumPixels_16(boxwidth, src_ptr + x) * scaleval >> 16; | 720 *dst_ptr++ = SumPixels_16(boxwidth, src_ptr + x) * scaleval >> 16; |
| 695 x += boxwidth; | 721 x += boxwidth; |
| 696 } | 722 } |
| 697 } | 723 } |
| 698 | 724 |
| 699 // Scale plane down to any dimensions, with interpolation. | 725 // Scale plane down to any dimensions, with interpolation. |
| 700 // (boxfilter). | 726 // (boxfilter). |
| 701 // | 727 // |
| 702 // Same method as SimpleScale, which is fixed point, outputting | 728 // Same method as SimpleScale, which is fixed point, outputting |
| 703 // one pixel of destination using fixed point (16.16) to step | 729 // one pixel of destination using fixed point (16.16) to step |
| 704 // through source, sampling a box of pixel with simple | 730 // through source, sampling a box of pixel with simple |
| 705 // averaging. | 731 // averaging. |
| 706 static void ScalePlaneBox(int src_width, int src_height, | 732 static void ScalePlaneBox(int src_width, int src_height, |
| 707 int dst_width, int dst_height, | 733 int dst_width, int dst_height, |
| 708 int src_stride, int dst_stride, | 734 int src_stride, int dst_stride, |
| 709 const uint8* src_ptr, uint8* dst_ptr) { | 735 const uint8* src_ptr, uint8* dst_ptr) { |
| 710 int j; | 736 int j, k; |
| 711 // Initial source x/y coordinate and step values as 16.16 fixed point. | 737 // Initial source x/y coordinate and step values as 16.16 fixed point. |
| 712 int x = 0; | 738 int x = 0; |
| 713 int y = 0; | 739 int y = 0; |
| 714 int dx = 0; | 740 int dx = 0; |
| 715 int dy = 0; | 741 int dy = 0; |
| 716 const int max_y = (src_height << 16); | 742 const int max_y = (src_height << 16); |
| 717 ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, | 743 ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, |
| 718 &x, &y, &dx, &dy); | 744 &x, &y, &dx, &dy); |
| 719 src_width = Abs(src_width); | 745 src_width = Abs(src_width); |
| 720 // TODO(fbarchard): Remove this and make AddRows handle boxheight 1. | |
| 721 if (!IS_ALIGNED(src_width, 16) || dst_height * 2 > src_height) { | |
| 722 uint8* dst = dst_ptr; | |
| 723 int j; | |
| 724 for (j = 0; j < dst_height; ++j) { | |
| 725 int boxheight; | |
| 726 int iy = y >> 16; | |
| 727 const uint8* src = src_ptr + iy * src_stride; | |
| 728 y += dy; | |
| 729 if (y > max_y) { | |
| 730 y = max_y; | |
| 731 } | |
| 732 boxheight = (y >> 16) - iy; | |
| 733 ScalePlaneBoxRow_C(dst_width, boxheight, | |
| 734 x, dx, src_stride, | |
| 735 src, dst); | |
| 736 dst += dst_stride; | |
| 737 } | |
| 738 return; | |
| 739 } | |
| 740 { | 746 { |
| 741 // Allocate a row buffer of uint16. | 747 // Allocate a row buffer of uint16. |
| 742 align_buffer_64(row16, src_width * 2); | 748 align_buffer_64(row16, src_width * 2); |
| 743 void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, | 749 void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, |
| 744 const uint16* src_ptr, uint8* dst_ptr) = | 750 const uint16* src_ptr, uint8* dst_ptr) = |
| 745 (dx & 0xffff) ? ScaleAddCols2_C: ScaleAddCols1_C; | 751 (dx & 0xffff) ? ScaleAddCols2_C: |
| 746 void (*ScaleAddRows)(const uint8* src_ptr, ptrdiff_t src_stride, | 752 ((dx != 0x10000) ? ScaleAddCols1_C : ScaleAddCols0_C); |
| 747 uint16* dst_ptr, int src_width, int src_height) = ScaleAddRows_C; | 753 void (*ScaleAddRow)(const uint8* src_ptr, uint16* dst_ptr, int src_width) = |
| 748 | 754 ScaleAddRow_C; |
| 749 #if defined(HAS_SCALEADDROWS_SSE2) | 755 #if defined(HAS_SCALEADDROW_SSE2) |
| 750 if (TestCpuFlag(kCpuHasSSE2) | 756 if (TestCpuFlag(kCpuHasSSE2)) { |
| 751 #ifdef AVOID_OVERREAD | 757 ScaleAddRow = ScaleAddRow_Any_SSE2; |
| 752 && IS_ALIGNED(src_width, 16) | 758 if (IS_ALIGNED(src_width, 16)) { |
| 759 ScaleAddRow = ScaleAddRow_SSE2; |
| 760 } |
| 761 } |
| 753 #endif | 762 #endif |
| 754 ) { | 763 #if defined(HAS_SCALEADDROW_AVX2) |
| 755 ScaleAddRows = ScaleAddRows_SSE2; | 764 if (TestCpuFlag(kCpuHasAVX2)) { |
| 765 ScaleAddRow = ScaleAddRow_Any_AVX2; |
| 766 if (IS_ALIGNED(src_width, 32)) { |
| 767 ScaleAddRow = ScaleAddRow_AVX2; |
| 768 } |
| 769 } |
| 770 #endif |
| 771 #if defined(HAS_SCALEADDROW_NEON) |
| 772 if (TestCpuFlag(kCpuHasNEON)) { |
| 773 ScaleAddRow = ScaleAddRow_Any_NEON; |
| 774 if (IS_ALIGNED(src_width, 16)) { |
| 775 ScaleAddRow = ScaleAddRow_NEON; |
| 776 } |
| 756 } | 777 } |
| 757 #endif | 778 #endif |
| 758 | 779 |
| 759 for (j = 0; j < dst_height; ++j) { | 780 for (j = 0; j < dst_height; ++j) { |
| 760 int boxheight; | 781 int boxheight; |
| 761 int iy = y >> 16; | 782 int iy = y >> 16; |
| 762 const uint8* src = src_ptr + iy * src_stride; | 783 const uint8* src = src_ptr + iy * src_stride; |
| 763 y += dy; | 784 y += dy; |
| 764 if (y > (src_height << 16)) { | 785 if (y > max_y) { |
| 765 y = (src_height << 16); | 786 y = max_y; |
| 766 } | 787 } |
| 767 boxheight = (y >> 16) - iy; | 788 boxheight = MIN1((y >> 16) - iy); |
| 768 ScaleAddRows(src, src_stride, (uint16*)(row16), | 789 memset(row16, 0, src_width * 2); |
| 769 src_width, boxheight); | 790 for (k = 0; k < boxheight; ++k) { |
| 770 ScaleAddCols(dst_width, boxheight, x, dx, (uint16*)(row16), | 791 ScaleAddRow(src, (uint16 *)(row16), src_width); |
| 771 dst_ptr); | 792 src += src_stride; |
| 793 } |
| 794 ScaleAddCols(dst_width, boxheight, x, dx, (uint16*)(row16), dst_ptr); |
| 772 dst_ptr += dst_stride; | 795 dst_ptr += dst_stride; |
| 773 } | 796 } |
| 774 free_aligned_buffer_64(row16); | 797 free_aligned_buffer_64(row16); |
| 775 } | 798 } |
| 776 } | 799 } |
| 777 | 800 |
| 778 static void ScalePlaneBox_16(int src_width, int src_height, | 801 static void ScalePlaneBox_16(int src_width, int src_height, |
| 779 int dst_width, int dst_height, | 802 int dst_width, int dst_height, |
| 780 int src_stride, int dst_stride, | 803 int src_stride, int dst_stride, |
| 781 const uint16* src_ptr, uint16* dst_ptr) { | 804 const uint16* src_ptr, uint16* dst_ptr) { |
| 782 int j; | 805 int j, k; |
| 783 // Initial source x/y coordinate and step values as 16.16 fixed point. | 806 // Initial source x/y coordinate and step values as 16.16 fixed point. |
| 784 int x = 0; | 807 int x = 0; |
| 785 int y = 0; | 808 int y = 0; |
| 786 int dx = 0; | 809 int dx = 0; |
| 787 int dy = 0; | 810 int dy = 0; |
| 788 const int max_y = (src_height << 16); | 811 const int max_y = (src_height << 16); |
| 789 ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, | 812 ScaleSlope(src_width, src_height, dst_width, dst_height, kFilterBox, |
| 790 &x, &y, &dx, &dy); | 813 &x, &y, &dx, &dy); |
| 791 src_width = Abs(src_width); | 814 src_width = Abs(src_width); |
| 792 // TODO(fbarchard): Remove this and make AddRows handle boxheight 1. | |
| 793 if (!IS_ALIGNED(src_width, 16) || dst_height * 2 > src_height) { | |
| 794 uint16* dst = dst_ptr; | |
| 795 int j; | |
| 796 for (j = 0; j < dst_height; ++j) { | |
| 797 int boxheight; | |
| 798 int iy = y >> 16; | |
| 799 const uint16* src = src_ptr + iy * src_stride; | |
| 800 y += dy; | |
| 801 if (y > max_y) { | |
| 802 y = max_y; | |
| 803 } | |
| 804 boxheight = (y >> 16) - iy; | |
| 805 ScalePlaneBoxRow_16_C(dst_width, boxheight, | |
| 806 x, dx, src_stride, | |
| 807 src, dst); | |
| 808 dst += dst_stride; | |
| 809 } | |
| 810 return; | |
| 811 } | |
| 812 { | 815 { |
| 813 // Allocate a row buffer of uint32. | 816 // Allocate a row buffer of uint32. |
| 814 align_buffer_64(row32, src_width * 4); | 817 align_buffer_64(row32, src_width * 4); |
| 815 void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, | 818 void (*ScaleAddCols)(int dst_width, int boxheight, int x, int dx, |
| 816 const uint32* src_ptr, uint16* dst_ptr) = | 819 const uint32* src_ptr, uint16* dst_ptr) = |
| 817 (dx & 0xffff) ? ScaleAddCols2_16_C: ScaleAddCols1_16_C; | 820 (dx & 0xffff) ? ScaleAddCols2_16_C: ScaleAddCols1_16_C; |
| 818 void (*ScaleAddRows)(const uint16* src_ptr, ptrdiff_t src_stride, | 821 void (*ScaleAddRow)(const uint16* src_ptr, uint32* dst_ptr, int src_width) = |
| 819 uint32* dst_ptr, int src_width, int src_height) = ScaleAddRows_16_C; | 822 ScaleAddRow_16_C; |
| 820 | 823 |
| 821 #if defined(HAS_SCALEADDROWS_16_SSE2) | 824 #if defined(HAS_SCALEADDROW_16_SSE2) |
| 822 if (TestCpuFlag(kCpuHasSSE2) | 825 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(src_width, 16)) { |
| 823 #ifdef AVOID_OVERREAD | 826 ScaleAddRow = ScaleAddRow_16_SSE2; |
| 824 && IS_ALIGNED(src_width, 16) | |
| 825 #endif | |
| 826 ) { | |
| 827 ScaleAddRows = ScaleAddRows_16_SSE2; | |
| 828 } | 827 } |
| 829 #endif | 828 #endif |
| 830 | 829 |
| 831 for (j = 0; j < dst_height; ++j) { | 830 for (j = 0; j < dst_height; ++j) { |
| 832 int boxheight; | 831 int boxheight; |
| 833 int iy = y >> 16; | 832 int iy = y >> 16; |
| 834 const uint16* src = src_ptr + iy * src_stride; | 833 const uint16* src = src_ptr + iy * src_stride; |
| 835 y += dy; | 834 y += dy; |
| 836 if (y > (src_height << 16)) { | 835 if (y > max_y) { |
| 837 y = (src_height << 16); | 836 y = max_y; |
| 838 } | 837 } |
| 839 boxheight = (y >> 16) - iy; | 838 boxheight = MIN1((y >> 16) - iy); |
| 840 ScaleAddRows(src, src_stride, (uint32*)(row32), | 839 memset(row32, 0, src_width * 4); |
| 841 src_width, boxheight); | 840 for (k = 0; k < boxheight; ++k) { |
| 842 ScaleAddCols(dst_width, boxheight, x, dx, (uint32*)(row32), | 841 ScaleAddRow(src, (uint32 *)(row32), src_width); |
| 843 dst_ptr); | 842 src += src_stride; |
| 843 } |
| 844 ScaleAddCols(dst_width, boxheight, x, dx, (uint32*)(row32), dst_ptr); |
| 844 dst_ptr += dst_stride; | 845 dst_ptr += dst_stride; |
| 845 } | 846 } |
| 846 free_aligned_buffer_64(row32); | 847 free_aligned_buffer_64(row32); |
| 847 } | 848 } |
| 848 } | 849 } |
| 849 | 850 |
| 850 // Scale plane down with bilinear interpolation. | 851 // Scale plane down with bilinear interpolation. |
| 851 void ScalePlaneBilinearDown(int src_width, int src_height, | 852 void ScalePlaneBilinearDown(int src_width, int src_height, |
| 852 int dst_width, int dst_height, | 853 int dst_width, int dst_height, |
| 853 int src_stride, int dst_stride, | 854 int src_stride, int dst_stride, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 } | 915 } |
| 915 } | 916 } |
| 916 #endif | 917 #endif |
| 917 | 918 |
| 918 | 919 |
| 919 #if defined(HAS_SCALEFILTERCOLS_SSSE3) | 920 #if defined(HAS_SCALEFILTERCOLS_SSSE3) |
| 920 if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { | 921 if (TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { |
| 921 ScaleFilterCols = ScaleFilterCols_SSSE3; | 922 ScaleFilterCols = ScaleFilterCols_SSSE3; |
| 922 } | 923 } |
| 923 #endif | 924 #endif |
| 925 #if defined(HAS_SCALEFILTERCOLS_NEON) |
| 926 if (TestCpuFlag(kCpuHasNEON) && src_width < 32768) { |
| 927 ScaleFilterCols = ScaleFilterCols_Any_NEON; |
| 928 if (IS_ALIGNED(dst_width, 8)) { |
| 929 ScaleFilterCols = ScaleFilterCols_NEON; |
| 930 } |
| 931 } |
| 932 #endif |
| 924 if (y > max_y) { | 933 if (y > max_y) { |
| 925 y = max_y; | 934 y = max_y; |
| 926 } | 935 } |
| 927 | 936 |
| 928 for (j = 0; j < dst_height; ++j) { | 937 for (j = 0; j < dst_height; ++j) { |
| 929 int yi = y >> 16; | 938 int yi = y >> 16; |
| 930 const uint8* src = src_ptr + yi * src_stride; | 939 const uint8* src = src_ptr + yi * src_stride; |
| 931 if (filtering == kFilterLinear) { | 940 if (filtering == kFilterLinear) { |
| 932 ScaleFilterCols(dst_ptr, src, dst_width, x, dx); | 941 ScaleFilterCols(dst_ptr, src, dst_width, x, dx); |
| 933 } else { | 942 } else { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 // Initial source x/y coordinate and step values as 16.16 fixed point. | 1059 // Initial source x/y coordinate and step values as 16.16 fixed point. |
| 1051 int x = 0; | 1060 int x = 0; |
| 1052 int y = 0; | 1061 int y = 0; |
| 1053 int dx = 0; | 1062 int dx = 0; |
| 1054 int dy = 0; | 1063 int dy = 0; |
| 1055 const int max_y = (src_height - 1) << 16; | 1064 const int max_y = (src_height - 1) << 16; |
| 1056 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, | 1065 void (*InterpolateRow)(uint8* dst_ptr, const uint8* src_ptr, |
| 1057 ptrdiff_t src_stride, int dst_width, int source_y_fraction) = | 1066 ptrdiff_t src_stride, int dst_width, int source_y_fraction) = |
| 1058 InterpolateRow_C; | 1067 InterpolateRow_C; |
| 1059 void (*ScaleFilterCols)(uint8* dst_ptr, const uint8* src_ptr, | 1068 void (*ScaleFilterCols)(uint8* dst_ptr, const uint8* src_ptr, |
| 1060 int dst_width, int x, int dx) = | 1069 int dst_width, int x, int dx) = |
| 1061 filtering ? ScaleFilterCols_C : ScaleCols_C; | 1070 filtering ? ScaleFilterCols_C : ScaleCols_C; |
| 1062 ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, | 1071 ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, |
| 1063 &x, &y, &dx, &dy); | 1072 &x, &y, &dx, &dy); |
| 1064 src_width = Abs(src_width); | 1073 src_width = Abs(src_width); |
| 1065 | 1074 |
| 1066 #if defined(HAS_INTERPOLATEROW_SSE2) | 1075 #if defined(HAS_INTERPOLATEROW_SSE2) |
| 1067 if (TestCpuFlag(kCpuHasSSE2)) { | 1076 if (TestCpuFlag(kCpuHasSSE2)) { |
| 1068 InterpolateRow = InterpolateRow_Any_SSE2; | 1077 InterpolateRow = InterpolateRow_Any_SSE2; |
| 1069 if (IS_ALIGNED(dst_width, 16)) { | 1078 if (IS_ALIGNED(dst_width, 16)) { |
| 1070 InterpolateRow = InterpolateRow_SSE2; | 1079 InterpolateRow = InterpolateRow_SSE2; |
| 1071 } | 1080 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 #endif | 1114 #endif |
| 1106 | 1115 |
| 1107 if (filtering && src_width >= 32768) { | 1116 if (filtering && src_width >= 32768) { |
| 1108 ScaleFilterCols = ScaleFilterCols64_C; | 1117 ScaleFilterCols = ScaleFilterCols64_C; |
| 1109 } | 1118 } |
| 1110 #if defined(HAS_SCALEFILTERCOLS_SSSE3) | 1119 #if defined(HAS_SCALEFILTERCOLS_SSSE3) |
| 1111 if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { | 1120 if (filtering && TestCpuFlag(kCpuHasSSSE3) && src_width < 32768) { |
| 1112 ScaleFilterCols = ScaleFilterCols_SSSE3; | 1121 ScaleFilterCols = ScaleFilterCols_SSSE3; |
| 1113 } | 1122 } |
| 1114 #endif | 1123 #endif |
| 1124 #if defined(HAS_SCALEFILTERCOLS_NEON) |
| 1125 if (filtering && TestCpuFlag(kCpuHasNEON) && src_width < 32768) { |
| 1126 ScaleFilterCols = ScaleFilterCols_Any_NEON; |
| 1127 if (IS_ALIGNED(dst_width, 8)) { |
| 1128 ScaleFilterCols = ScaleFilterCols_NEON; |
| 1129 } |
| 1130 } |
| 1131 #endif |
| 1115 if (!filtering && src_width * 2 == dst_width && x < 0x8000) { | 1132 if (!filtering && src_width * 2 == dst_width && x < 0x8000) { |
| 1116 ScaleFilterCols = ScaleColsUp2_C; | 1133 ScaleFilterCols = ScaleColsUp2_C; |
| 1117 #if defined(HAS_SCALECOLS_SSE2) | 1134 #if defined(HAS_SCALECOLS_SSE2) |
| 1118 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { | 1135 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { |
| 1119 ScaleFilterCols = ScaleColsUp2_SSE2; | 1136 ScaleFilterCols = ScaleColsUp2_SSE2; |
| 1120 } | 1137 } |
| 1121 #endif | 1138 #endif |
| 1122 } | 1139 } |
| 1123 | 1140 |
| 1124 if (y > max_y) { | 1141 if (y > max_y) { |
| 1125 y = max_y; | 1142 y = max_y; |
| 1126 } | 1143 } |
| 1127 { | 1144 { |
| 1128 int yi = y >> 16; | 1145 int yi = y >> 16; |
| 1129 const uint8* src = src_ptr + yi * src_stride; | 1146 const uint8* src = src_ptr + yi * src_stride; |
| 1130 | 1147 |
| 1131 // Allocate 2 row buffers. | 1148 // Allocate 2 row buffers. |
| 1132 const int kRowSize = (dst_width + 15) & ~15; | 1149 const int kRowSize = (dst_width + 31) & ~31; |
| 1133 align_buffer_64(row, kRowSize * 2); | 1150 align_buffer_64(row, kRowSize * 2); |
| 1134 | 1151 |
| 1135 uint8* rowptr = row; | 1152 uint8* rowptr = row; |
| 1136 int rowstride = kRowSize; | 1153 int rowstride = kRowSize; |
| 1137 int lasty = yi; | 1154 int lasty = yi; |
| 1138 | 1155 |
| 1139 ScaleFilterCols(rowptr, src, dst_width, x, dx); | 1156 ScaleFilterCols(rowptr, src, dst_width, x, dx); |
| 1140 if (src_height > 1) { | 1157 if (src_height > 1) { |
| 1141 src += src_stride; | 1158 src += src_stride; |
| 1142 } | 1159 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 // Initial source x/y coordinate and step values as 16.16 fixed point. | 1198 // Initial source x/y coordinate and step values as 16.16 fixed point. |
| 1182 int x = 0; | 1199 int x = 0; |
| 1183 int y = 0; | 1200 int y = 0; |
| 1184 int dx = 0; | 1201 int dx = 0; |
| 1185 int dy = 0; | 1202 int dy = 0; |
| 1186 const int max_y = (src_height - 1) << 16; | 1203 const int max_y = (src_height - 1) << 16; |
| 1187 void (*InterpolateRow)(uint16* dst_ptr, const uint16* src_ptr, | 1204 void (*InterpolateRow)(uint16* dst_ptr, const uint16* src_ptr, |
| 1188 ptrdiff_t src_stride, int dst_width, int source_y_fraction) = | 1205 ptrdiff_t src_stride, int dst_width, int source_y_fraction) = |
| 1189 InterpolateRow_16_C; | 1206 InterpolateRow_16_C; |
| 1190 void (*ScaleFilterCols)(uint16* dst_ptr, const uint16* src_ptr, | 1207 void (*ScaleFilterCols)(uint16* dst_ptr, const uint16* src_ptr, |
| 1191 int dst_width, int x, int dx) = | 1208 int dst_width, int x, int dx) = |
| 1192 filtering ? ScaleFilterCols_16_C : ScaleCols_16_C; | 1209 filtering ? ScaleFilterCols_16_C : ScaleCols_16_C; |
| 1193 ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, | 1210 ScaleSlope(src_width, src_height, dst_width, dst_height, filtering, |
| 1194 &x, &y, &dx, &dy); | 1211 &x, &y, &dx, &dy); |
| 1195 src_width = Abs(src_width); | 1212 src_width = Abs(src_width); |
| 1196 | 1213 |
| 1197 #if defined(HAS_INTERPOLATEROW_16_SSE2) | 1214 #if defined(HAS_INTERPOLATEROW_16_SSE2) |
| 1198 if (TestCpuFlag(kCpuHasSSE2)) { | 1215 if (TestCpuFlag(kCpuHasSSE2)) { |
| 1199 InterpolateRow = InterpolateRow_Any_16_SSE2; | 1216 InterpolateRow = InterpolateRow_Any_16_SSE2; |
| 1200 if (IS_ALIGNED(dst_width, 16)) { | 1217 if (IS_ALIGNED(dst_width, 16)) { |
| 1201 InterpolateRow = InterpolateRow_16_SSE2; | 1218 InterpolateRow = InterpolateRow_16_SSE2; |
| 1202 } | 1219 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 } | 1270 } |
| 1254 | 1271 |
| 1255 if (y > max_y) { | 1272 if (y > max_y) { |
| 1256 y = max_y; | 1273 y = max_y; |
| 1257 } | 1274 } |
| 1258 { | 1275 { |
| 1259 int yi = y >> 16; | 1276 int yi = y >> 16; |
| 1260 const uint16* src = src_ptr + yi * src_stride; | 1277 const uint16* src = src_ptr + yi * src_stride; |
| 1261 | 1278 |
| 1262 // Allocate 2 row buffers. | 1279 // Allocate 2 row buffers. |
| 1263 const int kRowSize = (dst_width + 15) & ~15; | 1280 const int kRowSize = (dst_width + 31) & ~31; |
| 1264 align_buffer_64(row, kRowSize * 4); | 1281 align_buffer_64(row, kRowSize * 4); |
| 1265 | 1282 |
| 1266 uint16* rowptr = (uint16*)row; | 1283 uint16* rowptr = (uint16*)row; |
| 1267 int rowstride = kRowSize; | 1284 int rowstride = kRowSize; |
| 1268 int lasty = yi; | 1285 int lasty = yi; |
| 1269 | 1286 |
| 1270 ScaleFilterCols(rowptr, src, dst_width, x, dx); | 1287 ScaleFilterCols(rowptr, src, dst_width, x, dx); |
| 1271 if (src_height > 1) { | 1288 if (src_height > 1) { |
| 1272 src += src_stride; | 1289 src += src_stride; |
| 1273 } | 1290 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 if (src_width * 2 == dst_width && x < 0x8000) { | 1344 if (src_width * 2 == dst_width && x < 0x8000) { |
| 1328 ScaleCols = ScaleColsUp2_C; | 1345 ScaleCols = ScaleColsUp2_C; |
| 1329 #if defined(HAS_SCALECOLS_SSE2) | 1346 #if defined(HAS_SCALECOLS_SSE2) |
| 1330 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { | 1347 if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(dst_width, 8)) { |
| 1331 ScaleCols = ScaleColsUp2_SSE2; | 1348 ScaleCols = ScaleColsUp2_SSE2; |
| 1332 } | 1349 } |
| 1333 #endif | 1350 #endif |
| 1334 } | 1351 } |
| 1335 | 1352 |
| 1336 for (i = 0; i < dst_height; ++i) { | 1353 for (i = 0; i < dst_height; ++i) { |
| 1337 ScaleCols(dst_ptr, src_ptr + (y >> 16) * src_stride, | 1354 ScaleCols(dst_ptr, src_ptr + (y >> 16) * src_stride, dst_width, x, dx); |
| 1338 dst_width, x, dx); | |
| 1339 dst_ptr += dst_stride; | 1355 dst_ptr += dst_stride; |
| 1340 y += dy; | 1356 y += dy; |
| 1341 } | 1357 } |
| 1342 } | 1358 } |
| 1343 | 1359 |
| 1344 static void ScalePlaneSimple_16(int src_width, int src_height, | 1360 static void ScalePlaneSimple_16(int src_width, int src_height, |
| 1345 int dst_width, int dst_height, | 1361 int dst_width, int dst_height, |
| 1346 int src_stride, int dst_stride, | 1362 int src_stride, int dst_stride, |
| 1347 const uint16* src_ptr, uint16* dst_ptr) { | 1363 const uint16* src_ptr, uint16* dst_ptr) { |
| 1348 int i; | 1364 int i; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1378 // This function dispatches to a specialized scaler based on scale factor. | 1394 // This function dispatches to a specialized scaler based on scale factor. |
| 1379 | 1395 |
| 1380 LIBYUV_API | 1396 LIBYUV_API |
| 1381 void ScalePlane(const uint8* src, int src_stride, | 1397 void ScalePlane(const uint8* src, int src_stride, |
| 1382 int src_width, int src_height, | 1398 int src_width, int src_height, |
| 1383 uint8* dst, int dst_stride, | 1399 uint8* dst, int dst_stride, |
| 1384 int dst_width, int dst_height, | 1400 int dst_width, int dst_height, |
| 1385 enum FilterMode filtering) { | 1401 enum FilterMode filtering) { |
| 1386 // Simplify filtering when possible. | 1402 // Simplify filtering when possible. |
| 1387 filtering = ScaleFilterReduce(src_width, src_height, | 1403 filtering = ScaleFilterReduce(src_width, src_height, |
| 1388 dst_width, dst_height, | 1404 dst_width, dst_height, filtering); |
| 1389 filtering); | |
| 1390 | 1405 |
| 1391 // Negative height means invert the image. | 1406 // Negative height means invert the image. |
| 1392 if (src_height < 0) { | 1407 if (src_height < 0) { |
| 1393 src_height = -src_height; | 1408 src_height = -src_height; |
| 1394 src = src + (src_height - 1) * src_stride; | 1409 src = src + (src_height - 1) * src_stride; |
| 1395 src_stride = -src_stride; | 1410 src_stride = -src_stride; |
| 1396 } | 1411 } |
| 1397 | 1412 |
| 1398 // Use specialized scales to improve performance for common resolutions. | 1413 // Use specialized scales to improve performance for common resolutions. |
| 1399 // For example, all the 1/2 scalings will use ScalePlaneDown2() | 1414 // For example, all the 1/2 scalings will use ScalePlaneDown2() |
| 1400 if (dst_width == src_width && dst_height == src_height) { | 1415 if (dst_width == src_width && dst_height == src_height) { |
| 1401 // Straight copy. | 1416 // Straight copy. |
| 1402 CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height); | 1417 CopyPlane(src, src_stride, dst, dst_stride, dst_width, dst_height); |
| 1403 return; | 1418 return; |
| 1404 } | 1419 } |
| 1405 if (dst_width == src_width) { | 1420 if (dst_width == src_width && filtering != kFilterBox) { |
| 1406 int dy = FixedDiv(src_height, dst_height); | 1421 int dy = FixedDiv(src_height, dst_height); |
| 1407 // Arbitrary scale vertically, but unscaled vertically. | 1422 // Arbitrary scale vertically, but unscaled horizontally. |
| 1408 ScalePlaneVertical(src_height, | 1423 ScalePlaneVertical(src_height, |
| 1409 dst_width, dst_height, | 1424 dst_width, dst_height, |
| 1410 src_stride, dst_stride, src, dst, | 1425 src_stride, dst_stride, src, dst, |
| 1411 0, 0, dy, 1, filtering); | 1426 0, 0, dy, 1, filtering); |
| 1412 return; | 1427 return; |
| 1413 } | 1428 } |
| 1414 if (dst_width <= Abs(src_width) && dst_height <= src_height) { | 1429 if (dst_width <= Abs(src_width) && dst_height <= src_height) { |
| 1415 // Scale down. | 1430 // Scale down. |
| 1416 if (4 * dst_width == 3 * src_width && | 1431 if (4 * dst_width == 3 * src_width && |
| 1417 4 * dst_height == 3 * src_height) { | 1432 4 * dst_height == 3 * src_height) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1428 } | 1443 } |
| 1429 // 3/8 rounded up for odd sized chroma height. | 1444 // 3/8 rounded up for odd sized chroma height. |
| 1430 if (8 * dst_width == 3 * src_width && | 1445 if (8 * dst_width == 3 * src_width && |
| 1431 dst_height == ((src_height * 3 + 7) / 8)) { | 1446 dst_height == ((src_height * 3 + 7) / 8)) { |
| 1432 // optimized, 3/8 | 1447 // optimized, 3/8 |
| 1433 ScalePlaneDown38(src_width, src_height, dst_width, dst_height, | 1448 ScalePlaneDown38(src_width, src_height, dst_width, dst_height, |
| 1434 src_stride, dst_stride, src, dst, filtering); | 1449 src_stride, dst_stride, src, dst, filtering); |
| 1435 return; | 1450 return; |
| 1436 } | 1451 } |
| 1437 if (4 * dst_width == src_width && 4 * dst_height == src_height && | 1452 if (4 * dst_width == src_width && 4 * dst_height == src_height && |
| 1438 filtering != kFilterBilinear) { | 1453 (filtering == kFilterBox || filtering == kFilterNone)) { |
| 1439 // optimized, 1/4 | 1454 // optimized, 1/4 |
| 1440 ScalePlaneDown4(src_width, src_height, dst_width, dst_height, | 1455 ScalePlaneDown4(src_width, src_height, dst_width, dst_height, |
| 1441 src_stride, dst_stride, src, dst, filtering); | 1456 src_stride, dst_stride, src, dst, filtering); |
| 1442 return; | 1457 return; |
| 1443 } | 1458 } |
| 1444 } | 1459 } |
| 1445 if (filtering == kFilterBox && dst_height * 2 < src_height) { | 1460 if (filtering == kFilterBox && dst_height * 2 < src_height) { |
| 1446 ScalePlaneBox(src_width, src_height, dst_width, dst_height, | 1461 ScalePlaneBox(src_width, src_height, dst_width, dst_height, |
| 1447 src_stride, dst_stride, src, dst); | 1462 src_stride, dst_stride, src, dst); |
| 1448 return; | 1463 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1462 } | 1477 } |
| 1463 | 1478 |
| 1464 LIBYUV_API | 1479 LIBYUV_API |
| 1465 void ScalePlane_16(const uint16* src, int src_stride, | 1480 void ScalePlane_16(const uint16* src, int src_stride, |
| 1466 int src_width, int src_height, | 1481 int src_width, int src_height, |
| 1467 uint16* dst, int dst_stride, | 1482 uint16* dst, int dst_stride, |
| 1468 int dst_width, int dst_height, | 1483 int dst_width, int dst_height, |
| 1469 enum FilterMode filtering) { | 1484 enum FilterMode filtering) { |
| 1470 // Simplify filtering when possible. | 1485 // Simplify filtering when possible. |
| 1471 filtering = ScaleFilterReduce(src_width, src_height, | 1486 filtering = ScaleFilterReduce(src_width, src_height, |
| 1472 dst_width, dst_height, | 1487 dst_width, dst_height, filtering); |
| 1473 filtering); | |
| 1474 | 1488 |
| 1475 // Negative height means invert the image. | 1489 // Negative height means invert the image. |
| 1476 if (src_height < 0) { | 1490 if (src_height < 0) { |
| 1477 src_height = -src_height; | 1491 src_height = -src_height; |
| 1478 src = src + (src_height - 1) * src_stride; | 1492 src = src + (src_height - 1) * src_stride; |
| 1479 src_stride = -src_stride; | 1493 src_stride = -src_stride; |
| 1480 } | 1494 } |
| 1481 | 1495 |
| 1482 // Use specialized scales to improve performance for common resolutions. | 1496 // Use specialized scales to improve performance for common resolutions. |
| 1483 // For example, all the 1/2 scalings will use ScalePlaneDown2() | 1497 // For example, all the 1/2 scalings will use ScalePlaneDown2() |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 uint8* dst_y, int dst_stride_y, | 1570 uint8* dst_y, int dst_stride_y, |
| 1557 uint8* dst_u, int dst_stride_u, | 1571 uint8* dst_u, int dst_stride_u, |
| 1558 uint8* dst_v, int dst_stride_v, | 1572 uint8* dst_v, int dst_stride_v, |
| 1559 int dst_width, int dst_height, | 1573 int dst_width, int dst_height, |
| 1560 enum FilterMode filtering) { | 1574 enum FilterMode filtering) { |
| 1561 int src_halfwidth = SUBSAMPLE(src_width, 1, 1); | 1575 int src_halfwidth = SUBSAMPLE(src_width, 1, 1); |
| 1562 int src_halfheight = SUBSAMPLE(src_height, 1, 1); | 1576 int src_halfheight = SUBSAMPLE(src_height, 1, 1); |
| 1563 int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); | 1577 int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); |
| 1564 int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); | 1578 int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); |
| 1565 if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || | 1579 if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || |
| 1580 src_width > 32768 || src_height > 32768 || |
| 1566 !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { | 1581 !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { |
| 1567 return -1; | 1582 return -1; |
| 1568 } | 1583 } |
| 1569 | 1584 |
| 1570 ScalePlane(src_y, src_stride_y, src_width, src_height, | 1585 ScalePlane(src_y, src_stride_y, src_width, src_height, |
| 1571 dst_y, dst_stride_y, dst_width, dst_height, | 1586 dst_y, dst_stride_y, dst_width, dst_height, |
| 1572 filtering); | 1587 filtering); |
| 1573 ScalePlane(src_u, src_stride_u, src_halfwidth, src_halfheight, | 1588 ScalePlane(src_u, src_stride_u, src_halfwidth, src_halfheight, |
| 1574 dst_u, dst_stride_u, dst_halfwidth, dst_halfheight, | 1589 dst_u, dst_stride_u, dst_halfwidth, dst_halfheight, |
| 1575 filtering); | 1590 filtering); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1587 uint16* dst_y, int dst_stride_y, | 1602 uint16* dst_y, int dst_stride_y, |
| 1588 uint16* dst_u, int dst_stride_u, | 1603 uint16* dst_u, int dst_stride_u, |
| 1589 uint16* dst_v, int dst_stride_v, | 1604 uint16* dst_v, int dst_stride_v, |
| 1590 int dst_width, int dst_height, | 1605 int dst_width, int dst_height, |
| 1591 enum FilterMode filtering) { | 1606 enum FilterMode filtering) { |
| 1592 int src_halfwidth = SUBSAMPLE(src_width, 1, 1); | 1607 int src_halfwidth = SUBSAMPLE(src_width, 1, 1); |
| 1593 int src_halfheight = SUBSAMPLE(src_height, 1, 1); | 1608 int src_halfheight = SUBSAMPLE(src_height, 1, 1); |
| 1594 int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); | 1609 int dst_halfwidth = SUBSAMPLE(dst_width, 1, 1); |
| 1595 int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); | 1610 int dst_halfheight = SUBSAMPLE(dst_height, 1, 1); |
| 1596 if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || | 1611 if (!src_y || !src_u || !src_v || src_width == 0 || src_height == 0 || |
| 1612 src_width > 32768 || src_height > 32768 || |
| 1597 !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { | 1613 !dst_y || !dst_u || !dst_v || dst_width <= 0 || dst_height <= 0) { |
| 1598 return -1; | 1614 return -1; |
| 1599 } | 1615 } |
| 1600 | 1616 |
| 1601 ScalePlane_16(src_y, src_stride_y, src_width, src_height, | 1617 ScalePlane_16(src_y, src_stride_y, src_width, src_height, |
| 1602 dst_y, dst_stride_y, dst_width, dst_height, | 1618 dst_y, dst_stride_y, dst_width, dst_height, |
| 1603 filtering); | 1619 filtering); |
| 1604 ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_halfheight, | 1620 ScalePlane_16(src_u, src_stride_u, src_halfwidth, src_halfheight, |
| 1605 dst_u, dst_stride_u, dst_halfwidth, dst_halfheight, | 1621 dst_u, dst_stride_u, dst_halfwidth, dst_halfheight, |
| 1606 filtering); | 1622 filtering); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 dst_u, dst_halfwidth, | 1680 dst_u, dst_halfwidth, |
| 1665 dst_v, dst_halfwidth, | 1681 dst_v, dst_halfwidth, |
| 1666 dst_width, aheight, | 1682 dst_width, aheight, |
| 1667 interpolate ? kFilterBox : kFilterNone); | 1683 interpolate ? kFilterBox : kFilterNone); |
| 1668 } | 1684 } |
| 1669 | 1685 |
| 1670 #ifdef __cplusplus | 1686 #ifdef __cplusplus |
| 1671 } // extern "C" | 1687 } // extern "C" |
| 1672 } // namespace libyuv | 1688 } // namespace libyuv |
| 1673 #endif | 1689 #endif |
| OLD | NEW |