Skip to content

Commit a1ea23e

Browse files
committed
Support ASYNC functions (#52)
1 parent b18d386 commit a1ea23e

26 files changed

+903
-399
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { isCompressed, readHeaderAsync, decompressAsync, isNIFTI1, readImage } from '../src/nifti.js'
2+
import { NIFTI1 } from '../src/nifti1.js'
3+
import { describe, it, assert, beforeEach } from 'vitest'
4+
import * as fs from 'fs'
5+
import { Utils } from '../src/utilities.js'
6+
import { NIFTI2 } from '../src/nifti2.js'
7+
8+
let data: ArrayBuffer
9+
let nifti1: NIFTI1 | NIFTI2 | null = null
10+
11+
beforeEach(async () => {
12+
const buf = fs.readFileSync('./data/little.nii.gz')
13+
data = Utils.toArrayBuffer(buf)
14+
if (isCompressed(data)) {
15+
data = await decompressAsync(data)
16+
}
17+
nifti1 = await readHeaderAsync(data)
18+
})
19+
20+
describe('NIFTI-Reader-JS', function () {
21+
describe('nifti-1 little endian test', function () {
22+
it('should have a valid NIFTI header', async function () {
23+
assert.notEqual(nifti1, null)
24+
console.log(nifti1)
25+
})
26+
27+
it('isNIFTI1() should return true', async function () {
28+
assert.equal(true, isNIFTI1(data))
29+
})
30+
31+
it('numBitsPerVoxel should be 32', async function () {
32+
assert.equal(32, nifti1!.numBitsPerVoxel)
33+
})
34+
35+
it('littleEndian should be true', async function () {
36+
assert.equal(true, nifti1!.littleEndian)
37+
})
38+
39+
it('dims[1] should be 64', async function () {
40+
assert.equal(64, nifti1!.dims[1])
41+
})
42+
43+
it('dims[2] should be 64', async function () {
44+
assert.equal(64, nifti1!.dims[2])
45+
})
46+
47+
it('dims[3] should be 21', async function () {
48+
assert.equal(21, nifti1!.dims[3])
49+
})
50+
51+
it('image data checksum should equal 4006845507', async function () {
52+
const imageData = readImage(nifti1!, data)
53+
const checksum = Utils.crc32(new DataView(imageData))
54+
assert.equal(checksum, 4006845507)
55+
})
56+
})
57+
})
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { readHeaderAsync } from '../src/nifti.js'
2+
import { NIFTI1 } from '../src/nifti1.js'
3+
import * as fs from 'fs'
4+
import { Utils } from '../src/utilities.js'
5+
import { NIFTI2 } from '../src/nifti2.js'
6+
import { NIFTIEXTENSION } from '../src/nifti.js'
7+
import { describe, it, assert, beforeEach } from 'vitest'
8+
9+
let nifti2 = null
10+
11+
beforeEach(async () => {
12+
const buf = fs.readFileSync('./data/avg152T1_LR_nifti2.nii.gz')
13+
const data = Utils.toArrayBuffer(buf)
14+
nifti2 = await readHeaderAsync(data)
15+
})
16+
17+
describe('NIFTI-Reader-JS', function () {
18+
const EXPECTED_EXTENSION_LENGTH = 376
19+
20+
describe('nifti-2 extension test', function () {
21+
it('should not throw error when reading header', async function () {
22+
assert.doesNotThrow(() => {
23+
if (!nifti2) {
24+
throw new Error('Failed to read NIFTI header')
25+
}
26+
})
27+
})
28+
29+
it('extensions can be added and serialized', async function () {
30+
let edata = new Int32Array(6)
31+
edata.fill(8)
32+
let newExtension = new NIFTIEXTENSION(32, 4, edata.buffer, true)
33+
nifti2!.addExtension(newExtension)
34+
35+
assert.equal(1, nifti2!.extensions.length)
36+
37+
let bytes = nifti2!.toArrayBuffer(true)
38+
let copy = await readHeaderAsync(bytes)
39+
40+
assert.equal(1, copy!.extensions.length)
41+
assert.equal(4, copy!.extensions[0].ecode)
42+
assert.equal(24, copy!.extensions[0].edata.byteLength)
43+
})
44+
})
45+
})
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { readHeaderAsync } from '../src/nifti.js'
2+
import { NIFTI1 } from '../src/nifti1.js'
3+
import * as fs from 'fs'
4+
import { Utils } from '../src/utilities.js'
5+
import { NIFTI2 } from '../src/nifti2.js'
6+
import { NIFTIEXTENSION } from '../src/nifti.js'
7+
import { describe, it, assert, beforeEach } from 'vitest'
8+
9+
let nifti2 = null
10+
11+
async function compress(data: ArrayBuffer): Promise<ArrayBuffer> {
12+
const uint8Data = new Uint8Array(data)
13+
const format = 'gzip' // Changed to gzip as requested
14+
const stream = new CompressionStream(format)
15+
const writer = stream.writable.getWriter()
16+
17+
await writer.write(uint8Data)
18+
await writer.close()
19+
20+
const response = new Response(stream.readable)
21+
return await response.arrayBuffer()
22+
}
23+
24+
beforeEach(async () => {
25+
const buf = fs.readFileSync('./data/avg152T1_LR_nifti2.nii.gz')
26+
const data = Utils.toArrayBuffer(buf)
27+
nifti2 = await readHeaderAsync(data)
28+
})
29+
30+
describe('NIFTI-Reader-JS', function () {
31+
const EXPECTED_EXTENSION_LENGTH = 376
32+
33+
describe('nifti-2 extension test', function () {
34+
it('should not throw error when reading header', async function () {
35+
assert.doesNotThrow(() => {
36+
if (!nifti2) {
37+
throw new Error('Failed to read NIFTI header')
38+
}
39+
})
40+
})
41+
42+
it('extensions can be added, compressed, and serialized', async function () {
43+
let edata = new Int32Array(6)
44+
edata.fill(8)
45+
let newExtension = new NIFTIEXTENSION(32, 4, edata.buffer, true)
46+
nifti2!.addExtension(newExtension)
47+
48+
assert.equal(1, nifti2!.extensions.length)
49+
50+
let bytes = nifti2!.toArrayBuffer(true)
51+
console.log('Original bytes length:', bytes.byteLength)
52+
53+
// Compress the arrayBuffer bytes using gzip
54+
let compressedBytes = await compress(bytes)
55+
console.log('Compressed bytes length:', compressedBytes.byteLength)
56+
57+
// Decompress and read the header
58+
let copy = await readHeaderAsync(compressedBytes)
59+
60+
assert.equal(1, copy!.extensions.length)
61+
assert.equal(4, copy!.extensions[0].ecode)
62+
assert.equal(24, copy!.extensions[0].edata.byteLength)
63+
})
64+
})
65+
})

dist/nifti-extension.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ export declare class NIFTIEXTENSION {
1818
* Returns extension as ArrayBuffer.
1919
* @returns {ArrayBuffer}
2020
*/
21-
toArrayBuffer(): ArrayBufferLike;
21+
toArrayBuffer(): ArrayBuffer;
2222
}
2323
//# sourceMappingURL=nifti-extension.d.ts.map

dist/nifti-extension.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/nifti-extension.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/nifti.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,26 @@ export declare function isCompressed(data: ArrayBuffer): boolean;
3535
* @returns {ArrayBuffer}
3636
*/
3737
export declare function decompress(data: ArrayBuffer): ArrayBufferLike;
38+
/**
39+
* Returns promise of decompressed data.
40+
* @param {ArrayBuffer} data
41+
* @returns {Promise<ArrayBuffer>}
42+
*/
43+
export declare function decompressAsync(data: ArrayBuffer): Promise<ArrayBuffer>;
44+
/**
45+
* Returns promise of decompressed initial portion of data, reads at least minOutputBytes or entire file.
46+
* @param {ArrayBuffer} data
47+
* @param {number } minOutputBytes
48+
* @returns {Promise<ArrayBuffer>}
49+
*/
50+
export declare function decompressHeaderAsync(data: ArrayBuffer, minOutputBytes?: number): Promise<ArrayBufferLike>;
3851
/**
3952
* Reads and returns the header object.
4053
* @param {ArrayBuffer} data
4154
* @returns {NIFTI1|NIFTI2}
4255
*/
4356
export declare function readHeader(data: ArrayBuffer, isHdrImgPairOK?: boolean): NIFTI1 | NIFTI2;
57+
export declare function readHeaderAsync(data: ArrayBuffer, isHdrImgPairOK?: boolean): Promise<NIFTI1 | NIFTI2>;
4458
/**
4559
* Returns true if this header contains an extension.
4660
* @param {NIFTI1|NIFTI2} header

dist/nifti.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/nifti.js

Lines changed: 147 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)