镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

JpegEncoder producing incorrect output on windows-arm (was working on beta0005) #1275

Closed

Description

@peter-bozovic

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

I already found the issue #871 which seems to be resolved, but as the issue was for linux-arm this one is maybe specific to windows-arm.
On beta0005, the image was saving correctly, on rc3 it is kinda grayish with squares.

Original image:
image

Resized image:
image

Steps to Reproduce

Just loading and saving the image:

// Loading originalImage
using (var targetImage = new MemoryStream())
{
    using (var image = SixLabors.ImageSharp.Image.Load(originalImage))
    {
        image.SaveAsJpeg(targetImage);
    }
}
// Saving targetImage 

System Configuration

  • ImageSharp version: 1.0.0-rc0003
  • Other ImageSharp packages and versions: N/A
  • Environment (Operating system, version and so on): Windows 10 IoT Core 10.0.17763.1217
  • .NET Framework version: UWP - Windows 10, version 1903
  • Additional information: Application running on Raspberry PI 3 B / ARM architecture

Activity

  1. JimBobSquarePants commented on Jul 14, 2020

    @JimBobSquarePants
    Member

    @Sergio0694 @MattWhilden This um... This looks right up your street.

  2. Sergio0694 commented on Jul 14, 2020

    @Sergio0694
    Member

    @peter-bozovic Well for one it's weird that you're seeing this both in DEBUG and RELEASE modes on UWP, as those use two completely different runtimes (UWP-flavored .NET Core 2.1-like runtime in DEBUG vs. .NET Native in RELEASE). First thing, what I would suggest is to first try to isolate the issue a bit more, eg.:

    • You haven't specified this, I assume you did check to be using the latest .NETCore-UWP lib? That'd be 6.2.10 I think.
    • Can you repro this with another framework? Eg. does this happen with a .NET Core 2.1/3.1 or .NET 5 console app too?
    • Can you try this with the previous RC builds too, to see if this has been there for a while or somehow started recently?

    @JimBobSquarePants FYI Matthew is no longer in the .NET Native team (😢), pinging @tommcdon for more info 👍

  3. peter-bozovic commented on Jul 14, 2020

    @peter-bozovic
    Author

    Yes, it's weird and sorry for such specific configuration where I found it :(

    About the Relase, I'm building it without the "Compile with .NET native tool chain", so it's probably not using the .NET Native. I don't know if it's the limitation of the Windows IoT Core, or the ARM architecture, but with that option, the app doesn't build.

    I don't know where to check the .NETCore-UWP ? I'm using the "Universal Windows" app project type and all I see are Min and Target versions for the SDK. It doesn't mention anywhere .NET Core or .NET Framework.

    Yes, I have tested the .NET 4.5 console app and it works correctly. It also works on ASPNET Core 3.1 API website.

    About other versions of the library:

    • beta0006
      image

    • beta0007
      image

    • rc0001 & rc0002 - they are the same size, assuming they produce same result
      image

    • rc0003 produced few kb smaller file (in the initial post)

  4. Sergio0694 commented on Jul 14, 2020

    @Sergio0694
    Member

    About the Relase, I'm building it without the "Compile with .NET native tool chain", so it's probably not using the .NET Native. I don't know if it's the limitation of the Windows IoT Core, or the ARM architecture, but with that option, the app doesn't build.

    Mh, that kinda sounds similar to #1204, in fact I've had to drop the ARM arch in my UWP app as well as I just couldn't get it to work fine with .NET Native using the latest RC builds of ImageSharp. I wonder if these two issues are somewhat related 🤔

    As for the .NETCore-UWP package, you need to open the NuGet packages window for your UWP app and check this one:

    image

    Make sure you have the latest version installed, just to be extra sure.
    Besides, staying up to date is always great regardless of ImageSharp issues 😄

  5. peter-bozovic commented on Jul 14, 2020

    @peter-bozovic
    Author

    Ah yes, didn't see it in the list since it was filtered with "ImageSharp", daaah !
    It's 6.2.10 :)

    Sorry about the #1204, I just found for you the ARM32 architecture with Windows :D

    And guess what, when I removed ImageSharp from our main solution, it's building for relase with .NET native !
    ImageSharp was the culprit ...
    Not good for those who really wants .NET native, but good to know there's workaround with disabling this build option ...

  6. JimBobSquarePants commented on Jul 14, 2020

    @JimBobSquarePants
    Member

    ImageSharp was the culprit

    Well no... No it wasn't. A bug/limitation in the compiler is responsible for any issues, not this library.

    I'd really like to see issues like this fixed upstream. We can only build upon what the framework(s) provide us.

  7. Sergio0694 commented on Jul 14, 2020

    @Sergio0694
    Member

    Yes that's the same thing I noticed, there's something in ImageSharp that's causing issues with the .NET Native compiler. I mean, that's not all that surprising considering the huge amount of heavily generic code that ImageSharp uses, that's one of the most difficult things to handle for a fully AOT compiler, in fact we've already had similar issues in the past (though those have been resolved thankfully, see #828). Right now I can't personally complain though, at least the crash seems to be isolated on ARM32, as all other archs are building just fine in UWP (including with .NET Native) as far as I can tell.

    Your best bet at this point would probably be to either wait for Tom to chime in, or to prepare a .NET Native repro for the ARM32 build error (see the guide here) and send that to the .NET Native team for them to investigate 👍

  8. tocsoft commented on Jul 14, 2020

    @tocsoft
    Member

    @peter-bozovic can you please try saving out your test case in alternative formats, i.e. save as png/bmp too... just to verify that it is definitely the encoder and not the decoder that's at fault.

  9. peter-bozovic commented on Jul 14, 2020

    @peter-bozovic
    Author

    Saving to PNG was working fine

  10. JimBobSquarePants commented on Jul 15, 2020

    @JimBobSquarePants
    Member

    I'll be something to do with the way we translate from Rgbr32 to Rgb24. I'm curious. @peter-bozovic Does using Image<Rgb24> work with jpeg?

  11. 24 remaining items

  12. JimBobSquarePants commented on Jul 29, 2020

    @JimBobSquarePants
    Member

    @antonfirsov That and the RgbToYCbCrTables code has rewritten in my branch.

    https://github.com/SixLabors/ImageSharp/compare/js/simplify-jpeg-encoder

    I've made a point of refactoring the code to use the indexers and methods we use successfully during decoding.

    I wanted @brianpopow to check that there were no regressive issues caused by my changes.

  13. antonfirsov commented on Jul 29, 2020

    @antonfirsov
    Member

    @JimBobSquarePants the change is quite small, wouldn't be sufficient I'm afraid. For the sake of investigation I would rather suggest testing out more aggressive changes:

    1. (The changes already in place)
    2. Wire out .AsSpanUnsafe() and PixelOperations<TPixel>.Instance.ToRgb24() doing dumb, safe & slow conversion
    3. Remove all Unasafe.* trickery from LoadAndStretchEdges
    4. Even consider NoInling on the block indexer

    We can then test different permutations of 0-3 on different branches to find the root cause, and decide what goes into product code in the end.

  14. JimBobSquarePants commented on Jul 29, 2020

    @JimBobSquarePants
    Member

    @antonfirsov I'd like to get 0 tested first before attempting anything else.

    Update

    Looking at AsSpanUnsafe(). I cannot see anything that could corrupt memory there; everything looks stack only. I've updated the constraint of GenericBlock8x8<T> to use unmanaged to ensure the type parameter is though (I know everything we pass is unmanaged but convention is king) as I don't know whether the runtime helpers in the Span<T> constructor exist in earlier target frameworks. It's unfortunate MemoryMarshal.CreateSpan only exists in later targets.

    I've updated our method implementation to use that where we can in the branch.

            public Span<T> AsSpanUnsafe()
            {
    #if SUPPORTS_CREATESPAN
                Span<GenericBlock8x8<T>> s = MemoryMarshal.CreateSpan(ref this, 1);
                return MemoryMarshal.Cast<GenericBlock8x8<T>, T>(s);
    #else
                return new Span<T>(Unsafe.AsPointer(ref this), Size);
    #endif
            }
  15. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    @tocsoft How did you get the issue to replicate locally?

    I'm running via Visual Studio in Release mode x86 and cannot get my custom branch to replicate.

    I can try deploying to the PI I bought to fix this but I'd rather work locally if I can.

  16. tocsoft commented on Aug 6, 2020

    @tocsoft
    Member

    I had to deploy to the pi to replicate, you can just set the PI as a remote debug target for UWP apps and debug that way, its still should still just be an F5 debug experience

  17. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    Ok thanks!

    Should I be targeting x86? I assumed ARM64 since the issue title specifically mentions ARM and you can't build ARM32 but that didn't allow me to install.

    Also what folder did you load/save the images to? I'm attempting to use the following but I don't want to keep getting it wrong as building the app takes a lifetime.

    private async Task InitAsync()
    {
        StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
        if (string.IsNullOrWhiteSpace(picturesFolder.Path))
        {
            // Fallback for running in VS
            picturesFolder = KnownFolders.SavedPictures;
        }
    
        using (var outStream = await picturesFolder.OpenStreamForWriteAsync("1275.jpg", CreationCollisionOption.ReplaceExisting).ConfigureAwait(false))
        using (var inStream = await picturesFolder.OpenStreamForReadAsync("1275.png").ConfigureAwait(false))
        {
            using (var image = await ISImage.LoadAsync(inStream).ConfigureAwait(false))
            {
                await image.SaveAsJpegAsync(outStream).ConfigureAwait(false);
            }
        }
    }
  18. tocsoft commented on Aug 6, 2020

    @tocsoft
    Member

    To be fair I didn't save the image to disk I cheated and just rendered to as an image to the screen. This is what I used to reproduce https://github.com/tocsoft/ImageSharpUwpArmIssueRepro it has an image control on the screen and I just render/display it in the constructor

    I can't remember exactly what settings I ended up with, I just chose the device using the debug dropdown, I think I chose remote and it popped up a screen to pick the device, once I did this VS just changed the settings as required for the device. Only add thing i ended up needing to do was force image sharp to be release build and the uwp app to be debug (I couldn't get it to attach the debugger if memory served) ... also needed to reduce target frameworks down to netstandard1.3 only as it seemed to have been getting confused with the multiple frameworks being defined.

  19. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    image

    This is the result of an attempted installation with ARM with "Compile with .NET native tool chain" turned off.

    OK... I'm stumped. I need idiot proof instructions for how to get this on my device.

  20. tocsoft commented on Aug 6, 2020

    @tocsoft
    Member

    I am confused on how you are trying to run it... all I did was was hit debug from VS I never tried 'installing' it or anything like that just ran from VS targeting the PI and it just work. I might have had to run it from right clicking the project and starting it from there but nothing too unusual.

  21. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    I've been trying to do it via Visual Studio but I keep hitting the following issue.

    Failed to connect to device '127.0.0.1' using Universal Authentication. Please verify the correct remote authentication mode is specified in the project debug settings.

    So I thought I'd deploy direct to see if anything works.

  22. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    Ok... I'm up and running and can replicate. I'll see what I can do....

  23. added a commit that references this issue on Aug 6, 2020
    33aa644
  24. JimBobSquarePants commented on Aug 6, 2020

    @JimBobSquarePants
    Member

    Ok.... Looks like I've fixed it. Tested both Rgba32 and Rgb24 and everything is working.

    I'm going to open a PR using the branch I've been testing with which quite a few changes to the encoder which make it easier to debug.

    I only bought the one Raspberry PI (I'm gonna get another) so @brianpopow will need to double check my fix on Linux.

  25. brianpopow commented on Aug 7, 2020

    @brianpopow
    Collaborator

    I only bought the one Raspberry PI (I'm gonna get another) so @brianpopow will need to double check my fix on Linux.

    I have just tested it on Linux + ARM. Works fine, no problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions