emcconville / wand

The ctypes-based simple ImageMagick binding for Python
http://docs.wand-py.org/
Other
1.42k stars 199 forks source link

Access violation after importing colour (from colour-science) #661

Open roelandschoukens opened 2 months ago

roelandschoukens commented 2 months ago

test:

import numpy as np
from wand.resource import genesis as wand_genesis
from wand.image import Image

# as a workaround, call wand_genesis() before importing other packages
# this also runs successfully if we don't import colour at all.
#wand_genesis() 

import colour  # from https://github.com/colour-science/colour

with Image.from_array(np.linspace(0, 1, 256*256).reshape([256, 256])) as img:
    img.save(filename=f'test.exr')
    print("saved")

This will raise an exception from the save() call.

    r = library.MagickWriteImage(self.wand, filename)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: exception: access violation reading 0x0000000000000000

This problem started happening after I upgraded ImageMagick:

$ magick -version
Version: ImageMagick 7.1.1-38 Q16-HDRI x64 b0ab922:20240901 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Channel-masks(64-bit) Cipher DPC HDRI Modules OpenCL OpenMP(2.0)
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (194134120)

and

$ py -m wand.version --verbose
Wand 0.6.13
ImageMagick 7.1.1-38 Q16-HDRI x64 b0ab922:20240901 https://imagemagick.org
emcconville commented 2 months ago

Thanks for reporting this. Sadly, I'm unable to reproduce this. Would you be able to share more info on the system experiencing this OSError?

roelandschoukens commented 2 months ago

OK that colour package imports rather more other stuff than I expected, it can be narrowed down to PySide6. (this is the official Python Qt binding.)

import numpy as np
from wand.image import Image
import PySide6

with Image.from_array(np.linspace(0, 1, 256*256).reshape([256, 256])) as img:
    img.save(filename=f'test.exr')
    print("saved")

I tried to reproduce it with a build of ImageMagick I built locally but with that build it actually works correctly. And unfortunately the Windows binaries from ImageMagick themselves are built without debug symbols.

It is crashing when CORE_RL_exr_.dll tries to call the standard library, and it is getting a msvcp140.dll that is perhaps slightly incompatible with the one shipped with ImageMagick.

>   msvcp140.dll!00007ffb29933080() Unknown Non-user code. Symbol loading disabled by Include/Exclude setting.
    CORE_RL_exr_.dll!00007ffb00ef8d6a() Unknown Non-user code. Binary was not built with debug information.
    CORE_RL_exr_.dll!00007ffb00ef5a3a() Unknown Non-user code. Binary was not built with debug information.

(it is getting . . . \site-packages\shiboken6\msvcp140.dll instead of the one in the ImageMagick directory. This possibly explains why sometimes you can fix the issue by calling wand_genesis first)

roelandschoukens commented 2 months ago

The last module I can narrow it down to is shiboken6, which is kind of, sort of part of Qt.

I think this is some generic possible problem if a lot of modules are importing DLLs. Shiboken has a slightly older version of msvcp140.dll than ImageMagick, perhaps the latter uses a function that was added in the meantime.