Skip to content

Commit

Permalink
feat: make Percentage always positive
Browse files Browse the repository at this point in the history
  • Loading branch information
Gounlaf committed Mar 1, 2024
1 parent 51134bb commit 483e875
Show file tree
Hide file tree
Showing 17 changed files with 43 additions and 369 deletions.
24 changes: 20 additions & 4 deletions src/Magick.NET.Core/Types/Percentage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@ namespace ImageMagick;
/// </summary>
/// <param name="value">The value (0% = 0.0, 100% = 100.0).</param>
public Percentage(double value)
=> _value = value;
{
Throw.IfNegative(nameof(value), value);

_value = value;
}

/// <summary>
/// Initializes a new instance of the <see cref="Percentage"/> struct.
/// </summary>
/// <param name="value">The value (0% = 0, 100% = 100).</param>
public Percentage(int value)
=> _value = value;
{
Throw.IfNegative(nameof(value), value);

_value = value;
}

/// <summary>
/// Converts the specified double to an instance of this type.
Expand Down Expand Up @@ -170,15 +178,23 @@ public override int GetHashCode()
/// <param name="value">The value to use.</param>
/// <returns>The new value.</returns>
public double Multiply(double value)
=> (value * _value) / 100.0;
{
Throw.IfNegative(nameof(value), value);

return (value * _value) / 100.0;
}

/// <summary>
/// Multiplies the value by the specified percentage.
/// </summary>
/// <param name="value">The value to use.</param>
/// <returns>The new value.</returns>
public int Multiply(int value)
=> (int)((value * _value) / 100.0);
{
Throw.IfNegative(nameof(value), value);

return (int)((value * _value) / 100.0);
}

/// <summary>
/// Returns a double that represents the current percentage.
Expand Down
45 changes: 5 additions & 40 deletions src/Magick.NET/MagickImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1358,11 +1358,7 @@ public void BlackThreshold(Percentage threshold)
/// <param name="channels">The channel(s) to make black.</param>
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void BlackThreshold(Percentage threshold, Channels channels)
{
Throw.IfNegative(nameof(threshold), threshold);

_nativeInstance.BlackThreshold(threshold.ToString(), channels);
}
=> _nativeInstance.BlackThreshold(threshold.ToString(), channels);

/// <summary>
/// Simulate a scene at nighttime in the moonlight.
Expand Down Expand Up @@ -1736,11 +1732,7 @@ public void ColorDecisionList(string fileName)
/// <param name="alpha">The alpha percentage.</param>
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void Colorize(IMagickColor<QuantumType> color, Percentage alpha)
{
Throw.IfNegative(nameof(alpha), alpha);

Colorize(color, alpha, alpha, alpha);
}
=> Colorize(color, alpha, alpha, alpha);

/// <summary>
/// Colorize image with the specified color, using specified percent alpha for red, green,
Expand All @@ -1754,9 +1746,6 @@ public void Colorize(IMagickColor<QuantumType> color, Percentage alpha)
public void Colorize(IMagickColor<QuantumType> color, Percentage alphaRed, Percentage alphaGreen, Percentage alphaBlue)
{
Throw.IfNull(nameof(color), color);
Throw.IfNegative(nameof(alphaRed), alphaRed);
Throw.IfNegative(nameof(alphaGreen), alphaGreen);
Throw.IfNegative(nameof(alphaBlue), alphaBlue);

var blend = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", alphaRed.ToInt32(), alphaGreen.ToInt32(), alphaBlue.ToInt32());

Expand Down Expand Up @@ -2282,9 +2271,6 @@ public void ContrastStretch(Percentage blackPoint, Percentage whitePoint)
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void ContrastStretch(Percentage blackPoint, Percentage whitePoint, Channels channels)
{
Throw.IfNegative(nameof(blackPoint), blackPoint);
Throw.IfNegative(nameof(whitePoint), whitePoint);

var contrast = CalculateContrastStretch(blackPoint, whitePoint);
_nativeInstance.ContrastStretch(contrast.X, contrast.Y, channels);
}
Expand Down Expand Up @@ -2500,7 +2486,6 @@ public double Deskew(Percentage threshold)
public double Deskew(IDeskewSettings settings)
{
Throw.IfNull(nameof(settings), settings);
Throw.IfNegative(nameof(settings), settings.Threshold);

using var temporaryDefines = new TemporaryDefines(this);
temporaryDefines.SetArtifact("deskew:auto-crop", settings.AutoCrop);
Expand Down Expand Up @@ -3849,12 +3834,7 @@ public void LevelColors(IMagickColor<QuantumType> blackColor, IMagickColor<Quant
/// <param name="whitePoint">The white point.</param>
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void LinearStretch(Percentage blackPoint, Percentage whitePoint)
{
Throw.IfNegative(nameof(blackPoint), blackPoint);
Throw.IfNegative(nameof(whitePoint), whitePoint);

_nativeInstance.LinearStretch(PercentageHelper.ToQuantum(blackPoint), PercentageHelper.ToQuantum(whitePoint));
}
=> _nativeInstance.LinearStretch(PercentageHelper.ToQuantum(blackPoint), PercentageHelper.ToQuantum(whitePoint));

/// <summary>
/// Rescales image with seam carving.
Expand Down Expand Up @@ -4125,10 +4105,6 @@ public void Modulate(Percentage brightness, Percentage saturation)
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void Modulate(Percentage brightness, Percentage saturation, Percentage hue)
{
Throw.IfNegative(nameof(brightness), brightness);
Throw.IfNegative(nameof(saturation), saturation);
Throw.IfNegative(nameof(hue), hue);

var modulate = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}", brightness.ToDouble(), saturation.ToDouble(), hue.ToDouble());

_nativeInstance.Modulate(modulate);
Expand Down Expand Up @@ -4698,14 +4674,7 @@ public void RandomThreshold(QuantumType low, QuantumType high, Channels channels
/// <param name="percentageHighBlack">Defines the maximum black threshold value.</param>
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void RangeThreshold(Percentage percentageLowBlack, Percentage percentageLowWhite, Percentage percentageHighWhite, Percentage percentageHighBlack)
{
Throw.IfNegative(nameof(percentageLowBlack), percentageLowBlack);
Throw.IfNegative(nameof(percentageLowWhite), percentageLowWhite);
Throw.IfNegative(nameof(percentageHighWhite), percentageHighWhite);
Throw.IfNegative(nameof(percentageHighBlack), percentageHighBlack);

RangeThreshold(PercentageHelper.ToQuantumType(percentageLowBlack), PercentageHelper.ToQuantumType(percentageLowWhite), PercentageHelper.ToQuantumType(percentageHighWhite), PercentageHelper.ToQuantumType(percentageHighBlack));
}
=> RangeThreshold(PercentageHelper.ToQuantumType(percentageLowBlack), PercentageHelper.ToQuantumType(percentageLowWhite), PercentageHelper.ToQuantumType(percentageHighWhite), PercentageHelper.ToQuantumType(percentageHighBlack));

/// <summary>
/// Applies soft and hard thresholding.
Expand Down Expand Up @@ -6908,11 +6877,7 @@ public void WhiteThreshold(Percentage threshold)
/// <param name="channels">The channel(s) to make black.</param>
/// <exception cref="MagickException">Thrown when an error is raised by ImageMagick.</exception>
public void WhiteThreshold(Percentage threshold, Channels channels)
{
Throw.IfNegative(nameof(threshold), threshold);

_nativeInstance.WhiteThreshold(threshold.ToString(), channels);
}
=> _nativeInstance.WhiteThreshold(threshold.ToString(), channels);

/// <summary>
/// Writes the image to the specified file.
Expand Down
14 changes: 2 additions & 12 deletions src/Magick.NET/Types/MagickGeometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ public MagickGeometry(int x, int y, int width, int height)
/// <param name="percentageWidth">The percentage of the width.</param>
/// <param name="percentageHeight">The percentage of the height.</param>
public MagickGeometry(Percentage percentageWidth, Percentage percentageHeight)
{
Throw.IfNegative(nameof(percentageWidth), percentageWidth);
Throw.IfNegative(nameof(percentageHeight), percentageHeight);

InitializeFromPercentage(0, 0, (int)percentageWidth, (int)percentageHeight);
}
=> InitializeFromPercentage(0, 0, (int)percentageWidth, (int)percentageHeight);

/// <summary>
/// Initializes a new instance of the <see cref="MagickGeometry"/> class using the specified offsets, width and height.
Expand All @@ -63,12 +58,7 @@ public MagickGeometry(Percentage percentageWidth, Percentage percentageHeight)
/// <param name="percentageWidth">The percentage of the width.</param>
/// <param name="percentageHeight">The percentage of the height.</param>
public MagickGeometry(int x, int y, Percentage percentageWidth, Percentage percentageHeight)
{
Throw.IfNegative(nameof(percentageWidth), percentageWidth);
Throw.IfNegative(nameof(percentageHeight), percentageHeight);

InitializeFromPercentage(x, y, (int)percentageWidth, (int)percentageHeight);
}
=> InitializeFromPercentage(x, y, (int)percentageWidth, (int)percentageHeight);

/// <summary>
/// Initializes a new instance of the <see cref="MagickGeometry"/> class using the specified geometry.
Expand Down
6 changes: 6 additions & 0 deletions src/Shared/Throw.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public static void IfNegative(string paramName, int value)
throw new ArgumentException("Value should not be negative.", paramName);
}

public static void IfNegative(string paramName, double value)
{
if (value < 0.0)
throw new ArgumentException("Value should not be negative.", paramName);
}

public static void IfNegative(string paramName, Percentage value)
{
if ((double)value < 0.0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Dirk Lemstra https://github.com/dlemstra/Magick.NET.
// Licensed under the Apache License, Version 2.0.

using System;
using ImageMagick;
using Xunit;

Expand All @@ -10,6 +11,15 @@ public partial class PercentageTests
{
public class TheConstructor
{
[Fact]
public void ShouldThrowExceptionWhenValueIsNegative()
{
Assert.Throws<ArgumentException>("value", () => new Percentage(-1.0));
Assert.Throws<ArgumentException>("value", () => (Percentage)(-1.0));
Assert.Throws<ArgumentException>("value", () => new Percentage(-1));
Assert.Throws<ArgumentException>("value", () => (Percentage)(-1));
}

[Fact]
public void ShouldDefaultToZero()
{
Expand All @@ -30,12 +40,5 @@ public void ShouldHandleValueAbove100()
var percentage = new Percentage(200.0);
Assert.Equal("200%", percentage.ToString());
}

[Fact]
public void ShouldHandleNegativeValue()
{
var percentage = new Percentage(-25);
Assert.Equal("-25%", percentage.ToString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -244,21 +244,5 @@ public void ShouldThrowExceptionWhenHeightIsNegative()
Assert.Throws<ArgumentException>("height", () => factory.Create(5, -1));
Assert.Throws<ArgumentException>("height", () => factory.Create(0, 0, 5, -1));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageWidthIsNegative()
{
var factory = new MagickGeometryFactory();

Assert.Throws<ArgumentException>("percentageWidth", () => factory.Create(new Percentage(-1), new Percentage(10)));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageHeightIsNegative()
{
var factory = new MagickGeometryFactory();

Assert.Throws<ArgumentException>("percentageHeight", () => factory.Create(new Percentage(10), new Percentage(-1)));
}
}
}
32 changes: 0 additions & 32 deletions tests/Magick.NET.Tests/MagickImageTests/TheColorizeMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ public void ShouldThrowExceptionWhenColorIsNull()
Assert.Throws<ArgumentNullException>("color", () => image.Colorize(null, new Percentage(50)));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageIsNegative()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("alpha", () => image.Colorize(MagickColors.Purple, new Percentage(-1)));
}

[Fact]
public void ShouldColorizeTheImage()
{
Expand All @@ -49,30 +41,6 @@ public void ShouldThrowExceptionWhenColorIsNull()
Assert.Throws<ArgumentNullException>("color", () => image.Colorize(null, new Percentage(25), new Percentage(50), new Percentage(75)));
}

[Fact]
public void ShouldThrowExceptionWhenAlphaRedIsNegative()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("alphaRed", () => image.Colorize(MagickColors.Purple, new Percentage(-1), new Percentage(50), new Percentage(75)));
}

[Fact]
public void ShouldThrowExceptionWhenAlphaGreenIsNegative()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("alphaGreen", () => image.Colorize(MagickColors.Purple, new Percentage(25), new Percentage(-1), new Percentage(75)));
}

[Fact]
public void ShouldThrowExceptionWhenAlphaBlueIsNegative()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("alphaBlue", () => image.Colorize(MagickColors.Purple, new Percentage(25), new Percentage(50), new Percentage(-1)));
}

[Fact]
public void ShouldColorizeTheImage()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,6 @@ public partial class MagickImageTests
{
public class TheContrastStretchMethod
{
[Fact]
public void ShouldThrowExceptionWhenPercentageIsNull()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("blackPoint", () => image.ContrastStretch(new Percentage(-1)));
}

[Fact]
public void ShouldThrowExceptionWhenBlackPointIsNull()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("blackPoint", () => image.ContrastStretch(new Percentage(-1), new Percentage(50)));
}

[Fact]
public void ShouldThrowExceptionWhenWhitePointIsNull()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("whitePoint", () => image.ContrastStretch(new Percentage(50), new Percentage(-1)));
}

[Fact]
public void ShouldImproveTheContrast()
{
Expand Down
20 changes: 0 additions & 20 deletions tests/Magick.NET.Tests/MagickImageTests/TheDeskewMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,6 @@ public void ShouldThrowExceptionWhenSettingsIsNull()
Assert.Throws<ArgumentNullException>("settings", () => image.Deskew(null));
}

[Fact]
public void ShouldThrowExceptionWhenSettingsThresholdIsNegative()
{
var settings = new DeskewSettings
{
Threshold = new Percentage(-1),
};
using var image = new MagickImage();

Assert.Throws<ArgumentException>("settings", () => image.Deskew(settings));
}

[Fact]
public void ShouldThrowExceptionWhenThresholdIsNegative()
{
using var image = new MagickImage();

Assert.Throws<ArgumentException>("settings", () => image.Deskew(new Percentage(-1)));
}

[Fact]
public void ShouldDeskewTheImage()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,6 @@ public void ShouldThrowExceptionWhenHeightIsNegative()
Assert.Throws<ArgumentException>("height", () => image.InterpolativeResize(32, -1, PixelInterpolateMethod.Mesh));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageIsNegative()
{
using var image = new MagickImage(Files.RedPNG);
Assert.Throws<ArgumentException>("percentageWidth", () => image.InterpolativeResize(new Percentage(-1), PixelInterpolateMethod.Mesh));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageWidthIsNegative()
{
using var image = new MagickImage(Files.RedPNG);
Assert.Throws<ArgumentException>("percentageWidth", () => image.InterpolativeResize(new Percentage(-1), new Percentage(10), PixelInterpolateMethod.Mesh));
}

[Fact]
public void ShouldThrowExceptionWhenPercentageHeightIsNegative()
{
using var image = new MagickImage(Files.RedPNG);
Assert.Throws<ArgumentException>("percentageHeight", () => image.InterpolativeResize(new Percentage(10), new Percentage(-1), PixelInterpolateMethod.Mesh));
}

[Fact]
public void ShouldResizeTheImage()
{
Expand Down
Loading

0 comments on commit 483e875

Please sign in to comment.