Skip to content

Commit

Permalink
add jpegls and j2k wasm build
Browse files Browse the repository at this point in the history
  • Loading branch information
hanayik committed Jan 19, 2025
1 parent 95d4321 commit a2d6df7
Show file tree
Hide file tree
Showing 12 changed files with 2,159 additions and 20 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# GitHub syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ dist
node_modules
dcm2niix*.js
dcm2niix*.wasm

# pixi environments
.pixi
*.egg-info

*.tar.gz
openjpeg-2.5.3/
4 changes: 2 additions & 2 deletions console/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ wasm:
emcc -O3 $(UFILES) -lz -s USE_ZLIB -s DEMANGLE_SUPPORT=1 -s EXPORTED_RUNTIME_METHODS='["callMain", "ccall", "cwrap", "FS", "FS_createDataFile", "FS_readFile", "FS_unlink", "allocateUTF8", "getValue", "stringToUTF8", "setValue"]' -s STACK_OVERFLOW_CHECK=2 -s STACK_SIZE=16MB -s ALLOW_MEMORY_GROWTH=1 -s WASM=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORTED_FUNCTIONS='["_main", "_malloc", "_free"]' -s FORCE_FILESYSTEM=1 -s INVOKE_RUN=0 -o ../js/src/dcm2niix.js
# STACK_SIZE=16MB is the minimum value found to work with the current codebase when targeting WASM

wasm-jpegls:
emcc -O3 $(JFLAGS) $(UFILES) -lz -s USE_ZLIB -s DEMANGLE_SUPPORT=1 -s EXPORTED_RUNTIME_METHODS='["callMain", "ccall", "cwrap", "FS", "FS_createDataFile", "FS_readFile", "FS_unlink", "allocateUTF8", "getValue", "stringToUTF8", "setValue"]' -s STACK_OVERFLOW_CHECK=2 -s STACK_SIZE=16MB -s ALLOW_MEMORY_GROWTH=1 -s WASM=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORTED_FUNCTIONS='["_main", "_malloc", "_free"]' -s FORCE_FILESYSTEM=1 -s INVOKE_RUN=0 -o ../js/src/dcm2niix.jpegls.js
wasm-jpeg:
emcc -O3 $(JFLAGS) $(CFILES) -DUSE_OPENJPEG -I${PIXI_PROJECT_ROOT}/openjpeg-2.5.3/src/lib/openjp2/ -I${PIXI_PROJECT_ROOT}/openjpeg-2.5.3/build/src/lib/openjp2/ -L${PIXI_PROJECT_ROOT}/openjpeg-2.5.3/build/bin/ -lopenjp2 -lz -s USE_ZLIB -s DEMANGLE_SUPPORT=1 -s EXPORTED_RUNTIME_METHODS='["callMain", "ccall", "cwrap", "FS", "FS_createDataFile", "FS_readFile", "FS_unlink", "allocateUTF8", "getValue", "stringToUTF8", "setValue"]' -s STACK_OVERFLOW_CHECK=2 -s STACK_SIZE=16MB -s ALLOW_MEMORY_GROWTH=1 -s WASM=1 -s EXPORT_ES6=1 -s MODULARIZE=1 -s EXPORTED_FUNCTIONS='["_main", "_malloc", "_free"]' -s FORCE_FILESYSTEM=1 -s INVOKE_RUN=0 -o ../js/src/dcm2niix.jpeg.js
# STACK_SIZE=16MB is the minimum value found to work with the current codebase when targeting WASM

28 changes: 28 additions & 0 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ The `@niivue/dcm2niix` JavaScript library offers an object oriented API for work
// <input type="file" id="fileInput" webkitdirectory multiple>
import { Dcm2niix } from '@niivue/dcm2niix';

// use the jpeg import to load jpegls and j2k build of dcm2niix
// import { Dcm2niix } from '@niivue/dcm2niix/jpeg';

const dcm2niix = new Dcm2niix();
// call the init() method to load the wasm before processing any data
await dcm2niix.init();
Expand Down Expand Up @@ -66,6 +69,31 @@ npm install /path/to/niivue-dcm2niix.tgz

## Development

### Environment setup

You will need:
- NodeJS/NPM
- Emscripten
- Pixi
- Make/Cmake

