dlemstra / magick-wasm

The WASM library for ImageMagick
Apache License 2.0
533 stars 34 forks source link

iPhone HEIC images fail to load #22

Closed jankais3r closed 1 year ago

jankais3r commented 3 years ago

Hi Dirk,

Many thanks for providing the browser-based documentation. Thanks to it, I was finally able to start working on my project. The initial version of the documentation did not contain an example for working with user-provided images, so I added that functionality myself. Unfortunately, the page errors out when I try to load a HEIC photo I took with an iPhone.

Error log

That was maybe a month ago. When I went to check the documentation again this morning, I saw that you added the image upload functionality to the repo in the meantime, however it also fails to load iPhone HEIC photos (although it does not throw any error in the console like my code does, the image doesn't get rendered).

Error

Is this a known limitation of magick-wasm? I was hoping that it would be able to work with HEIC photos thanks to libheif. I can load example.heic image from libheif without any issue, but other heic photos just won't render with magick-wasm, even though they render fine on libheif's online demo page.

dlemstra commented 3 years ago

Can you attach your test image here? You will probably nee to zip it.

jankais3r commented 3 years ago

Here's one. But happens with all iPhone photos I tested so far.

IMG_0324.zip

dlemstra commented 3 years ago

I suspect something is happening inside the libheif library that is causing this error. I have no idea what is happening though. All I get as an exception is a 'number' and that is what you are seeing in the image above. I don't get that much detail as you get in a stack trace. I tried to see if updating emscripten would fix this but it also does not seem to fix this. Will need to figure out how I can debug this in more detail.

jankais3r commented 2 years ago

In case it helps anyone, here is my experimental code that produces more detailed error log.

magick-wasm-docs\src\views\classes\MagickExperiment.vue:

<template>
    <h1>MagickExperiment</h1>
    <canvas id="cvs"></canvas>
</template>

<script lang="ts">
import { Options, Vue } from 'vue-class-component'
import { ImageMagick } from '@imagemagick/magick-wasm/image-magick'

function load(b64: string) {
    var binary_string = window.atob(b64);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    ImageMagick.read(bytes, (image) => image.writeToCanvas(document.getElementById("cvs") as HTMLCanvasElement))
}

function waitFor(variable: any, callback: any) {
  var interval = setInterval(function() {
    if (typeof variable !== "undefined") {
      clearInterval(interval);
      callback();
    }
  }, 200);
}

const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.addEventListener('change', (e: Event) => {
    let file = (e.target! as HTMLInputElement)!.files![0];
    console.log(file.name);
    var fr = new FileReader();
    fr.readAsDataURL(file);
    waitFor(fr.result, function() {
        var b64 = (fr.result as string).substring((fr.result as string).indexOf( ',' ) + 1 );
        load(b64);
    });
});
document.body.appendChild(fileInput);

const blurBtn = document.createElement('input');
blurBtn.type = 'button';
blurBtn.value = 'Blur';
blurBtn.addEventListener('click', (e: Event) => {
    const canvas = document.getElementById("cvs") as HTMLCanvasElement;
    ImageMagick.readFromCanvas(canvas, (image) =>
    {
        image.blur()
        image.writeToCanvas(canvas)
        console.log('Blur applied.');
    })
});
document.body.appendChild(blurBtn);

@Options({
    methods: {
    }
})
export default class MagickImageView extends Vue {}
</script>
zhouyupeng commented 1 year ago

when I try to load a HEIC photo ,i have the same problem 5555555

dlemstra commented 1 year ago

It looks like the error message has improved. The next step will be trying to figure out where this abort is being raised. I could use some help with that.

dlemstra commented 1 year ago

Managed to get a bit more info by creating a debug build. And I am getting the following output:

$std::__2::__throw_system_error(int, char const*)   @   1d69f4e6:0x2a87cad
$std::__2::thread::thread<void (std::__2::__async_assoc_state<heif::Error, std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>>::*)(), std::__2::__async_assoc_state<heif::Error, std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>>*, void>(void (std::__2::__async_assoc_state<heif::Error, std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>>::*&&)(), std::__2::__async_assoc_state<heif::Error, std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>>*&&)   @   1d69f4e6:0x1f42402
$std::__2::future<heif::Error> std::__2::__make_async_assoc_state<heif::Error, std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>>(std::__2::__async_func<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int>&&)    @   1d69f4e6:0x1f2418e
$std::__2::future<std::__2::__invoke_of<std::__2::decay<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const>::type, std::__2::decay<heif::HeifContext const*>::type, std::__2::decay<unsigned int&>::type, std::__2::decay<std::__2::shared_ptr<heif::HeifPixelImage>&>::type, std::__2::decay<int&>::type, std::__2::decay<int&>::type>::type> std::__2::async<heif::Error (heif::HeifContext::*)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*, unsigned int&, std::__2::shared_ptr<heif::HeifPixelImage>&, int&, int&>(std::__2::launch, heif::Error (heif::HeifContext::*&&)(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>, int, int) const, heif::HeifContext const*&&, unsigned int&, std::__2::shared_ptr<heif::HeifPixelImage>&, int&, int&)  @   1d69f4e6:0x1f215dd
$heif::HeifContext::decode_full_grid_image(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>&, std::__2::vector<unsigned char, std::__2::allocator<unsigned char>> const&) const @   1d69f4e6:0x1f1d6a3
$heif::HeifContext::decode_image_planar(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>&, heif_colorspace, heif_decoding_options const*) const @   1d69f4e6:0x1f198de
$heif::HeifContext::decode_image_user(unsigned int, std::__2::shared_ptr<heif::HeifPixelImage>&, heif_colorspace, heif_chroma, heif_decoding_options const*) const  @   1d69f4e6:0x1f17a9c
$heif_decode_image  @   1d69f4e6:0x1ed0ea9
$ReadHEICImageHandle    @   1d69f4e6:0x775406
$ReadHEICImage  @   1d69f4e6:0x772ddb
$ReadImage  @   1d69f4e6:0xf70b9
$BlobToImage    @   1d69f4e6:0x777af
$MagickImage_ReadBlob
dlemstra commented 1 year ago

I already suspected this when I created this message but it turns out the for the heif library multi threading was enabled but this is not supported. I will need to make a change for this in the Magick.Native library but I was already able to seen the snowy picture that was posted by @jankais3r. This issue will be resolved in the next release.

kiastorm commented 1 year ago

Any update on this? I'm still getting the following:

image-converter.astro:54 RuntimeError: Aborted(). Build with -sASSERTIONS for more info.
    at fe (index.mjs:108:17)
    at ts (index.mjs:2992:9)
    at magick.wasm:0x6a16a
    at magick.wasm:0x1bf202
    at magick.wasm:0x3c99e2
    at magick.wasm:0x31c966
    at magick.wasm:0x91aabd
    at magick.wasm:0x693df
    at magick.wasm:0xaaa24
    at magick.wasm:0x897c43
dlemstra commented 1 year ago

This issue was resolved? Please open up something new with more information if you are running into something similar.