The tail LD2B predicate previously used the raw remaining width, however
for odd widths this is incorrect. We already calculate the correct
halved predicate for the UV store part so just compute the load
predicate from that directly.
Bug: 546962730
Change-Id: I59654208ea48eb5bcc6261a63cb90abae58c1668
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252280
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
This reverts commit 87c797b3c29cc6fb233fc329a93aace2942ba2d9.
Reason for revert: Only commit 8aeb3a9 needs the workaround
Original change's description:
> Add the ARGBToRGB565Row_SSE2() function back
>
> Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
> back because they hide the unaligned access in ARGBToRGB565Row_C().
>
> To reproduce the unalgined access error, run the following command in
> Google's internal repository:
> blaze test --config=asan third_party/libyuv:libyuv_test \
> --test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned
>
> Bug: b:547803993
> Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
> Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
> Commit-Queue: Wan-Teh Chang <wtc@google.com>
> Reviewed-by: Frank Barchard <fbarchard@google.com>
Bug: b:547803993
Change-Id: I904126f032f4ed37c470d8972152a137ca315168
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8258919
Reviewed-by: Frank Barchard <fbarchard@google.com>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Add the ARGBToRGB565Row_SSE2() and ARGBToRGB565Row_Any_SSE2() functions
back because they hide the unaligned access in ARGBToRGB565Row_C().
To reproduce the unalgined access error, run the following command in
Google's internal repository:
blaze test --config=asan third_party/libyuv:libyuv_test \
--test_filter=LibYUVConvertTest.I420ToARGBToRGB565_Unaligned
Bug: b:547803993
Change-Id: I9cc6b643bc007c100dfc092ef3ec814428789219
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8265046
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
It is the temporary input buffer, not the temporary output buffer, that
needs to be zero-initialized for msan.
This mistake may have been introduced because dst_temp was declared
before src_temp. So swap their declarations.
Change-Id: I74691afe51a7d84187fc0decbc83f2c970cf52b7
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8261587
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Copy dither4x4 (16 bytes) into an aligned local uint32_t dither4[4] array
using memcpy and index using dither4[y & 3] to avoid unaligned 32-bit
pointer dereference traps in fastbuild / UB sanitizers.
Bug: None
Test: LibYUVConvertTest.TestNoDither, LibYUVConvertTest.TestDither
Change-Id: I4447cd2924b16739a9bce2792d57a550dedeb345
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8262354
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
- Add register z2 to the inline assembly clobber list in ARGBToRGB565DitherRow_SVE2.
- Fix operand constraints and register indexes for src_argb, dst_rgb, and width in ARGBToRGB565DitherRow_NEON to properly use '+r' for modified
operands.
Bug: None
Change-Id: I521c5b37dc37e2bcbe910f72c389144b1491e9dc
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8261579
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
In ScaleARGBBilinearUp, ScalePlaneBilinearUp, ScalePlaneBilinearUp_16,
and ScaleUVBilinearUp, dy is strictly < 65536 (dy < 1.0 in 16.16 fixed
point), so yi (y >> 16) advances strictly in unit increments (0 -> 1 ->
2 -> ... -> H - 1).
Because yi transitions across each integer row in sequence:
- src is primed at row 2 and incrementally advanced by 1 row on each
integer transition while (y + 65536) < max_y.
- When y >= max_y - 65536, src increments stop, leaving src pointing to
the final row (H - 1).
- Therefore, src is always pointing to row yi + 1 before each buffer
swap, making the inner 'src = src_ptr + yi * src_stride' recomputation
and nested 'if (yi != lasty)' checks redundant.
Bug: 540206290, 539110937
Test: LibYUVScaleTest.*
Change-Id: Ic5cc5c601d4771e9df8b9a882df2f7f3e6777b23
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8252878
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
In ScaleARGBBilinearDown and ScaleARGBBilinearUp, adding dy to y can
overflow signed 32-bit int when scaling down large height images (e.g.,
src_height = 32768 down to 2). Check if max_y - dy < y before adding dy
to y to prevent signed integer overflow.
R=wtc
Fixed: 540206290, 539110937
Test: LibYUVScaleTest.ARGBScale_LargeHeightOverflow
Change-Id: If353d002714481ce0018653798047066663f1fb9
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8175358
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Replace rshrn2 with 2 8 byte registers and stp
All benchmarks run at 1280×720, 1000 iterations (taskset c0):
Function (1280x720 1000x) | OldNEON | NewNEON | OldSVE2 | NewSVE2
-------------------------------+---------+---------+---------+--------
TestInterpolatePlane (8-bit) | 76 ms | 66 ms | 125 ms | 34 ms
TestInterpolatePlane_16 | 195 ms | 66 ms | 195 ms | 64 ms
TestARGBInterpolate (50/50) | 104 ms | 104 ms | 128 ms | 89 ms
ARGBInterpolate0_Opt (0%) | 133 ms | 128 ms | 148 ms | 145 ms
ARGBInterpolate64_Opt (25%) | 211 ms | 181 ms | 244 ms | 222 ms
ARGBInterpolate128_Opt (50%) | 182 ms | 178 ms | 278 ms | 176 ms
ARGBInterpolate192_Opt (75%) | 211 ms | 173 ms | 223 ms | 209 ms
ARGBInterpolate255_Opt (99%) | 211 ms | 183 ms | 315 ms | 221 ms
──────
Function (1280x720 1000x) | OldNEON | NewNEON | OldSVE2 | NewSVE2
-------------------------------+---------+---------+---------+--------
TestInterpolatePlane (8-bit) | 164 ms | 124 ms | 119 ms | 50 ms
TestInterpolatePlane_16 | 211 ms | 129 ms | 138 ms | 75 ms
TestARGBInterpolate (50/50) | 159 ms | 159 ms | 210 ms | 166 ms
ARGBInterpolate0_Opt (0%) | 92 ms | 92 ms | 148 ms | 138 ms
ARGBInterpolate64_Opt (25%) | 223 ms | 223 ms | 232 ms | 232 ms
ARGBInterpolate128_Opt (50%) | 130 ms | 130 ms | 232 ms | 195 ms
ARGBInterpolate192_Opt (75%) | 223 ms | 223 ms | 232 ms | 232 ms
ARGBInterpolate255_Opt (99%) | 223 ms | 223 ms | 232 ms | 232 ms
Platform | NEON | SVE2 | Result
--------------------+--------+--------+---------------
MediaTek Cortex-C1 | 47 ms | 34 ms | SVE2 1.38x win
Qualcomm Oryon v3 | 87 ms | 73 ms | SVE2 1.19x win
Testing:
blaze test --config=android_arm64 //third_party/libyuv:libyuv_test --test_filter="*TestInterpolatePlane*"
Bug: None
Change-Id: I503ce5a1269da5e1c5950c6a2c5ce81ddf4aaca5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8216829
Commit-Queue: Frank Barchard <fbarchard@google.com>
Reviewed-by: George Steed <george.steed@arm.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
- MergeUVRow_SVE2: Interleaves U and V
- SplitUVRow_SVE2: De-interleaves UV
- InterpolateRow_SVE2: Bilinear row interpolation
- YUY2ToYRow_SVE2, YUY2ToUVRow_SVE2, UYVYToYRow_SVE2, UYVYToUVRow_SVE2
- HalfMergeUVRow_SVE2: 2:1 vertical averaging of U and V
OnePlus 15 with Qualcomm Snapdragon 8 Elite Gen 5 Oryon V3
Benchmark (1280x720 1000x) | SVE2 | NEON | Result
-------------------------------+--------+--------+------------------
TestInterpolatePlane | 119 ms | 164 ms | SVE2 is 1.38x win
TestInterpolatePlane_16 | 138 ms | 172 ms | SVE2 is 1.25x win
SplitUVPlane_Opt | 68 ms | 69 ms | SVE2 is 1.01x win
MergeUVPlane_Opt | 40 ms | 40 ms | Tied
SwapUVPlane_Opt | 72 ms | 72 ms | Tied
HalfMergeUVPlane_Opt | 50 ms | 50 ms | Tied
I420ToNV12_Opt | 25 ms | 26 ms | SVE2 is faster
I420ToNV21_Opt | 26 ms | 26 ms | Tied
YUY2ToNV12_Opt | 79 ms | 81 ms | SVE2 is faster
NV21ToNV12_Opt | 36 ms | 35 ms | Tied
Android420ToI420ToNV12_Opt | 53 ms | 53 ms | Tied
Android420ToI420ToNV21_Opt | 35 ms | 33 ms | NEON is faster
YUY2ToI420_Opt | 87 ms | 84 ms | NEON is faster
UYVYToI420_Opt | 87 ms | 83 ms | NEON is faster
YUY2ToI422_Opt | 101 ms | 97 ms | NEON is faster
UYVYToI422_Opt | 101 ms | 97 ms | NEON is faster
UYVYToNV12_Opt | 111 ms | 108 ms | NEON is faster
ARGBToNV21_Opt | 279 ms | 279 ms | Tied
ABGRToNV21_Opt | 279 ms | 280 ms | SVE2 is faster
ARGBToNV12_Opt | 285 ms | 280 ms | NEON is faster
ABGRToNV12_Opt | 284 ms | 281 ms | NEON is faster
Bug: 42280902
Change-Id: I53f633fe453f2853f7bc9fe17280e938912c4e8f
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8196068
Reviewed-by: Justin Green <greenjustin@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
It should be named dst_stride_vu to match the dst_vu parameter.
Change-Id: I3a4835eafa358787a858b896060e6c715813bbec
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8135083
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Fix the chroma plane order passed to MergeUVRow in ARGBToNV21Matrix.
MergeUVRow(a, b, dst, ...) writes a into byte 0 and b into byte 1.
Passing (row_u, row_v) produced NV12 format (UV interleaved) instead
of NV21 format (VU interleaved). Swapping to (row_v, row_u) ensures
the chroma channels are correctly ordered for NV21 output.
Test: libyuv_unittest --gtest_filter=*NV21*
Bug: None
Change-Id: I3b78246c635ce515923739298013a61203cabb72
TAG=agy
CONV=5daf08a8-11bd-4d47-8c71-c5b7a882a788
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8133203
Reviewed-by: richard winterton <rrwinterton@gmail.com>
RAW format in libyuv is Red-first ([R, G, B] in memory), whereas RGB24
is Blue-first ([B, G, R] in memory).
RGBToYMatrixRow and RGBToUVMatrixRow internally expand 3-byte input
into 4-byte [byte0, byte1, byte2, 255]. For RAW, this buffer becomes
[R, G, B, 255] (matching ABGR byte order). RAWToI420 previously passed
&kArgbI601Constants (which expects [B, G, R, 255]) instead of
&kAbgrI601Constants, causing Red and Blue channels to be swapped.
Pass &kAbgrI601Constants in RAWToI420, fix parameter names in
source/convert.cc, and add a unit test.
Test: libyuv_unittest --gtest_filter=*RAWToI420*
Bug: libyuv:537503370
TAG=agy
CONV=2c54c4b5-f515-421b-80b3-079caa9f948b
Change-Id: Ic72470813eaf15e80046c2c01cf804cb827039ab
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8133048
Reviewed-by: richard winterton <rrwinterton@gmail.com>
android_x86 was running out registers
Using "+m" for width on __i386__ (matching the convention in
SSSE3 row functions) makes width a stack variable instead
Was
3800 | "vbroadcasti128 16+%[kShuffleMaskARGBToRGB24],%%ymm5 \n"
| ^
1 error generated.
Test: libyuv_unittest --gunit_filter=*I422ToRGB24*
Bug: 42280902
Change-Id: I7e5e22e9e15b68be942c85dd3b7e233e9f4f1351
TAG=agy
CONV=5c8b22e3-9f50-4ace-b1d5-007ddf688477
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8127620
Reviewed-by: James Zern <jzern@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
- Implemented `I422ToRGB24Row_AVX2` and `I422ToRGB24Row_AVX512VBMI` in:
- `row_gcc.cc`: Inline assembly for GCC/Clang.
- `row_win.cc`: C++ intrinsics for MSVC (also verified with Clang).
Reduced width alignment requirement: changed from 32-pixel to 16-pixel
alignment in `convert_argb.cc` and `row_any.cc`. This allows the AVX2
path to be used for more common video resolutions.
```
I420ToRAW vs Rust on Icelake Xeon
Size I420ToRAW yuv420_to_rgb iterations
------- --------- --------------- ----------
640x480 57 us 77.377 µs/iter 3000
1280x720 170 us 221.671 µs/iter 1000
1920x1080 396 us 494.324 µs/iter 500
3840x2160 2040 us 2357 µs/iter 200
```
Bug: 42280902
Change-Id: I07c0505c95410ea16a6218c858844791a11ef073
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7908323
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Reviewed-by: richard winterton <rrwinterton@gmail.com>
Commit-Queue: Frank Barchard <fbarchard@google.com>
ARGBRotate90, ARGBRotate180 and ARGBRotate270 adjusted the source and
destination base pointers with expressions like src_stride_argb *
(height - 1) and dst_stride_argb * (width - 1) using 32-bit int
multiplication. For large frames this product overflows int before it
is applied as a pointer offset, yielding an out-of-bounds pointer even
on 64-bit targets (in the 90/270 cases the bad base pointer is then
passed to ARGBTranspose).
Cast the stride to ptrdiff_t before multiplying so the arithmetic is
performed in pointer width, matching the existing correct pattern at
rotate.cc:164 and rotate_argb.cc:235.
R=fbarchard@google.com
Change-Id: Ia4fd5d813de4fb7fa72c46aee723eca65980bccc
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8070980
Reviewed-by: Frank Barchard <fbarchard@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>
Commit-Queue: Max Hils <mhils@google.com>
The Convert16To8Row function pointer in I010ToNV12 is only ever called
with halfwidth for the chroma planes (the Y plane goes through
Convert16To8Plane which has its own dispatch), but its SIMD variants
were selected based on the alignment of the full luma width. When width
is a multiple of 32 but halfwidth is not, the bare AVX2 kernel was
selected and over-read the chroma sources and over-wrote the temporary
row buffer. Match the MergeUVRow dispatch in the same function and key
on halfwidth.
Bug: chromium:514748734
Change-Id: I4c2a42857828cdcc6505ebaa65d5b6a95b0f7e55
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8031724
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Suppose the variable `size` is of the uint64_t type. The condition
size > SIZE_MAX is always false if size_t is 64 bits, so the code inside
the body of `if (size > SIZE_MAX)` is dead code.
Fix Coverity defects CID 561616, CID 561617, CID 561618.
Change-Id: I91172896711943bdcec017edce3a9d1e389d9f88
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8020303
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Also validate crop_x, crop_y, crop_width, crop_height and make sure the
crop region stays inside the source rectangle.
Change-Id: I68748e14b21307b262d8b283147bce5ace8108d2
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7904591
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Fix int negation overflow in ConvertToARGB() and ConvertToI420().
Change-Id: Ia8e1f1a2994962a0372f4c31f6cc9c8972d8a954
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7904588
Reviewed-by: James Zern <jzern@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Validate that an int parameter is not equal to INT_MIN before negating
it.
Remove redundant src_width > 32768 || src_height > 32768 checks in
callers of ScalePlane(), ScalePlane_16(), ScalePlane_12(), and
UVScale().
Change UVScale() to validate its parameters in the same way as
ScalePlane(), ScalePlane_16(), and ScalePlane_12().
Change-Id: I64e03257cf090760030c966b49c4d23e4cec25e5
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7902889
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Remove __attribute__((no_sanitize("cfi-icall"))) from
ARGBToUVMatrixRow_AVX2(). This breaks MSVC compilation, and no other
libyuv function is marked with this attribute.
Change-Id: I2bb6a688e296dd4acff325c5bd750573a577f246
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7904777
Reviewed-by: Frank Barchard <fbarchard@google.com>
Treat height == INT_MIN as invalid. Omit explicit height == INT_MIN
check if we disallow height < 32768.
Perform multiplications of stride in the ptrdiff_t type.
Add checks for invalid width and height to some functions.
Bug: 518806561
Change-Id: I5e39fffed7f806852a8758d4b59df919839c0a3b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7891415
Reviewed-by: Frank Barchard <fbarchard@google.com>
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Adds a safety check to prevent signed integer overflow in the UV
plane coalescing logic within NV12ToI420. This ensures that
halfwidth * halfheight does not overflow INT_MAX, matching the Y
plane coalescing check and preventing potential undefined behavior
(signed integer overflow) which could lead to negative widths being
passed to SIMD functions.
Test: libyuv_unittest --gtest_filter=*NV12Crop*
Bug: None
CONV=6401df25-4d5d-4595-a231-f72c2c8e78df
TAG=agy
R=wtc@google.com
Change-Id: I15a51609a1e000a82f4b6958b4ada444efb1f2f4
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7886824
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Wan-Teh Chang <wtc@google.com>