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

LosslessCompress routine is making some PNGs grayscale #278

Closed
2 of 3 tasks
dabutvin opened this issue Aug 12, 2018 · 13 comments
Closed
2 of 3 tasks

LosslessCompress routine is making some PNGs grayscale #278

dabutvin opened this issue Aug 12, 2018 · 13 comments
Labels

Comments

@dabutvin
Copy link
Sponsor

dabutvin commented Aug 12, 2018

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am using the latest version of Magick.NET
  • I have searched open and closed issues to ensure it has not already been reported

I just saw there is a new version of Magick.NET. I am going to update to the latest version of Magick.NET-Q16-AnyCPU now and see if we get another repro

Description

The LosslessCompress is intermittently destroying a set of PNGs

image

I took a look at the before and after for a specific image and noticed the alpha channel is lost and the color goes from RGB to grayscale after optimization. Here's a screen grab of before and after comparison

image

I ran the same compression code in a loop on my laptop hundreds of times and was unable to reproduce the error. Is there anything you can think of that may be causing this? I am at a loss.

Here are the known repros of the issue:

nextcloud/nextcloud.com#932
nextcloud/nextcloud.com#920
https://github.com/dependabot/dependabot.github.io/pull/102
spences10/blog.scottspence.me#614

interestingly for the dependabot case

/images/blog/auto-merge-2.png went from 97.98kb -> 81.75kb in https://github.com/dependabot/dependabot.github.io/pull/101 and then from 81.75kb -> 10.03kb in https://github.com/dependabot/dependabot.github.io/pull/102

This one had no alpha before or after, but the color space went from RGB and LCD to Gray

image

Steps to Reproduce

Run ImgBot's call to LosslessCompress() see https://github.com/dabutvin/ImgBot/blob/master/CompressImagesFunction/CompressImages.cs#L120-L154

System Configuration

  • Magick.NET version: 7.5.0.1
  • Environment (Operating system, version and so on):
"os_name": "Windows Server 2016",
"os_build_lab_ex": "14393.2312.amd64fre.rs1_release(bryant).180609-2043",
"cores": 2
  • Additional information:
    This is an Azure functions environment running in consumption mode
@dabutvin
Copy link
Sponsor Author

just added another case from today to the list above (spences10/blog.scottspence.me#614)

here is an example of before and after info

image

image

@dlemstra
Copy link
Owner

Have you been able to reproduce this yet? It looks like some kind of color reduction is happening but I haven't been able to figure out yet where this happens. I have upgraded libpng and that might resolve the issue but I wish we could reproduce this so I can confirm that. It is also possible that we have some kind of bug in the PNG encoder but I could not figure out which part would cause the color reduction.

@dlemstra dlemstra added the bug label Aug 12, 2018
@dabutvin
Copy link
Sponsor Author

I haven't been able to reproduce it yet. I have an idea I want to try out when I get back home later today. Uploading a console app into the same exact environment and executing it within there using one of the affected images.

@dabutvin
Copy link
Sponsor Author

We've got another case today https://github.com/NeerajDana/todomvc/pull/1

@dabutvin
Copy link
Sponsor Author

I ran the simulation last night in the same Azure environment where the original problem occurred.
I ran this image through the losslessCompress routine in hundreds of loops and had no problem with any of the output :(

I'm pretty stumped here. Maybe I should add the git clone to the test instead of uploading the file manually? Could it be possible that the image is being corrupted during the clone and not during the optimization? Seems unlikely, but I am running out of ideas.

@dlemstra
Copy link
Owner

I was also thinking that it is possible that this is caused by the clone but that would not explain why we get a perfect PNG file. I suspect there is a race condition somewhere inside ImageMagick (maybe even libpng) where uninitialized memory or a shared variable sometimes causes a change in the code path and the colors of the image get reduced but I could not track this down. Maybe we can reproduce it faster if we run the code in parallel?

@dabutvin
Copy link
Sponsor Author

okay I've got this running right now in the Azure environment

    class Program
    {
        static void Main(string[] args)
        {
            var original = args[0];
            Console.WriteLine(original);
            var ext = Path.GetExtension(original);
            var optimizer = new ImageOptimizer { OptimalCompression = true };

            // make 1000 copies of original
            for (var i = 0; i < 1000;i++) 
            {
                File.Copy(original, original + i + ext);
            }

            Console.WriteLine("copied");

            // compress the copies in parallel
            Parallel.ForEach(Enumerable.Range(0, 999), i =>
            {
                var fileInfo = new FileInfo(original + i + ext);
                optimizer.LosslessCompress(fileInfo);
            });

            Console.WriteLine("done");
        }
    }

image
image

We'll see if it can hit a repro

@dlemstra
Copy link
Owner

dlemstra commented Aug 14, 2018

I wonder what happens when you try this with all the images from one of the repos that fails and optimize them in parallel. And do that in a loop until we optimize one of those images too much. And when we have a reproducible situation we can enable debug logging to get more information.

@dabutvin
Copy link
Sponsor Author

Okay I've got this running right now against https://github.com/dependabot/dependabot.github.io/pull/102. This is what the code looks like:

class Program
{
    static void Main(string[] args)
    {
        var optimizer = new ImageOptimizer { OptimalCompression = true };
        var shouldContinue = true;

        while (shouldContinue)
        {
            var files = Directory.GetFiles(args[0], "*.png", new EnumerationOptions { RecurseSubdirectories = true });
            Console.WriteLine("found " + files.Length + " files!");
            Parallel.ForEach(files, file =>
            {
                var fileInfo = new FileInfo(file);
                if(optimizer.LosslessCompress(fileInfo))
                {
                    Console.WriteLine("COMPRESSED: " + file);
                    shouldContinue = false;
                }
            });

            Console.WriteLine("done");
        }
    }
}

image

@dabutvin
Copy link
Sponsor Author

This has not been successful in reproducing the issue. I tried with finding all the image files, not just pngs and still no luck.

However, I forked the repo and queued ImgBot to run in batches of 10 and that seemed to repro with different results each time. https://github.com/dabutvin/dependabot.github.io/pulls?q=is%3Apr+is%3Aclosed

I can probably setup an environment to get debug info this way and force a repro what do you think?

@dlemstra
Copy link
Owner

dlemstra commented Aug 18, 2018

Is it also possible to reproduce the issue with that repo and running the optimizer against it locally? Does it matter if you run the code synchronous or asynchronous? The debug logging could be kind of a mess because its a global log and we don't have some kind of context. You can find some info on how to enable that here: https://github.com/dlemstra/Magick.NET/blob/master/Documentation/DetailedDebugInformation.md.

I might have some time available later today (GMT+1) to work on this together with you if that would help. You can contact me through email for the how and when.

@dlemstra
Copy link
Owner

Thanks for helping me fix this issue @dabutvin. Could not have done it without your help 👍 Just pushed a new release that solves this issue.

@dabutvin
Copy link
Sponsor Author

👍 👍 👍 Awesome! Great news

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants