dlemstra / magick-wasm

The WASM library for ImageMagick
Apache License 2.0
571 stars 38 forks source link

Wrapping `ImageMagick.read` in a `Promise` causes it to fail silently? So strange. #148

Closed lancejpollard closed 9 months ago

lancejpollard commented 9 months ago

magick-wasm version

0.0.28

Description

I got this package to work temporarily by manually copying the build files to the public directory, and going from there FYI.

But now I'm stumped.

This one works fine, with the callback:

export async function readWithImageMagickCallback(
  file: Uint8Array,
  callback: (err: Error | null, image?: IMagickImage) => void,
) {
  try {
    ImageMagick.read(file, image => {
      callback(null, image)
    })
  } catch (e) {
    callback(e as Error)
  }
}

This one returns an image but fails silently:

export async function readWithImageMagickPromise(
  file: Uint8Array,
): Promise<IMagickImage> {
  return new Promise((res, rej) => {
    try {
      ImageMagick.read(file, image => {
        res(image)
      })
    } catch (e) {
      rej(e)
    }
  })
}

I am basically trying to do this in my code:

const arrayBuffer = await file.arrayBuffer()
const image = await readWithImageMagick(
  new Uint8Array(arrayBuffer),
)
const out = await writeWithImageMagick(image, imageMagickFormat)

But the out is an emby ArrayBuffer in the end, **only if I call it through this Promise technique. If I call i t through the callback version of the function, IT WORKS!

I can only imagine why that might occur. All I can imagine is that because I've wrapped the call in a Promise, the imagemagick-wasm code is CHECKING for wrapping in a promise and acts differently based on that. Somehow, some super meta programming? I don't understand why it wouldn't work if I wrap it in a promise? Maybe a polyfill bug or something strange... Any ideas?

Steps to Reproduce

Try calling the read function when it's wrapped in a promise with async/await like I have it above.

Images

Here is a picture of my logs on the out variable when passed through the Promise.

Screenshot 2024-02-02 at 9 50 28 AM
lancejpollard commented 9 months ago

I've also noticed that it is failing randomly on some PNG images converted to JPG, but that is a different issue.

dlemstra commented 9 months ago

You cannot use the image outside the scope of the read method.

lancejpollard commented 9 months ago

@dlemstra mind elaborating on that further, I have never seen such a situation before :)

dlemstra commented 9 months ago

Sorry for not adding more context. The reason this is not possible is because of the native code behind this project. The memory that is used for the image is freed after the method has been executed.

lancejpollard commented 9 months ago

Are there other things like that to be aware of in the codebase?

dlemstra commented 9 months ago

When you are getting the value inside a delegate and not as a return value you should not use it ouside that delegate.