Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions doc/content/api/browser_io.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ Returns:
- tags: a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) containing the mapping from tag to tag value.
- webWorker: a webworker that can be re-used.

## readDICOMTagsArrayBuffer(webWorker: Worker | null, arrayBuffer: ArrayBuffer, tags: string[] | null = null): Promise<{ tags: Map<string, string>, webWorker: Worker }>

Read tags from a DICOM [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).

Tags should be of the form `"GGGG|EEEE"`, where `GGGG` is the group ID in hex and `EEEE` is the element ID in hex. As an example, "0010|0010" is the PatientID.
Hexadecimal strings are treated case-insensitively.
A web worker object can be optionally provided to re-use a previously created web worker.
Otherwise, leave this null.

Returns:
- tags: a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) containing the mapping from tag to tag value.
- webWorker: a webworker that can be re-used.

## writeImageArrayBuffer(webWorker: Worker | null, useCompression: boolean, image: [Image](./Image.html), fileName: string, mimeType: string): Promise<{ webWorker: Worker, arrayBuffer: [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) }>

Write an image to a an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
Expand Down
1 change: 1 addition & 0 deletions src/io/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { default as readFile } from './../readFile.js'
export { default as readImageHTTP } from './../readImageHTTP.js'

export { default as readDICOMTags } from './../readDICOMTags.js'
export { default as readDICOMTagsArrayBuffer } from './../readDICOMTagsArrayBuffer.js'
export { default as readImageDICOMFileSeries } from './../readImageDICOMFileSeries.js'
export { default as readImageDICOMArrayBufferSeries } from './../readImageDICOMArrayBufferSeries.js'

Expand Down
52 changes: 2 additions & 50 deletions src/io/readDICOMTags.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,11 @@
import createWebWorkerPromise from '../core/internal/createWebWorkerPromise.js'
import { readAsArrayBuffer } from 'promise-file-reader'
import PipelineInput from '../pipeline/PipelineInput.js'
import TextStream from '../core/TextStream.js'

import config from '../itkConfig.js'

import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
import InterfaceTypes from '../core/InterfaceTypes.js'
import readDICOMTagsArrayBuffer from './readDICOMTagsArrayBuffer.js'

async function readDICOMTags (webWorker: Worker, file: File, tags: string[] | null = null): Promise<ReadDICOMTagsResult> {
let worker = webWorker
const { webworkerPromise, worker: usedWorker } = await createWebWorkerPromise(
'pipeline',
worker
)
worker = usedWorker

const arrayBuffer = await readAsArrayBuffer(file)
const dataArray = new Uint8Array(arrayBuffer)

const path = `./${file.name}`
const args = [path, '0', '--memory-io']
const inputs = [
{ type: InterfaceTypes.BinaryFile, data: { data: dataArray, path } }
] as PipelineInput[]
if (tags != null) {
args.push('--tags-to-read')
args.push('1')
inputs.push({ type: InterfaceTypes.TextStream, data: { data: JSON.stringify({ tags: tags }) } })
}
const outputs = [
{ type: InterfaceTypes.TextStream }
]

interface PipelineResult {
stdout: string
stderr: string
outputs: any[]
}

const result: PipelineResult = await webworkerPromise.postMessage(
{
operation: 'readDICOMTags',
config: config,
pipelinePath: 'ReadDICOMTags', // placeholder
args,
outputs,
inputs
},
[arrayBuffer]
)
const tagsJSON = (result.outputs[0].data as TextStream).data
const tagsResult = JSON.parse(tagsJSON)
const tagsMap: Map<string, string> = new Map(tagsResult.tags)
return { tags: tagsMap, webWorker: worker }
return await readDICOMTagsArrayBuffer(webWorker, arrayBuffer, tags)
}

export default readDICOMTags
57 changes: 57 additions & 0 deletions src/io/readDICOMTagsArrayBuffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import createWebWorkerPromise from '../core/internal/createWebWorkerPromise.js'
import PipelineInput from '../pipeline/PipelineInput.js'
import TextStream from '../core/TextStream.js'

import config from '../itkConfig.js'

import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
import InterfaceTypes from '../core/InterfaceTypes.js'

async function readDICOMTagsArrayBuffer (webWorker: Worker, arrayBuffer: ArrayBuffer, tags: string[] | null = null): Promise<ReadDICOMTagsResult> {
let worker = webWorker
const { webworkerPromise, worker: usedWorker } = await createWebWorkerPromise(
'pipeline',
worker
)
worker = usedWorker

const dataArray = new Uint8Array(arrayBuffer)

const path = './file.dcm'
const args = [path, '0', '--memory-io']
const inputs = [
{ type: InterfaceTypes.BinaryFile, data: { data: dataArray, path } }
] as PipelineInput[]
if (tags != null) {
args.push('--tags-to-read')
args.push('1')
inputs.push({ type: InterfaceTypes.TextStream, data: { data: JSON.stringify({ tags: tags }) } })
}
const outputs = [
{ type: InterfaceTypes.TextStream }
]

interface PipelineResult {
stdout: string
stderr: string
outputs: any[]
}

const result: PipelineResult = await webworkerPromise.postMessage(
{
operation: 'readDICOMTags',
config: config,
pipelinePath: 'ReadDICOMTags', // placeholder
args,
outputs,
inputs
},
[arrayBuffer]
)
const tagsJSON = (result.outputs[0].data as TextStream).data
const tagsResult = JSON.parse(tagsJSON)
const tagsMap: Map<string, string> = new Map(tagsResult.tags)
return { tags: tagsMap, webWorker: worker }
}

export default readDICOMTagsArrayBuffer
23 changes: 22 additions & 1 deletion test/browser/io/DICOMTest.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'tape'
import axios from 'axios'

import { IntTypes, PixelTypes, getMatrixElement, readImageFile, readDICOMTags } from 'browser/index.js'
import { IntTypes, PixelTypes, getMatrixElement, readImageFile, readDICOMTags, readDICOMTagsArrayBuffer } from 'browser/index.js'

export default function () {
test('Test reading a DICOM file', t => {
Expand Down Expand Up @@ -65,6 +65,27 @@ export default function () {
t.end()
})

test('Test reading DICOM tags ArrayBuffer', async t => {
const expected = {
'0010|0020': 'NOID',
'0020|0032': '-3.295510e+01\\-1.339286e+02\\1.167857e+02',
'0020|0037': '0.00000e+00\\ 1.00000e+00\\-0.00000e+00\\-0.00000e+00\\ 0.00000e+00\\-1.00000e+00',
// case sensitivity test
'0008|103e': 'SAG/RF-FAST/VOL/FLIP 30 ',
'0008|103E': 'SAG/RF-FAST/VOL/FLIP 30 '
}
const fileName = '1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.100.0.dcm'
const testFilePath = 'base/build/ExternalData/test/Input/' + fileName
const response = await axios.get(testFilePath, { responseType: 'arraybuffer' })
const arrayBuffer = response.data
const { tags: result, webWorker } = await readDICOMTagsArrayBuffer(null, arrayBuffer, Object.keys(expected))
webWorker.terminate()
t.true(result instanceof Map)
Object.keys(expected).forEach((tag) => {
t.is(result.get(tag), expected[tag], tag)
})
t.end()
})
test('Test reading all DICOM tags', async t => {
const expected = {
'0010|0020': 'NOID',
Expand Down