#!/bin/sh
# Upstream targets the browser, so exercise the module the way pdf.js loads it:
# instantiate the shipped WebAssembly from disk and decode a JBIG2 page.
set -eu

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

cat > "$work/check.mjs" <<'JS'
import fs from "node:fs"

const dir = "/usr/share/javascript/pdfjs-jbig2"
const bytes = fs.readFileSync(dir + "/jbig2.wasm")

// The module is built with -msimd128.  Where the JavaScript engine has no Wasm
// SIMD (the riscv64 port, for one) upstream's fallback build is what gets used.
let JBig2
let options = {}
try {
  new WebAssembly.Module(bytes)
  JBig2 = (await import(dir + "/jbig2.js")).default
  // The glue is built with -s ENVIRONMENT=web and would fetch the payload;
  // hand it the bytes instead.
  options = {
    instantiateWasm(imports, success) {
      const instance = new WebAssembly.Instance(
        new WebAssembly.Module(bytes), imports)
      success(instance)
      return instance.exports
    }
  }
} catch (e) {
  console.log(`cannot compile the WebAssembly (${e.message}); testing the fallback build`)
  JBig2 = (await import(dir + "/jbig2_nowasm_fallback.js")).default
}

const mod = await JBig2(options)

// A 16x16 blank page: page information, one MMR-coded generic region, end of
// page and end of file.
const jb2 = Buffer.from("AAAAADAAAQAAABMAAAAQAAAAEAAAAAAAAAAAAAAAAAAAASYAAQAAABcAAAAQAAAAEAAAAAAAAAAAAAH//wAQAQAAAAIxAAEAAAAA/////zMAAAAAAAA=", "base64")
const ptr = mod._malloc(jb2.length)
mod.writeArrayToMemory(jb2, ptr)
mod._jbig2_decode(ptr, jb2.length, 16, 16, 0, 0)
mod._free(ptr)

const img = mod.imageData
if (!img)
  throw new Error("jbig2_decode produced no image")
if (img.length !== 16 * 2)
  throw new Error(`unexpected image size ${img.length}`)
if (!img.every(b => b === 0xff))
  throw new Error("decoded page is not blank")
console.log("decoded 16x16 JBIG2 page")
JS

node "$work/check.mjs"
