Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageSharp produces a corrupted image on .NET 6 Preview 6 #55866

Closed
kerams opened this issue Jul 17, 2021 · 8 comments
Closed

ImageSharp produces a corrupted image on .NET 6 Preview 6 #55866

kerams opened this issue Jul 17, 2021 · 8 comments

Comments

@kerams
Copy link

kerams commented Jul 17, 2021

Description

Originally reported in SixLabors/ImageSharp#1704.

Loading a PNG file and immediately saving it as Jpeg works as expected on .NET 5. However when I switch to net6.0 in the csproj, only the top part of the image appears in the output jpeg file, the rest is black.

Steps to Reproduce

Create s console C# application and reference ImageSharp 1.0.3. First run this with net5.0 in the csproj, then compare the result to net6.0.

using SixLabors.ImageSharp;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            using var img = Image.Load("unknown.png");
            var fs = File.OpenWrite("unknown.jpeg");
            img.SaveAsJpeg(fs);
            fs.Flush();
            fs.Close();
        }
    }
}

Use this image
https://user-images.githubusercontent.com/5063478/126033585-4efb31ce-c231-4229-8412-68fb73950ffc.png

The result on 5.0.400-preview.21277.10 looks like the original image.

The result on 6.0.100-preview.6.21355.2 looks like this
https://user-images.githubusercontent.com/5063478/126033623-0f886133-bc0d-4449-8048-d5d29a0e377c.jpeg

Configuration

dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.100-preview.6.21355.2 Commit: 7f8e0d76c0

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19043
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.100-preview.6.21355.2\

Host (useful for support):
Version: 6.0.0-preview.7.21318.2
Commit: 1401202

.NET SDKs installed:
5.0.400-preview.21277.10 [C:\Program Files\dotnet\sdk]
6.0.100-preview.6.21355.2 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.0-preview.6.21355.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.0-preview.6.21352.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.0-preview.6.21353.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Regression?

Yes, works on 5.0.400-preview.21277.10.

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Jul 17, 2021
@stephentoub
Copy link
Member

cc: @tannergooding

@lewing
Copy link
Member

lewing commented Jul 19, 2021

We're looking into some mono image loading problems in ImageSharp that we bisected back to #53644

cc @danroth27 @vargaz

@ghost
Copy link

ghost commented Jul 19, 2021

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Originally reported in SixLabors/ImageSharp#1704.

Loading a PNG file and immediately saving it as Jpeg works as expected on .NET 5. However when I switch to net6.0 in the csproj, only the top part of the image appears in the output jpeg file, the rest is black.

Steps to Reproduce

Create s console C# application and reference ImageSharp 1.0.3. First run this with net5.0 in the csproj, then compare the result to net6.0.

using SixLabors.ImageSharp;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            using var img = Image.Load("unknown.png");
            var fs = File.OpenWrite("unknown.jpeg");
            img.SaveAsJpeg(fs);
            fs.Flush();
            fs.Close();
        }
    }
}

Use this image
https://user-images.githubusercontent.com/5063478/126033585-4efb31ce-c231-4229-8412-68fb73950ffc.png

The result on 5.0.400-preview.21277.10 looks like the original image.

The result on 6.0.100-preview.6.21355.2 looks like this
https://user-images.githubusercontent.com/5063478/126033623-0f886133-bc0d-4449-8048-d5d29a0e377c.jpeg

Configuration

dotnet --info .NET SDK (reflecting any global.json): Version: 6.0.100-preview.6.21355.2 Commit: 7f8e0d76c0

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19043
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.100-preview.6.21355.2\

Host (useful for support):
Version: 6.0.0-preview.7.21318.2
Commit: 1401202

.NET SDKs installed:
5.0.400-preview.21277.10 [C:\Program Files\dotnet\sdk]
6.0.100-preview.6.21355.2 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.0-preview.6.21355.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.0-preview.6.21352.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.0-preview.6.21353.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Regression?

Yes, works on 5.0.400-preview.21277.10.

Author: kerams
Assignees: -
Labels:

area-System.IO, untriaged

Milestone: -

@stephentoub
Copy link
Member

stephentoub commented Jul 19, 2021

These look suspect

Indeed, if I make these changes:

D:\repos\ImageSharp\src\ImageSharp [master ≡]> git diff
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index de70a9dff..779341b1c 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -506,11 +506,15 @@ private void DecodePixelData<TPixel>(DeflateStream compressedStream, ImageFrame<
             while (this.currentRow < this.header.Height)
             {
                 Span<byte> scanlineSpan = this.scanline.GetSpan();
-                int bytesRead = compressedStream.Read(scanlineSpan, this.currentRowBytesRead, this.bytesPerScanline - this.currentRowBytesRead);
-                this.currentRowBytesRead += bytesRead;
-                if (this.currentRowBytesRead < this.bytesPerScanline)
+                while (this.currentRowBytesRead < this.bytesPerScanline)
                 {
-                    return;
+                    int bytesRead = compressedStream.Read(scanlineSpan, this.currentRowBytesRead, this.bytesPerScanline - this.currentRowBytesRead);
+                    if (bytesRead <= 0)
+                    {
+                        return;
+                    }
+
+                    this.currentRowBytesRead += bytesRead;
                 }

                 this.currentRowBytesRead = 0;
@@ -577,11 +581,15 @@ private void DecodeInterlacedPixelData<TPixel>(DeflateStream compressedStream, I

                 while (this.currentRow < this.header.Height)
                 {
-                    int bytesRead = compressedStream.Read(this.scanline.GetSpan(), this.currentRowBytesRead, bytesPerInterlaceScanline - this.currentRowBytesRead);
-                    this.currentRowBytesRead += bytesRead;
-                    if (this.currentRowBytesRead < bytesPerInterlaceScanline)
+                    while (this.currentRowBytesRead < bytesPerInterlaceScanline)
                     {
-                        return;
+                        int bytesRead = compressedStream.Read(this.scanline.GetSpan(), this.currentRowBytesRead, bytesPerInterlaceScanline - this.currentRowBytesRead);
+                        if (bytesRead <= 0)
+                        {
+                            return;
+                        }
+
+                        this.currentRowBytesRead += bytesRead;
                     }

                     this.currentRowBytesRead = 0;

Before this change, I could repro with the example in this issue. After this change, it appears to work correctly.

@adamsitnik adamsitnik removed the untriaged New issue has not been triaged by the area owner label Jul 19, 2021
@adamsitnik
Copy link
Member

Since this was caused by a breaking change that we have introduced on purpose (dotnet/docs#24649) and fixed by @stephentoub in SixLabors/ImageSharp#1707, I am closing the issue.

@JimBobSquarePants
Copy link

Thanks for the swift diagnosis and fix!

@ghost ghost locked as resolved and limited conversation to collaborators Aug 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants