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

Won't save on macOS and Linux #3

Closed
bleroy opened this Issue Feb 9, 2017 · 7 comments

Comments

Projects
None yet
4 participants
@bleroy

bleroy commented Feb 9, 2017

If you run the benchmarks under https://github.com/bleroy/core-imaging-playground/blob/master/NetCore/LoadResizeSave.cs, you'll see that it works on Windows, but crashes when it attempts to save the images on Linux and macOS.

@bleroy

This comment has been minimized.

Show comment
Hide comment
@bleroy

bleroy Feb 10, 2017

Here's the stack trace:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> FreeImageAPI.FreeImageException: Unable to save bitmap
   at FreeImageAPI.FreeImageBitmap.Save(String filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags)
   at ImageProcessing.LoadResizeSave.FreeImageResize(String path, Int32 size, String outputDirectory) in /home/bertrand/Projects/core-imaging-playground/NetCore/LoadResizeSave.cs:line 161
   at ImageProcessing.LoadResizeSave.FreeImageResizeBenchmark() in /home/bertrand/Projects/core-imaging-playground/NetCore/LoadResizeSave.cs:line 140
   at BenchmarkDotNet.Autogenerated.Runnable.MainMultiAction(Int64 invokeCount) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 415
   at BenchmarkDotNet.Engines.Engine.Jitting()
   at BenchmarkDotNet.Autogenerated.Runnable.Run(IHostApi hostApi) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 96
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at BenchmarkDotNet.Autogenerated.Program.Main(String[] args) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 45

bleroy commented Feb 10, 2017

Here's the stack trace:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> FreeImageAPI.FreeImageException: Unable to save bitmap
   at FreeImageAPI.FreeImageBitmap.Save(String filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags)
   at ImageProcessing.LoadResizeSave.FreeImageResize(String path, Int32 size, String outputDirectory) in /home/bertrand/Projects/core-imaging-playground/NetCore/LoadResizeSave.cs:line 161
   at ImageProcessing.LoadResizeSave.FreeImageResizeBenchmark() in /home/bertrand/Projects/core-imaging-playground/NetCore/LoadResizeSave.cs:line 140
   at BenchmarkDotNet.Autogenerated.Runnable.MainMultiAction(Int64 invokeCount) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 415
   at BenchmarkDotNet.Engines.Engine.Jitting()
   at BenchmarkDotNet.Autogenerated.Runnable.Run(IHostApi hostApi) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 96
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at BenchmarkDotNet.Autogenerated.Program.Main(String[] args) in /home/bertrand/Projects/core-imaging-playground/BDN.Generated/BDN.Generated.notcs:line 45
@matgr1

This comment has been minimized.

Show comment
Hide comment
@matgr1

matgr1 Mar 27, 2017

Owner

sorry it took so long to get to this, but I finally got around to setting up a Linux VM to investigate...

It looks like the problem is in the native freeimage library somewhere - it's returning "false" from SaveEx, but unfortunately the native error handling isn't the best so there isn't a great way to get the reason (there is the FreeImageEngine.Message event, but that doesn't seem to be firing in this case).

I'll try digging a little deeper with a c++ test program...

Owner

matgr1 commented Mar 27, 2017

sorry it took so long to get to this, but I finally got around to setting up a Linux VM to investigate...

It looks like the problem is in the native freeimage library somewhere - it's returning "false" from SaveEx, but unfortunately the native error handling isn't the best so there isn't a great way to get the reason (there is the FreeImageEngine.Message event, but that doesn't seem to be firing in this case).

I'll try digging a little deeper with a c++ test program...

@nigelsrichards

This comment has been minimized.

Show comment
Hide comment
@nigelsrichards

nigelsrichards Apr 10, 2017

Hello,
I have come across the same problem. Would you like me to help ?

nigelsrichards commented Apr 10, 2017

Hello,
I have come across the same problem. Would you like me to help ?

@matgr1

This comment has been minimized.

Show comment
Hide comment
@matgr1

matgr1 Apr 11, 2017

Owner

@nigelsrichards sure that would be great! I'm having trouble finding some time to look at this myself

Owner

matgr1 commented Apr 11, 2017

@nigelsrichards sure that would be great! I'm having trouble finding some time to look at this myself

@matgr1

This comment has been minimized.

Show comment
Hide comment
@matgr1

matgr1 May 12, 2017

Owner

There is a workaround (for Linux at least, haven't tried macOS yet) - don't use the Save function that takes a path, use the stream one instead, eg:

using (FileStream stream = File.OpenWrite(OutputPath(path, outputDirectory, FreeImage)))
{
    resized.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG,
        FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD |
        FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE);
}
Owner

matgr1 commented May 12, 2017

There is a workaround (for Linux at least, haven't tried macOS yet) - don't use the Save function that takes a path, use the stream one instead, eg:

using (FileStream stream = File.OpenWrite(OutputPath(path, outputDirectory, FreeImage)))
{
    resized.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG,
        FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD |
        FREE_IMAGE_SAVE_FLAGS.JPEG_BASELINE);
}
@CShepartd

This comment has been minimized.

Show comment
Hide comment
@CShepartd

CShepartd Aug 9, 2017

Save and Load dont working with path wothout using stream on linux (and mac) cuz path overload using FreeImage_LoadU and FreeImage_SaveU In docs we can read Note that this function only works on MS Windows operating systems. On other systems, the function does nothing and returns FALSE.

So using stream is only other way to do the same but we can fix problem. To repair we need to PInvoke and wrap FreeImage_Load and FreeImage_Save

CShepartd commented Aug 9, 2017

Save and Load dont working with path wothout using stream on linux (and mac) cuz path overload using FreeImage_LoadU and FreeImage_SaveU In docs we can read Note that this function only works on MS Windows operating systems. On other systems, the function does nothing and returns FALSE.

So using stream is only other way to do the same but we can fix problem. To repair we need to PInvoke and wrap FreeImage_Load and FreeImage_Save

@matgr1

This comment has been minimized.

Show comment
Hide comment
@matgr1

matgr1 Aug 14, 2017

Owner

Thanks for finding that! I've changed it so that the unicode functions are only used in when RuntimeInformation.IsOSPlatform(OSPlatform.Windows) returns true (for netstandard).

I'm not sure if there's a good way to identify the platform when targeting full .net, so for now I just assume Windows in that case. This may be a problem running on Mono on a non-Windows platform. Any suggestions?

Owner

matgr1 commented Aug 14, 2017

Thanks for finding that! I've changed it so that the unicode functions are only used in when RuntimeInformation.IsOSPlatform(OSPlatform.Windows) returns true (for netstandard).

I'm not sure if there's a good way to identify the platform when targeting full .net, so for now I just assume Windows in that case. This may be a problem running on Mono on a non-Windows platform. Any suggestions?

@matgr1 matgr1 closed this Aug 14, 2017

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