[Pixi](https://prefix.dev/) is used to create the environment for building the WASM port of `dcm2niix`. To install pixi, follow their instructions.

> Note: on macos-arm64, you can get emscripten using homebrew since there is not yet a native arm64 version of emscripten on conda-forge (which is where pixi searches for packages).
### Building dcm2niix WASM

```bash
pixi run wasm
```

### clean up after build

```bash
pixi run clean
```

### If doing things manually
First `cd` into the `js` directory of the `dcm2niix` repository.

```bash
Expand Down
10 changes: 5 additions & 5 deletions js/esbuild.config.jpegls.js → js/esbuild.config.jpeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const esbuild = require('esbuild');
const fs = require('fs');

esbuild.build({
entryPoints: ['./src/index.jpegls.js'],
outfile: './dist/index.jpegls.js',
entryPoints: ['./src/index.jpeg.js'],
outfile: './dist/index.jpeg.js',
bundle: true,
format: 'esm',
target: ['es2020'],
Expand All @@ -17,8 +17,8 @@ esbuild.build({
// Technically, none of the files in the src folder require processing by esbuild,
// but it does allow minification (optional), and ES version target specification if needed.
// In the future, if we use Typescript, we can use esbuild to transpile the Typescript to JS.
fs.copyFileSync('./src/worker.jpegls.js', './dist/worker.jpegls.js');
fs.copyFileSync('./src/dcm2niix.jpegls.wasm', './dist/dcm2niix.jpegls.wasm');
fs.copyFileSync('./src/dcm2niix.jpegls.js', './dist/dcm2niix.jpegls.js');
fs.copyFileSync('./src/worker.jpeg.js', './dist/worker.jpeg.js');
fs.copyFileSync('./src/dcm2niix.jpeg.wasm', './dist/dcm2niix.jpeg.wasm');
fs.copyFileSync('./src/dcm2niix.jpeg.js', './dist/dcm2niix.jpeg.js');
console.log('Build completed!');
}).catch(() => process.exit(1));
6 changes: 3 additions & 3 deletions js/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ <h1>dcm2niix WASM Demo</h1>
<a id="downloadLink" style="display: none;">Download Processed Image(s)</a>

<script type="module">
import { Dcm2niix } from './dist/index.js';
// import { Dcm2niix } from './dist/index.js';
// use below line for jpegls version
// import { Dcm2niix } from './dist/index.jpegls.js';
import { Dcm2niix } from './dist/index.jpeg.js';

const fileInput = document.getElementById('fileInput');
const processButton = document.getElementById('processButton');
Expand Down Expand Up @@ -52,7 +52,7 @@ <h1>dcm2niix WASM Demo</h1>
}
const dcm2niix = new Dcm2niix();
await dcm2niix.init()
const resultFileList = await dcm2niix.inputFromDropItems(files).run()
const resultFileList = await dcm2niix.inputFromDropItems(files).v().run()

resultFileList.forEach((resultFile, index) => {
let url = URL.createObjectURL(resultFile);
Expand Down
4 changes: 2 additions & 2 deletions js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
".": {
"import": "./dist/index.js"
},
"./with-jpegls": {
"import": "./dist/index.jpegls.js"
"./jpeg": {
"import": "./dist/index.jpeg.js"
}
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "node esbuild.config.js && node esbuild.config.jpegls.js",
"build": "node esbuild.config.js && node esbuild.config.jpeg.js",
"makeWasm": "make wasm -C ../console",
"makeWasmJpegls": "JPEGLS=1 make wasm-jpegls -C ../console",
"makeWasmJpeg": "JPEGLS=1 make wasm-jpeg -C ../console",
"fixWasmJs": "node scripts/pre-build.js -i src/dcm2niix.js -o src/dcm2niix.js",
"fixWasmJsJpegls": "node scripts/pre-build.js -i src/dcm2niix.jpegls.js -o src/dcm2niix.jpegls.js",
"prebuild": "npm run makeWasm && npm run makeWasmJpegls && npm run fixWasmJs && npm run fixWasmJsJpegls",
"fixWasmJsJpeg": "node scripts/pre-build.js -i src/dcm2niix.jpeg.js -o src/dcm2niix.jpeg.js",
"prebuild": "npm run makeWasm && npm run makeWasmJpeg && npm run fixWasmJs && npm run fixWasmJsJpeg",
"demo": "npm run build && npx http-server .",
"demo-no-build": "npx http-server .",
"pub": "npm run build && npm publish --access public"
},
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion js/src/index.jpegls.js → js/src/index.jpeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export class Dcm2niix {
}

init() {
this.worker = new Worker(new URL('./worker.jpegls.js', import.meta.url), { type: 'module' });
this.worker = new Worker(new URL('./worker.jpeg.js', import.meta.url), { type: 'module' });
return new Promise((resolve, reject) => {
// handle worker ready message.
// This gets reassigned in the run() method,
Expand Down
2 changes: 1 addition & 1 deletion js/src/worker.jpegls.js → js/src/worker.jpeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// The worker is of type "module" so that it can use ES6 module syntax.
// Importantly, the emscripten code must be compiled with: -s EXPORT_ES6=1 -s MODULARIZE=1.
// This allows proper module bundlers to import the worker and wasm properly with code splitting.
import Module from './dcm2niix.jpegls.js';
import Module from './dcm2niix.jpeg.js';

// initialise an instance of the Emscripten Module so that
// it is ready when the worker receives a message.
Expand Down
Loading

0 comments on commit a2d6df7

Please sign in to comment.