diff --git a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs index eb1ba8140..158786e3c 100644 --- a/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs @@ -88,6 +88,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm if (this.colorType != PbmColorType.BlackAndWhite) { this.maxPixelValue = this.options.MaxPixelValue ?? metadata.MaxPixelValue; + this.maxPixelValue = Math.Max(this.maxPixelValue, PbmConstants.MaxLength); } } diff --git a/src/ImageSharp/Formats/Pbm/PlainEncoder.cs b/src/ImageSharp/Formats/Pbm/PlainEncoder.cs index b67f0a077..2e7c60e5e 100644 --- a/src/ImageSharp/Formats/Pbm/PlainEncoder.cs +++ b/src/ImageSharp/Formats/Pbm/PlainEncoder.cs @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner row = allocator.Allocate(width); Span rowSpan = row.GetSpan(); - IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelGrayscale); + using IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelGrayscale); Span plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner row = allocator.Allocate(width); Span rowSpan = row.GetSpan(); - IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelGrayscaleWide); + using IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelGrayscaleWide); Span plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) @@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner row = allocator.Allocate(width); Span rowSpan = row.GetSpan(); - IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelRgb); + using IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelRgb); Span plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) @@ -178,7 +178,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner row = allocator.Allocate(width); Span rowSpan = row.GetSpan(); - IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelRgbWide); + using IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelRgbWide); Span plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner row = allocator.Allocate(width); Span rowSpan = row.GetSpan(); - IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelBlackAndWhite); + using IMemoryOwner plainMemory = allocator.Allocate(width * MaxCharsPerPixelBlackAndWhite); Span plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) diff --git a/tests/ImageSharp.Tests/Formats/Pbm/PbmDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmDecoderTests.cs index 6c84fba9e..479db2ca5 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/PbmDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/PbmDecoderTests.cs @@ -84,6 +84,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Pbm where TPixel : unmanaged, IPixel { using Image image = provider.GetImage(); + image.DebugSave(provider); image.CompareToReferenceOutput(provider, grayscale: isGrayscale); } diff --git a/tests/ImageSharp.Tests/Formats/Pbm/RoundTripTests.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmRoundTripTests.cs similarity index 62% rename from tests/ImageSharp.Tests/Formats/Pbm/RoundTripTests.cs rename to tests/ImageSharp.Tests/Formats/Pbm/PbmRoundTripTests.cs index 391e8c054..715a1e07e 100644 --- a/tests/ImageSharp.Tests/Formats/Pbm/RoundTripTests.cs +++ b/tests/ImageSharp.Tests/Formats/Pbm/PbmRoundTripTests.cs @@ -11,8 +11,28 @@ using static SixLabors.ImageSharp.Tests.TestImages.Pbm; namespace SixLabors.ImageSharp.Tests.Formats.Pbm { [Trait("Format", "Pbm")] - public class RoundTripTests + public class PbmRoundTripTests { + [Theory] + [InlineData(BlackAndWhiteBinary)] + [InlineData(GrayscalePlain)] + [InlineData(GrayscaleBinary)] + public void PbmGrayscaleImageCanRoundTrip(string imagePath) + { + // Arrange + var testFile = TestFile.Create(imagePath); + using var stream = new MemoryStream(testFile.Bytes, false); + + // Act + using var originalImage = Image.Load(stream); + Image colorImage = originalImage.CloneAs(); + using Image encodedImage = this.RoundTrip(colorImage); + + // Assert + Assert.NotNull(encodedImage); + ImageComparer.Exact.VerifySimilarity(colorImage, encodedImage); + } + [Theory] [InlineData(RgbPlain)] [InlineData(RgbBinary)] @@ -37,7 +57,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Pbm using var decodedStream = new MemoryStream(); originalImage.SaveAsPbm(decodedStream); decodedStream.Seek(0, SeekOrigin.Begin); - var encodedImage = (Image)Image.Load(decodedStream); + var encodedImage = Image.Load(decodedStream); return encodedImage; } } diff --git a/tests/ImageSharp.Tests/Formats/Pbm/PbmTestUtils.cs b/tests/ImageSharp.Tests/Formats/Pbm/PbmTestUtils.cs deleted file mode 100644 index 7b701fe3d..000000000 --- a/tests/ImageSharp.Tests/Formats/Pbm/PbmTestUtils.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using System; -using System.IO; -using ImageMagick; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; -using Xunit; - -namespace SixLabors.ImageSharp.Tests.Formats.Pbm -{ - public static class PbmTestUtils - { - public static void CompareWithReferenceDecoder( - TestImageProvider provider, - Image image, - bool useExactComparer = true, - float compareTolerance = 0.01f) - where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel - { - string path = TestImageProvider.GetFilePathOrNull(provider); - if (path == null) - { - throw new InvalidOperationException("CompareToOriginal() works only with file providers!"); - } - - var testFile = TestFile.Create(path); - Image magickImage = DecodeWithMagick(Configuration.Default, new FileInfo(testFile.FullPath)); - if (useExactComparer) - { - ImageComparer.Exact.VerifySimilarity(magickImage, image); - } - else - { - ImageComparer.Tolerant(compareTolerance).VerifySimilarity(magickImage, image); - } - } - - public static Image DecodeWithMagick(Configuration configuration, FileInfo fileInfo) - where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel - { - using (var magickImage = new MagickImage(fileInfo)) - { - magickImage.AutoOrient(); - var result = new Image(configuration, magickImage.Width, magickImage.Height); - - Assert.True(result.TryGetSinglePixelSpan(out Span resultPixels)); - - using (IUnsafePixelCollection pixels = magickImage.GetPixelsUnsafe()) - { - byte[] data = pixels.ToByteArray(PixelMapping.RGBA); - - PixelOperations.Instance.FromRgba32Bytes( - configuration, - data, - resultPixels, - resultPixels.Length); - } - - return result; - } - } - } -}