diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs
index df7686c31..0ce6e3c9f 100644
--- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs
+++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors.
+// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Runtime.CompilerServices;
@@ -42,9 +42,11 @@ internal sealed class CieXyzToCieLabConverter
float xr = input.X / wx, yr = input.Y / wy, zr = input.Z / wz;
- float fx = xr > CieConstants.Epsilon ? MathF.Pow(xr, 0.3333333F) : ((CieConstants.Kappa * xr) + 16F) / 116F;
- float fy = yr > CieConstants.Epsilon ? MathF.Pow(yr, 0.3333333F) : ((CieConstants.Kappa * yr) + 16F) / 116F;
- float fz = zr > CieConstants.Epsilon ? MathF.Pow(zr, 0.3333333F) : ((CieConstants.Kappa * zr) + 16F) / 116F;
+ const float inv116 = 1 / 116F;
+
+ float fx = xr > CieConstants.Epsilon ? MathF.Pow(xr, 0.3333333F) : ((CieConstants.Kappa * xr) + 16F) * inv116;
+ float fy = yr > CieConstants.Epsilon ? MathF.Pow(yr, 0.3333333F) : ((CieConstants.Kappa * yr) + 16F) * inv116;
+ float fz = zr > CieConstants.Epsilon ? MathF.Pow(zr, 0.3333333F) : ((CieConstants.Kappa * zr) + 16F) * inv116;
float l = (116F * fy) - 16F;
float a = 500F * (fx - fy);
diff --git a/src/ImageSharp/Common/Helpers/HexConverter.cs b/src/ImageSharp/Common/Helpers/HexConverter.cs
index 7ec0ca625..3c863cc37 100644
--- a/src/ImageSharp/Common/Helpers/HexConverter.cs
+++ b/src/ImageSharp/Common/Helpers/HexConverter.cs
@@ -16,21 +16,19 @@ internal static class HexConverter
/// The number of bytes written to .
public static int HexStringToBytes(ReadOnlySpan chars, Span bytes)
{
- if ((chars.Length % 2) != 0)
+ if ((chars.Length & 1) != 0) // bit-hack for % 2
{
throw new ArgumentException("Input string length must be a multiple of 2", nameof(chars));
}
- if ((bytes.Length * 2) < chars.Length)
+ if ((bytes.Length << 1) < chars.Length) // bit-hack for * 2
{
throw new ArgumentException("Output span must be at least half the length of the input string");
}
- else
- {
- // Slightly better performance in the loop below, allows us to skip a bounds check
- // while still supporting output buffers that are larger than necessary
- bytes = bytes[..(chars.Length / 2)];
- }
+
+ // Slightly better performance in the loop below, allows us to skip a bounds check
+ // while still supporting output buffers that are larger than necessary
+ bytes = bytes[..(chars.Length >> 1)]; // bit-hack for / 2
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static int FromChar(int c)
diff --git a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs
index 18daaed48..f2135b764 100644
--- a/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs
+++ b/src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs
@@ -84,7 +84,7 @@ internal readonly struct WXYZShuffle4 : IShuffle4
{
ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source));
ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
- int n = source.Length / 4;
+ int n = (int)((uint)source.Length / 4);
for (nint i = 0; i < (uint)n; i++)
{
@@ -108,7 +108,7 @@ internal readonly struct WZYXShuffle4 : IShuffle4
{
ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source));
ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
- int n = source.Length / 4;
+ int n = (int)((uint)source.Length / 4);
for (nint i = 0; i < (uint)n; i++)
{
@@ -132,7 +132,7 @@ internal readonly struct YZWXShuffle4 : IShuffle4
{
ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source));
ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
- int n = source.Length / 4;
+ int n = (int)((uint)source.Length / 4);
for (nint i = 0; i < (uint)n; i++)
{
@@ -156,7 +156,7 @@ internal readonly struct ZYXWShuffle4 : IShuffle4
{
ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source));
ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
- int n = source.Length / 4;
+ int n = (int)((uint)source.Length / 4);
for (nint i = 0; i < (uint)n; i++)
{
@@ -187,7 +187,7 @@ internal readonly struct XWZYShuffle4 : IShuffle4
{
ref uint sBase = ref Unsafe.As(ref MemoryMarshal.GetReference(source));
ref uint dBase = ref Unsafe.As(ref MemoryMarshal.GetReference(dest));
- int n = source.Length / 4;
+ int n = (int)((uint)source.Length / 4);
for (nint i = 0; i < (uint)n; i++)
{
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
index 8c79b181c..6fc36cd70 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.FallbackIntrinsics128.cs
@@ -71,7 +71,7 @@ internal static partial class SimdUtils
{
VerifySpanInput(source, dest, 4);
- int count = dest.Length / 4;
+ int count = (int)((uint)dest.Length / 4);
if (count == 0)
{
return;
@@ -105,7 +105,7 @@ internal static partial class SimdUtils
{
VerifySpanInput(source, dest, 4);
- int count = source.Length / 4;
+ int count = (int)((uint)source.Length / 4);
if (count == 0)
{
return;
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
index 654ae3810..06b61443f 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
@@ -159,7 +159,7 @@ internal static partial class SimdUtils
int remainder = source.Length % (Vector128.Count * 3);
int sourceCount = source.Length - remainder;
- int destCount = sourceCount * 4 / 3;
+ int destCount = (int)((uint)sourceCount * 4 / 3);
if (sourceCount > 0)
{
@@ -192,7 +192,7 @@ internal static partial class SimdUtils
int remainder = source.Length % (Vector128.Count * 4);
int sourceCount = source.Length - remainder;
- int destCount = sourceCount * 3 / 4;
+ int destCount = (int)((uint)sourceCount * 3 / 4);
if (sourceCount > 0)
{
diff --git a/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
index d507d88c5..ebc43f882 100644
--- a/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
@@ -206,8 +206,8 @@ internal sealed unsafe class DeflaterHuffman : IDisposable
int lc = Lcode(litlen);
this.literalTree.WriteSymbol(pendingBuffer, lc);
- int bits = (lc - 261) / 4;
- if (bits > 0 && bits <= 5)
+ int bits = (int)(((uint)lc - 261) / 4);
+ if (bits is > 0 and <= 5)
{
this.Pending.WriteBits(litlen & ((1 << bits) - 1), bits);
}
@@ -364,7 +364,7 @@ internal sealed unsafe class DeflaterHuffman : IDisposable
this.literalTree.Frequencies[lc]++;
if (lc >= 265 && lc < 285)
{
- this.extraBits += (lc - 261) / 4;
+ this.extraBits += (int)(((uint)lc - 261) / 4);
}
int dc = Dcode(distance - 1);
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index dfc6bb961..4a71dc8b8 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -489,7 +489,7 @@ internal sealed class BmpDecoderCore : IImageDecoderInternals
// If the second byte > 2, we are in 'absolute mode'.
// The second byte contains the number of color indexes that follow.
int max = cmd[1];
- int bytesToRead = (max + 1) / 2;
+ int bytesToRead = (int)(((uint)max + 1) / 2);
byte[] run = new byte[bytesToRead];
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index f30369d19..a2c705823 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -124,7 +124,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
this.bitsPerPixel ??= bmpMetadata.BitsPerPixel;
short bpp = (short)this.bitsPerPixel;
- int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);
+ int bytesPerLine = (int)(4 * ((((uint)image.Width * (ushort)bpp) + 31) / 32));
this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F));
int colorPaletteSize = this.bitsPerPixel switch
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
index d1cb3559b..e5d252f43 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
@@ -16,7 +16,7 @@ internal partial struct Block8x8F
{
var CMin4 = new Vector4(0F);
var CMax4 = new Vector4(maximum);
- var COff4 = new Vector4(MathF.Ceiling(maximum / 2));
+ var COff4 = new Vector4(MathF.Ceiling(maximum * 0.5F)); // /2
this.V0L = Numerics.Clamp(this.V0L + COff4, CMin4, CMax4);
this.V0R = Numerics.Clamp(this.V0R + COff4, CMin4, CMax4);
@@ -42,7 +42,7 @@ internal partial struct Block8x8F
[MethodImpl(InliningOptions.ShortMethod)]
public void NormalizeColorsAndRoundInPlaceVector8(float maximum)
{
- var off = new Vector(MathF.Ceiling(maximum / 2));
+ var off = new Vector(MathF.Ceiling(maximum * 0.5F)); // /2
var max = new Vector(maximum);
ref Vector row0 = ref Unsafe.As>(ref this.V0L);
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
index aa211ea22..7350edd38 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
@@ -29,7 +29,7 @@ internal partial struct Block8x8F
{
var CMin4 = new Vector4(0F);
var CMax4 = new Vector4(maximum);
- var COff4 = new Vector4(MathF.Ceiling(maximum / 2));
+ var COff4 = new Vector4(MathF.Ceiling(maximum * 0.5F)); // /2
<#
@@ -53,7 +53,7 @@ internal partial struct Block8x8F
[MethodImpl(InliningOptions.ShortMethod)]
public void NormalizeColorsAndRoundInPlaceVector8(float maximum)
{
- var off = new Vector(MathF.Ceiling(maximum / 2));
+ var off = new Vector(MathF.Ceiling(maximum * 0.5F)); // /2
var max = new Vector(maximum);
<#
diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
index 62f48af16..1291beb47 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
@@ -26,7 +26,7 @@ internal abstract partial class JpegColorConverterBase
this.ColorSpace = colorSpace;
this.Precision = precision;
this.MaximumValue = MathF.Pow(2, precision) - 1;
- this.HalfValue = MathF.Ceiling(this.MaximumValue / 2);
+ this.HalfValue = MathF.Ceiling(this.MaximumValue * 0.5F); // /2
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor2.cs
index 51d8d0359..8b4256e3b 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor2.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor2.cs
@@ -25,7 +25,7 @@ internal sealed class DownScalingComponentProcessor2 : ComponentProcessor
Buffer2D spectralBuffer = this.Component.SpectralBlocks;
float maximumValue = this.Frame.MaxColorChannelValue;
- float normalizationValue = MathF.Ceiling(maximumValue / 2);
+ float normalizationValue = MathF.Ceiling(maximumValue * 0.5F); // /2
int destAreaStride = this.ColorBuffer.Width;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor4.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor4.cs
index b8a40f53b..170cdbb3c 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor4.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor4.cs
@@ -25,7 +25,7 @@ internal sealed class DownScalingComponentProcessor4 : ComponentProcessor
Buffer2D spectralBuffer = this.Component.SpectralBlocks;
float maximumValue = this.Frame.MaxColorChannelValue;
- float normalizationValue = MathF.Ceiling(maximumValue / 2);
+ float normalizationValue = MathF.Ceiling(maximumValue * 0.5F); // /2
int destAreaStride = this.ColorBuffer.Width;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor8.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor8.cs
index 121b74546..81104d2f3 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor8.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ComponentProcessors/DownScalingComponentProcessor8.cs
@@ -22,7 +22,7 @@ internal sealed class DownScalingComponentProcessor8 : ComponentProcessor
Buffer2D spectralBuffer = this.Component.SpectralBlocks;
float maximumValue = this.Frame.MaxColorChannelValue;
- float normalizationValue = MathF.Ceiling(maximumValue / 2);
+ float normalizationValue = MathF.Ceiling(maximumValue * 0.5F); // /2
int destAreaStride = this.ColorBuffer.Width;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
index f479df7e2..1453b0a56 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
@@ -123,7 +123,7 @@ internal class HuffmanScanEncoder
private bool IsStreamFlushNeeded
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => this.emitWriteIndex < (uint)this.emitBuffer.Length / 2;
+ get => this.emitWriteIndex < (int)((uint)this.emitBuffer.Length / 2);
}
public void BuildHuffmanTable(JpegHuffmanTableConfig tableConfig)
diff --git a/src/ImageSharp/Formats/Jpeg/Components/ScaledFloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/ScaledFloatingPointDCT.cs
index 369626a96..4f67b7dfe 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/ScaledFloatingPointDCT.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ScaledFloatingPointDCT.cs
@@ -103,10 +103,10 @@ internal static class ScaledFloatingPointDCT
// temporal result is saved to +4 shifted indices
// because result is saved into the top left 2x2 region of the
// input block
- block[(ctr * 8) + 0 + 4] = (tmp10 + tmp2) / 2;
- block[(ctr * 8) + 3 + 4] = (tmp10 - tmp2) / 2;
- block[(ctr * 8) + 1 + 4] = (tmp12 + tmp0) / 2;
- block[(ctr * 8) + 2 + 4] = (tmp12 - tmp0) / 2;
+ block[(ctr * 8) + 0 + 4] = (tmp10 + tmp2) * 0.5F;
+ block[(ctr * 8) + 3 + 4] = (tmp10 - tmp2) * 0.5F;
+ block[(ctr * 8) + 1 + 4] = (tmp12 + tmp0) * 0.5F;
+ block[(ctr * 8) + 2 + 4] = (tmp12 - tmp0) * 0.5F;
}
for (int ctr = 0; ctr < 4; ctr++)
@@ -136,10 +136,10 @@ internal static class ScaledFloatingPointDCT
(z4 * FP32_2_562915447);
// Save results to the top left 4x4 subregion
- block[(ctr * 8) + 0] = MathF.Round(Numerics.Clamp(((tmp10 + tmp2) / 2) + normalizationValue, 0, maxValue));
- block[(ctr * 8) + 3] = MathF.Round(Numerics.Clamp(((tmp10 - tmp2) / 2) + normalizationValue, 0, maxValue));
- block[(ctr * 8) + 1] = MathF.Round(Numerics.Clamp(((tmp12 + tmp0) / 2) + normalizationValue, 0, maxValue));
- block[(ctr * 8) + 2] = MathF.Round(Numerics.Clamp(((tmp12 - tmp0) / 2) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 0] = MathF.Round(Numerics.Clamp(((tmp10 + tmp2) * 0.5F) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 3] = MathF.Round(Numerics.Clamp(((tmp10 - tmp2) * 0.5F) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 1] = MathF.Round(Numerics.Clamp(((tmp12 + tmp0) * 0.5F) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 2] = MathF.Round(Numerics.Clamp(((tmp12 - tmp0) * 0.5F) + normalizationValue, 0, maxValue));
}
}
@@ -183,8 +183,8 @@ internal static class ScaledFloatingPointDCT
// temporal result is saved to +2 shifted indices
// because result is saved into the top left 2x2 region of the
// input block
- block[(ctr * 8) + 2] = (tmp10 + tmp0) / 4;
- block[(ctr * 8) + 3] = (tmp10 - tmp0) / 4;
+ block[(ctr * 8) + 2] = (tmp10 + tmp0) * 0.25F; // /4
+ block[(ctr * 8) + 3] = (tmp10 - tmp0) * 0.25F; // /4
}
for (int ctr = 0; ctr < 2; ctr++)
@@ -199,8 +199,8 @@ internal static class ScaledFloatingPointDCT
(block[ctr + (8 * 1) + 2] * FP32_3_624509785);
// Save results to the top left 2x2 subregion
- block[(ctr * 8) + 0] = MathF.Round(Numerics.Clamp(((tmp10 + tmp0) / 4) + normalizationValue, 0, maxValue));
- block[(ctr * 8) + 1] = MathF.Round(Numerics.Clamp(((tmp10 - tmp0) / 4) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 0] = MathF.Round(Numerics.Clamp(((tmp10 + tmp0) * 0.25F) + normalizationValue, 0, maxValue));
+ block[(ctr * 8) + 1] = MathF.Round(Numerics.Clamp(((tmp10 - tmp0) * 0.25F) + normalizationValue, 0, maxValue));
}
}
diff --git a/src/ImageSharp/Formats/Png/Adam7.cs b/src/ImageSharp/Formats/Png/Adam7.cs
index f52a66c26..8310ca64c 100644
--- a/src/ImageSharp/Formats/Png/Adam7.cs
+++ b/src/ImageSharp/Formats/Png/Adam7.cs
@@ -67,16 +67,22 @@ internal static class Adam7
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ComputeColumns(int width, int passIndex)
{
- switch (passIndex)
+ uint w = (uint)width;
+
+ uint result = passIndex switch
{
- case 0: return (width + 7) / 8;
- case 1: return (width + 3) / 8;
- case 2: return (width + 3) / 4;
- case 3: return (width + 1) / 4;
- case 4: return (width + 1) / 2;
- case 5: return width / 2;
- case 6: return width;
- default: throw new ArgumentException($"Not a valid pass index: {passIndex}");
- }
+ 0 => (w + 7) / 8,
+ 1 => (w + 3) / 8,
+ 2 => (w + 3) / 4,
+ 3 => (w + 1) / 4,
+ 4 => (w + 1) / 2,
+ 5 => w / 2,
+ 6 => w,
+ _ => Throw(passIndex)
+ };
+
+ return (int)result;
+
+ static uint Throw(int passIndex) => throw new ArgumentException($"Not a valid pass index: {passIndex}");
}
}
diff --git a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
index 36f8c20d7..d57dea994 100644
--- a/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
+++ b/src/ImageSharp/Formats/Tiff/Compression/TiffBaseCompression.cs
@@ -16,7 +16,7 @@ internal abstract class TiffBaseCompression : IDisposable
this.Width = width;
this.BitsPerPixel = bitsPerPixel;
this.Predictor = predictor;
- this.BytesPerRow = ((width * bitsPerPixel) + 7) / 8;
+ this.BytesPerRow = (int)(((uint)(width * bitsPerPixel) + 7) / 8);
}
///
diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
index 45bbed12d..4499c5583 100644
--- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
@@ -793,7 +793,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
}
}
- int bytesPerRow = ((width * bitsPerPixel) + 7) / 8;
+ int bytesPerRow = (int)(((uint)(width * bitsPerPixel) + 7) / 8);
return bytesPerRow * height;
}
diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter{TPixel}.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter{TPixel}.cs
index 189c8fd6a..c4a749255 100644
--- a/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter{TPixel}.cs
+++ b/src/ImageSharp/Formats/Tiff/Writers/TiffBaseColorWriter{TPixel}.cs
@@ -29,7 +29,7 @@ internal abstract class TiffBaseColorWriter : IDisposable
///
/// Gets the bytes per row.
///
- public int BytesPerRow => ((this.Image.Width * this.BitsPerPixel) + 7) / 8;
+ public int BytesPerRow => (int)(((uint)(this.Image.Width * this.BitsPerPixel) + 7) / 8);
protected ImageFrame Image { get; }
diff --git a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
index b83b44fa1..5b4eab64a 100644
--- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
+++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
@@ -457,7 +457,7 @@ internal class Vp8BitWriter : BitWriterBase
this.Finish();
uint numBytes = (uint)this.NumBytes();
int mbSize = this.enc.Mbw * this.enc.Mbh;
- int expectedSize = mbSize * 7 / 8;
+ int expectedSize = (int)((uint)mbSize * 7 / 8);
Vp8BitWriter bitWriterPartZero = new(expectedSize, this.enc);
diff --git a/src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
index 139518163..5eec2a2ca 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
@@ -316,7 +316,7 @@ internal class HistogramEncoder
int triesWithNoSuccess = 0;
int numUsed = histograms.Count(h => h != null);
int outerIters = numUsed;
- int numTriesNoSuccess = outerIters / 2;
+ int numTriesNoSuccess = (int)((uint)outerIters / 2);
var stats = new Vp8LStreaks();
var bitsEntropy = new Vp8LBitEntropy();
@@ -346,7 +346,7 @@ internal class HistogramEncoder
for (int iter = 0; iter < outerIters && numUsed >= minClusterSize && ++triesWithNoSuccess < numTriesNoSuccess; iter++)
{
double bestCost = histoPriorityList.Count == 0 ? 0.0d : histoPriorityList[0].CostDiff;
- int numTries = numUsed / 2;
+ int numTries = (int)((uint)numUsed / 2);
uint randRange = (uint)((numUsed - 1) * numUsed);
// Pick random samples.
diff --git a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
index 5cee6bc39..18104331c 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
@@ -100,7 +100,7 @@ internal static class HuffmanUtils
uint k;
// The stride must end, collapse what we have, if we have enough (4).
- uint count = (uint)((sum + (stride / 2)) / stride);
+ uint count = (sum + ((uint)stride / 2)) / (uint)stride;
if (count < 1)
{
count = 1;
@@ -144,7 +144,7 @@ internal static class HuffmanUtils
sum += counts[i];
if (stride >= 4)
{
- limit = (uint)((sum + (stride / 2)) / stride);
+ limit = (sum + ((uint)stride / 2)) / (uint)stride;
}
}
}
diff --git a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
index d4db3db53..8a5ec162f 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
@@ -1440,7 +1440,12 @@ internal static unsafe class LosslessUtils
}
[MethodImpl(InliningOptions.ShortMethod)]
- private static int AddSubtractComponentHalf(int a, int b) => (int)Clip255((uint)(a + ((a - b) / 2)));
+ private static int AddSubtractComponentHalf(int a, int b)
+ {
+ uint ua = (uint)a;
+ uint ub = (uint)b;
+ return (int)Clip255(ua + ((ua - ub) / 2));
+ }
[MethodImpl(InliningOptions.ShortMethod)]
private static int AddSubtractComponentFull(int a, int b, int c) => (int)Clip255((uint)(a + b - c));
diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
index e714a7725..7be0e69f7 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
@@ -963,7 +963,7 @@ internal class Vp8LEncoder : IDisposable
else
{
int nBits = BitOperations.Log2((uint)trimmedLength - 2);
- int nBitPairs = (nBits / 2) + 1;
+ int nBitPairs = (int)(((uint)nBits / 2) + 1);
this.bitWriter.PutBits((uint)nBitPairs - 1, 3);
this.bitWriter.PutBits((uint)trimmedLength - 2, nBitPairs * 2);
}
@@ -1820,7 +1820,7 @@ internal class Vp8LEncoder : IDisposable
{
// VP8LResidualImage needs room for 2 scanlines of uint32 pixels with an extra
// pixel in each, plus 2 regular scanlines of bytes.
- int bgraScratchSize = this.UsePredictorTransform ? ((width + 1) * 2) + (((width * 2) + 4 - 1) / 4) : 0;
+ int bgraScratchSize = this.UsePredictorTransform ? (int)((((uint)width + 1) * 2) + ((((uint)width * 2) + 4 - 1) / 4)) : 0;
int transformDataSize = this.UsePredictorTransform || this.UseCrossColorTransform ? LosslessUtils.SubSampleSize(width, this.TransformBits) * LosslessUtils.SubSampleSize(height, this.TransformBits) : 0;
this.BgraScratch = this.memoryAllocator.Allocate(bgraScratchSize);
diff --git a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs
index 527242906..32d4fcbb6 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs
@@ -59,7 +59,7 @@ internal sealed class Vp8LHashChain : IDisposable
public void Fill(ReadOnlySpan bgra, int quality, int xSize, int ySize, bool lowEffort)
{
int size = xSize * ySize;
- int iterMax = GetMaxItersForQuality(quality);
+ int iterMax = GetMaxItersForQuality((uint)quality);
int windowSize = GetWindowSizeForHashChain(quality, xSize);
int pos;
@@ -272,7 +272,7 @@ internal sealed class Vp8LHashChain : IDisposable
/// The quality.
/// Number of hash chain lookups.
[MethodImpl(InliningOptions.ShortMethod)]
- private static int GetMaxItersForQuality(int quality) => 8 + (quality * quality / 128);
+ private static int GetMaxItersForQuality(uint quality) => (int)(8 + (quality * quality / 128));
[MethodImpl(InliningOptions.ShortMethod)]
private static int GetWindowSizeForHashChain(int quality, int xSize)
diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
index 16b4c827e..186aa6c21 100644
--- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
@@ -683,7 +683,7 @@ internal class Vp8Encoder : IDisposable
{
if (accum[n] != 0)
{
- int newCenter = (distAccum[n] + (accum[n] / 2)) / accum[n];
+ int newCenter = (distAccum[n] + (accum[n] >> 1)) / accum[n]; // >> 1 is bit-hack for / 2
displaced += Math.Abs(centers[n] - newCenter);
centers[n] = newCenter;
weightedAverage += newCenter * accum[n];
@@ -691,7 +691,7 @@ internal class Vp8Encoder : IDisposable
}
}
- weightedAverage = (weightedAverage + (totalWeight / 2)) / totalWeight;
+ weightedAverage = (weightedAverage + (totalWeight >> 1)) / totalWeight; // >> 1 is bit-hack for / 2
if (displaced < 5)
{
break; // no need to keep on looping...
@@ -1177,6 +1177,6 @@ internal class Vp8Encoder : IDisposable
{
int total = a + b;
return total == 0 ? 255 // that's the default probability.
- : ((255 * a) + (total / 2)) / total; // rounded proba
+ : ((255 * a) + (int)((uint)total / 2)) / total; // rounded proba
}
}
diff --git a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs
index e63a7ef74..36f3abcd9 100644
--- a/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs
@@ -731,7 +731,7 @@ internal sealed class WebpLossyDecoder
Span dst = buf[dstStartIdx..];
int yEnd = io.MbY + io.MbH;
int mbw = io.MbW;
- int uvw = (mbw + 1) / 2;
+ int uvw = (int)(((uint)mbw + 1) / 2);
int y = io.MbY;
byte[] uvBuffer = new byte[(14 * 32) + 15];
diff --git a/src/ImageSharp/IO/ChunkedMemoryStream.cs b/src/ImageSharp/IO/ChunkedMemoryStream.cs
index da52f7ca8..253454814 100644
--- a/src/ImageSharp/IO/ChunkedMemoryStream.cs
+++ b/src/ImageSharp/IO/ChunkedMemoryStream.cs
@@ -547,7 +547,7 @@ internal sealed class ChunkedMemoryStream : Stream
#pragma warning disable IDE1006 // Naming Styles
const int _128K = 1 << 17;
const int _4M = 1 << 22;
- return i < 16 ? _128K * (1 << (i / 4)) : _4M;
+ return i < 16 ? _128K * (1 << (int)((uint)i / 4)) : _4M;
#pragma warning restore IDE1006 // Naming Styles
}
diff --git a/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs b/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
index 2cb4421d5..798edf9b2 100644
--- a/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
+++ b/src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
@@ -156,7 +156,7 @@ internal sealed class UniformUnmanagedMemoryPoolMemoryAllocator : MemoryAllocato
// Workaround for https://github.com/dotnet/runtime/issues/65466
if (total > 0)
{
- return total / 8;
+ return (long)((ulong)total / 8);
}
}
diff --git a/src/ImageSharp/Primitives/Rectangle.cs b/src/ImageSharp/Primitives/Rectangle.cs
index baffbc7f4..2f0df3574 100644
--- a/src/ImageSharp/Primitives/Rectangle.cs
+++ b/src/ImageSharp/Primitives/Rectangle.cs
@@ -195,7 +195,7 @@ public struct Rectangle : IEquatable
/// The rectangle.
/// The .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Point Center(Rectangle rectangle) => new(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2));
+ public static Point Center(Rectangle rectangle) => new(rectangle.Left + (rectangle.Width & 1), rectangle.Top + (rectangle.Height & 1)); // & 1 is bit-hack for / 2
///
/// Creates a rectangle that represents the intersection between and
diff --git a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
index b710243a5..1c76ea6a4 100644
--- a/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
@@ -132,7 +132,7 @@ internal class BinaryThresholdProcessor : ImageProcessor
case BinaryThresholdMode.MaxChroma:
{
- float threshold = this.threshold / 2F;
+ float threshold = this.threshold * 0.5F; // /2
for (int x = 0; x < rowSpan.Length; x++)
{
float chroma = GetMaxChroma(span[x]);
@@ -149,9 +149,10 @@ internal class BinaryThresholdProcessor : ImageProcessor
private static float GetSaturation(Rgb24 rgb)
{
// Slimmed down RGB => HSL formula. See HslAndRgbConverter.
- float r = rgb.R / 255F;
- float g = rgb.G / 255F;
- float b = rgb.B / 255F;
+ const float inv255 = 1 / 255F;
+ float r = rgb.R * inv255;
+ float g = rgb.G * inv255;
+ float b = rgb.B * inv255;
float max = MathF.Max(r, MathF.Max(g, b));
float min = MathF.Min(r, MathF.Min(g, b));
@@ -162,7 +163,7 @@ internal class BinaryThresholdProcessor : ImageProcessor
return 0F;
}
- float l = (max + min) / 2F;
+ float l = (max + min) * 0.5F; // /2
if (l <= .5F)
{
diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs
index e2272db03..0baa87a61 100644
--- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs
@@ -59,8 +59,8 @@ internal class AdaptiveHistogramEqualizationProcessor : HistogramEqualiz
int tileWidth = (int)MathF.Ceiling(sourceWidth / (float)this.Tiles);
int tileHeight = (int)MathF.Ceiling(sourceHeight / (float)this.Tiles);
int tileCount = this.Tiles;
- int halfTileWidth = tileWidth / 2;
- int halfTileHeight = tileHeight / 2;
+ int halfTileWidth = (int)((uint)tileWidth / 2);
+ int halfTileHeight = (int)((uint)tileHeight / 2);
int luminanceLevels = this.LuminanceLevels;
// The image is split up into tiles. For each tile the cumulative distribution function will be calculated.
@@ -176,7 +176,7 @@ internal class AdaptiveHistogramEqualizationProcessor : HistogramEqualiz
int xEnd,
int luminanceLevels)
{
- int halfTileHeight = tileHeight / 2;
+ int halfTileHeight = (int)((uint)tileHeight / 2);
int cdfY = 0;
int y = halfTileHeight;
@@ -228,7 +228,7 @@ internal class AdaptiveHistogramEqualizationProcessor : HistogramEqualiz
int yEnd,
int luminanceLevels)
{
- int halfTileWidth = tileWidth / 2;
+ int halfTileWidth = (int)((uint)tileWidth / 2);
int cdfX = 0;
int x = halfTileWidth;
diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
index f25db12c2..bbac9b9d8 100644
--- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
@@ -59,7 +59,7 @@ internal class AdaptiveHistogramEqualizationSlidingWindowProcessor : His
int tileWidth = source.Width / this.Tiles;
int tileHeight = tileWidth;
int pixelInTile = tileWidth * tileHeight;
- int halfTileHeight = tileHeight / 2;
+ int halfTileHeight = (int)((uint)tileHeight / 2);
int halfTileWidth = halfTileHeight;
SlidingWindowInfos slidingWindowInfos = new(tileWidth, tileHeight, halfTileWidth, halfTileHeight, pixelInTile);
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs
index 11befd5da..14da3ac89 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/FlipProcessor{TPixel}.cs
@@ -54,7 +54,7 @@ internal class FlipProcessor : ImageProcessor
using IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(source.Width);
Span temp = tempBuffer.Memory.Span;
- for (int yTop = 0; yTop < height / 2; yTop++)
+ for (int yTop = 0; yTop < (int)((uint)height / 2); yTop++)
{
int yBottom = height - yTop - 1;
Span topRow = source.DangerousGetRowSpan(yBottom);
diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs
index d03a694ba..d90f948b6 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs
@@ -105,11 +105,11 @@ internal static class ResizeHelper
switch (options.Position)
{
case AnchorPositionMode.Left:
- targetY = (height - sourceHeight) / 2;
+ targetY = (int)((uint)(height - sourceHeight) / 2);
targetX = 0;
break;
case AnchorPositionMode.Right:
- targetY = (height - sourceHeight) / 2;
+ targetY = (int)((uint)(height - sourceHeight) / 2);
targetX = width - sourceWidth;
break;
case AnchorPositionMode.TopRight:
@@ -118,7 +118,7 @@ internal static class ResizeHelper
break;
case AnchorPositionMode.Top:
targetY = 0;
- targetX = (width - sourceWidth) / 2;
+ targetX = (int)((uint)(width - sourceWidth) / 2);
break;
case AnchorPositionMode.TopLeft:
targetY = 0;
@@ -130,15 +130,15 @@ internal static class ResizeHelper
break;
case AnchorPositionMode.Bottom:
targetY = height - sourceHeight;
- targetX = (width - sourceWidth) / 2;
+ targetX = (int)((uint)(width - sourceWidth) / 2);
break;
case AnchorPositionMode.BottomLeft:
targetY = height - sourceHeight;
targetX = 0;
break;
default:
- targetY = (height - sourceHeight) / 2;
- targetX = (width - sourceWidth) / 2;
+ targetY = (int)((uint)(height - sourceHeight) / 2);
+ targetX = (int)((uint)(width - sourceWidth) / 2);
break;
}