diff options
author | Werner Lemberg <wl@gnu.org> | 2021-08-06 08:31:22 +0200 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2021-08-06 08:31:22 +0200 |
commit | 6be8bfe499fcb4f8de989d5d977b0433877b7271 (patch) | |
tree | 8125fa5c2e54467f99440d60a191ccc2bfd86b84 | |
parent | 09195a82a4a39afb0f8281563f48ce4493455b4e (diff) | |
download | freetype2-6be8bfe499fcb4f8de989d5d977b0433877b7271.tar.gz |
[smooth] Fix left shifts of negative numbers.
Reported as
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36241
* src/smooth/ftgrays.c (LEFT_SHIFT): New macro.
(gray_render_conic) [BEZIER_USE_DDA]: Use it.
-rw-r--r-- | src/smooth/ftgrays.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index 131b86c3e..322bf6c53 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -1035,6 +1035,9 @@ typedef ptrdiff_t FT_PtrDist; # include <emmintrin.h> #endif +#define LEFT_SHIFT( a, b ) (FT_Int64)( (FT_UInt64)(a) << (b) ) + + static void gray_render_conic( RAS_ARG_ const FT_Vector* control, const FT_Vector* to ) @@ -1126,13 +1129,15 @@ typedef ptrdiff_t FT_PtrDist; * EMIT(P) * * To ensure accurate results, perform computations on 64-bit - * values, after scaling them by 2^32: + * values, after scaling them by 2^32. + * + * h = 1 / 2^N * - * R << 32 = 2 * A << (32 - N - N) - * = A << (33 - 2 *N) + * R << 32 = 2 * A << (32 - N - N) + * = A << (33 - 2*N) * - * Q << 32 = (2 * B << (32 - N)) + (A << (32 - N - N)) - * = (B << (33 - N)) + (A << (32 - N - N)) + * Q << 32 = (2 * B << (32 - N)) + (A << (32 - N - N)) + * = (B << (33 - N)) + (A << (32 - 2*N)) */ #ifdef __SSE2__ @@ -1199,14 +1204,14 @@ typedef ptrdiff_t FT_PtrDist; bx = p1.x - p0.x; by = p1.y - p0.y; - rx = ax << ( 33 - 2 * shift ); - ry = ay << ( 33 - 2 * shift ); + rx = LEFT_SHIFT( ax, 33 - 2 * shift ); + ry = LEFT_SHIFT( ay, 33 - 2 * shift ); - qx = ( bx << ( 33 - shift ) ) + ( ax << ( 32 - 2 * shift ) ); - qy = ( by << ( 33 - shift ) ) + ( ay << ( 32 - 2 * shift ) ); + qx = LEFT_SHIFT( bx, 33 - shift ) + LEFT_SHIFT( ax, 32 - 2 * shift ); + qy = LEFT_SHIFT( by, 33 - shift ) + LEFT_SHIFT( ay, 32 - 2 * shift ); - px = (FT_Int64)p0.x << 32; - py = (FT_Int64)p0.y << 32; + px = LEFT_SHIFT( p0.x, 32 ); + py = LEFT_SHIFT( p0.y, 32 ); for ( count = 1U << shift; count > 0; count-- ) { |