8dc409777e
A page with no React, no store and no router around it: hand /src/engine/skiaShim.ts a file, develop it, and read the plane back. It is the shortest path to the answer when the stage looks wrong and the question is whether the engine or the app around it is at fault.
73 lines
2.9 KiB
HTML
73 lines
2.9 KiB
HTML
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>probe: develop a real RAW</title>
|
|
<body>
|
|
<pre id="out" style="font:12px monospace">running…</pre>
|
|
<img id="shot" style="max-width:100%">
|
|
<script type="module">
|
|
const log = (...a) => {
|
|
const s = a.map((x) => (typeof x === 'string' ? x : JSON.stringify(x))).join(' ');
|
|
document.getElementById('out').textContent += s + '\n';
|
|
console.log(s);
|
|
};
|
|
const b64 = (bytes) => {
|
|
let s = '';
|
|
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
s += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000));
|
|
}
|
|
return btoa(s);
|
|
};
|
|
|
|
try {
|
|
const RAW_URL = new URLSearchParams(location.search).get('f') || 'http://127.0.0.1:5300/DSC03453.ARW';
|
|
const { initSkia } = await import('/src/engine/skiaShim.ts');
|
|
await initSkia({ locateFile: (file) => `/wasm/${file}` });
|
|
log('canvaskit up');
|
|
const { developRaw } = await import('/src/engine/rawDevelop.ts');
|
|
|
|
const bytes = new Uint8Array(await (await fetch(RAW_URL)).arrayBuffer());
|
|
log('raw bytes', bytes.length, RAW_URL);
|
|
// The develop hands its buffer to LibRaw's worker, which detaches it — one
|
|
// copy each, since the plane below is read out of a second decode.
|
|
const forPlane = bytes.slice();
|
|
|
|
const t0 = performance.now();
|
|
const jpeg = await developRaw(bytes);
|
|
log('develop ms', Math.round(performance.now() - t0), 'jpeg bytes', jpeg.length);
|
|
window.__dev = b64(jpeg);
|
|
document.getElementById('shot').src = URL.createObjectURL(new Blob([jpeg], { type: 'image/jpeg' }));
|
|
|
|
// The plane and the colour data behind that develop, so the shader can be
|
|
// replayed offline a stage at a time.
|
|
const { default: LibRaw } = await import('libraw-wasm');
|
|
const raw = new LibRaw();
|
|
// LibRaw hands the buffer to its worker, which detaches it — a copy, since
|
|
// the develop above already passed the original through.
|
|
await raw.open(forPlane, {
|
|
halfSize: true, outputBps: 16, outputColor: 0, noAutoScale: true,
|
|
useCameraWb: false, noAutoBright: true, gamm: [1, 1], userQual: 3, highlight: 0,
|
|
});
|
|
const meta = await raw.metadata(true);
|
|
const img = await raw.imageData();
|
|
const cd = meta.color_data;
|
|
const plane = new Uint8Array(img.data.buffer, img.data.byteOffset, img.data.byteLength);
|
|
log('plane', img.width, 'x', img.height, 'bytes', plane.length);
|
|
log('black', cd.black, 'maximum', cd.maximum, 'mul', cd.cam_mul, 'model', meta.normalized_model);
|
|
window.__dump = {
|
|
b64: b64(plane),
|
|
width: img.width, height: img.height,
|
|
black: cd.black, maximum: cd.maximum,
|
|
cam_mul: cd.cam_mul, rgb_cam: cd.rgb_cam,
|
|
model: meta.normalized_model, raw_bps: meta.raw_bps ?? null,
|
|
};
|
|
const thumb = await raw.thumbnailData().catch(() => null);
|
|
if (thumb?.data?.length) window.__thumb = b64(new Uint8Array(thumb.data));
|
|
log('thumb', thumb?.format, thumb?.width, 'x', thumb?.height);
|
|
raw.dispose();
|
|
log('DONE');
|
|
} catch (e) {
|
|
log('ERROR', e?.message ?? String(e), (e?.stack ?? '').split('\n').slice(0, 6).join(' | '));
|
|
log('FAILED');
|
|
}
|
|
</script>
|