-
-
Notifications
You must be signed in to change notification settings - Fork 855
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
JpegEncoder producing incorrect output on windows-arm (was working on beta0005) #1275
Comments
@Sergio0694 @MattWhilden This um... This looks right up your street. |
@peter-bozovic Well for one it's weird that you're seeing this both in
@JimBobSquarePants FYI Matthew is no longer in the .NET Native team (😢), pinging @tommcdon for more info 👍 |
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: |
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: Make sure you have the latest version installed, just to be extra sure. |
Ah yes, didn't see it in the list since it was filtered with "ImageSharp", daaah ! 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 ! |
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. |
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 👍 |
@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. |
Saving to PNG was working fine |
I'll be something to do with the way we translate from |
If you ment trying |
Thanks, that cuts down some of the options. |
Ok been trying to/managed reproduce this one. First some goodish news (may actually be bad news) if I take a dependency on the source directly it doesn't corrupt and seems to work fine. However it does break when using the nuget dependency. I wonder if it chooses different targets for package reference vs project reference. |
Oh wow @tocsoft that's progress! So what is the underlying target framework being used by UWP in the failing instance? |
it seems to be using the netstandard1.3 build |
Wait a second, that's weird - UWP should be using the .NET Standard 2.0 target, no? 🤔 |
@Sergio0694 I have no idea so any guidance on how we can get it to fail locally against the source would be great. |
I'm 100% positive that UWP on SDK >= 16299 should pick the .NET Standard 2.0 target. |
will check once I stop debugging .. though I'm note sure it actually matters too much in this case because the code part of the code where we we seems to be having issues will be identical for both targets. |
oh I can get it to fail locally against source now btw... just needs ImageSharp to be in release mode |
ok we end up with a difference in the encoding after the 2nd execution of ImageSharp/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs Lines 1003 to 1024 in ef5e21b
ie x=0, y = 0 and i = 0 then identical results locally, i=1 then results start to differ |
@tocsoft can you check if there any tests failing? |
not really no way to get the tests over to the external device... well not without a significant amount of rebuilding/refactoring |
from this point forward there too much pointer magic going on for me to follow/track down the exact point values start to change at the moment. Doesn't help that its only a release build issue makes it a nightmare half the local just seem to get optimised away half the time so you can't even easily inspect half for the stuff I'm trying to debug, that's before you start adding in all the pointer mess. |
That pointer code is likely a relic of the first color converter I put together years ago. I’m confident we have language features available now that we can use to to avoid using them. Looking at the code we do a lot of pointer arithmetic where we don't need to now for |
@tocsoft I don't know if this will help but I made a branch with about 90% of the pointer stuff removed. https://github.com/SixLabors/ImageSharp/tree/js/simplify-jpeg-encoder |
@JimBobSquarePants worth a try, but I'm afraid it's more likely that the issue is other way around: GC-references are more prone to runtime bugs, than basic pointers. I suspect this code, since we already had similar issues with ImageSharp/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs Lines 60 to 80 in 493e422
Other candidate for runtime bugs: Yet another thing to consider to check is if the issue reproduces on Linux-ARM, since it's easier to investigate (and maybe CI-test in the future) than UWP. |
Another idea: do a diff between beta5 and todays state and look for changes in code being invoked from |
@antonfirsov Yeah possibly.... The changes in the branch should make it a lot easier to debug though. Last time we "fixed" on Linux ARM the issue was here. My money is the inlining in combination with Unsafe code in the caller. I would try removing it and testing on both ARM platforms if possible. Looking at that sample above we don't even need the |
@peter-bozovic @tocsoft Can you do me a favor and please run your application with a build from this branch? https://github.com/SixLabors/ImageSharp/tree/js/simplify-jpeg-encoder I've done a fair amount of rewriting to reuse paths we know work on the decoder. It removes a LOT of the Fingers crossed it works... It's much easier to debug anyway. @brianpopow Can you test it on your Linux environment also? I want to make sure I've not introduced issues. |
@JimBobSquarePants works on linux + ARM. I just did load the |
Thanks @brianpopow that's reassuring. I really hope it clears up the Windows issues now. Indexing and assignment during colorspace transform is a lot more conventional now. |
@brianpopow does the issue actually reproduce on Linux? I thought that platform is not affected. @JimBobSquarePants I still put my bet on the code in |
@antonfirsov sorry maybe i was unclear: I was able to load and save the image without any issue on linux + ARM. edit: to be more specific, it works with the current |
@antonfirsov That and the 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. |
@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:
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. |
@antonfirsov I'd like to get 0 tested first before attempting anything else. UpdateLooking at 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
} |
@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. |
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 |
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);
}
}
} |
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. |
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. |
I've been trying to do it via Visual Studio but I keep hitting the following issue.
So I thought I'd deploy direct to see if anything works. |
Ok... I'm up and running and can replicate. I'll see what I can do.... |
Ok.... Looks like I've fixed it. Tested both 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. |
I have just tested it on Linux + ARM. Works fine, no problems. |
Prerequisites
DEBUG
andRELEASE
modeDescription
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:
Resized image:
Steps to Reproduce
Just loading and saving the image:
System Configuration
The text was updated successfully, but these errors were encountered: