Skip to content

Commit

Permalink
wip: Update jpeg decoder.
Browse files Browse the repository at this point in the history
I was trying to see an xray that I got recently (happy to email it
privately if it helps), which fails to decode on the demo with:

```
JPX Error: Unsupported COD options (selectiveArithmeticCodingBypass) jpx.js:339:23
```

So this tries to update to openjpeg via
mozilla/pdf.js#17946, which should support it.
However:

 * It's very WIP (the image decodes correctly on the worker, but I only
   see black on the canvas, however I see correct metadata).
 * I haven't updated all the references to the other decoders.
 * It loads the non-jpeg decoders as a module which I can't test, but
   probably breaks them. I also need to update the sync decoders, which
   likely doesn't work.

I don't think I'll have time to finish this, but posting it here in case
it saves someone time or someone has the time to finish it up.

Thanks.
  • Loading branch information
emilio committed Apr 19, 2024
1 parent 63fd64f commit 72c5f70
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 2,418 deletions.
185 changes: 0 additions & 185 deletions decoders/pdfjs/arithmetic_decoder.js

This file was deleted.

62 changes: 56 additions & 6 deletions decoders/pdfjs/decode-jpeg2000.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,65 @@
// Do not warn if these variables were not defined before.
/* global importScripts, JpxImage */

importScripts('jpx.js', 'util.js', 'arithmetic_decoder.js');
import OpenJPEG from "./openjpeg.js";

self.addEventListener('message', function (event) {
class JpxError extends Error {
constructor(msg) {
super(`JPX error: ${msg}`, "JpxError");
}
}

class JpxImage {
static #module = null;

static decode(data, ignoreColorSpace) {
this.#module ||= OpenJPEG();
const imageData = this.#module.decode(data, ignoreColorSpace);
if (!imageData) {
throw new JpxError("JPX decode failed");
}
return imageData;
}

static cleanup() {
this.#module = null;
}

static parseImageProperties(stream) {
// No need to use OpenJPEG here since we're only getting very basic
// information which are located in the first bytes of the file.
let newByte = stream.getByte();
while (newByte >= 0) {
const oldByte = newByte;
newByte = stream.getByte();
const code = (oldByte << 8) | newByte;
// Image and tile size (SIZ)
if (code === 0xff51) {
stream.skip(4);
const Xsiz = stream.getInt32() >>> 0; // Byte 4
const Ysiz = stream.getInt32() >>> 0; // Byte 8
const XOsiz = stream.getInt32() >>> 0; // Byte 12
const YOsiz = stream.getInt32() >>> 0; // Byte 16
stream.skip(16);
const Csiz = stream.getUint16(); // Byte 36
return {
width: Xsiz - XOsiz,
height: Ysiz - YOsiz,
// Results are always returned as `Uint8ClampedArray`s.
bitsPerComponent: 8,
componentsCount: Csiz,
};
}
}
throw new JpxError("No size marker found in JPX stream");
}
}

console.log(JpxImage);

self.addEventListener('message', function (event) {
// decode DICOM buffer
var decoder = new JpxImage();
decoder.parse(event.data.buffer);
let res = JpxImage.decode(event.data.buffer, /* ignoreColorSpace = */ true);
// post decoded data
var res = decoder.tiles[0].items;
self.postMessage([res]);

}, false);
Loading

0 comments on commit 72c5f70

Please sign in to comment.