Skip to content

Commit 5f47b43

Browse files
committed
feat(readDICOMTagsArrayBuffer): Initial addition
1 parent eea33d4 commit 5f47b43

File tree

5 files changed

+95
-51
lines changed

5 files changed

+95
-51
lines changed

doc/content/api/browser_io.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ Returns:
9090
- tags: a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) containing the mapping from tag to tag value.
9191
- webWorker: a webworker that can be re-used.
9292

93+
## readDICOMTagsArrayBuffer(webWorker: Worker | null, arrayBuffer: ArrayBuffer, tags: string[] | null = null): Promise<{ tags: Map<string, string>, webWorker: Worker }>
94+
95+
Read tags from a DICOM [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
96+
97+
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.
98+
Hexadecimal strings are treated case-insensitively.
99+
A web worker object can be optionally provided to re-use a previously created web worker.
100+
Otherwise, leave this null.
101+
102+
Returns:
103+
- tags: a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) containing the mapping from tag to tag value.
104+
- webWorker: a webworker that can be re-used.
105+
93106
## 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) }>
94107

95108
Write an image to a an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).

src/io/browser/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export { default as readFile } from './../readFile.js'
1717
export { default as readImageHTTP } from './../readImageHTTP.js'
1818

1919
export { default as readDICOMTags } from './../readDICOMTags.js'
20+
export { default as readDICOMTagsArrayBuffer } from './../readDICOMTagsArrayBuffer.js'
2021
export { default as readImageDICOMFileSeries } from './../readImageDICOMFileSeries.js'
2122
export { default as readImageDICOMArrayBufferSeries } from './../readImageDICOMArrayBufferSeries.js'
2223

src/io/readDICOMTags.ts

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,11 @@
1-
import createWebWorkerPromise from '../core/internal/createWebWorkerPromise.js'
21
import { readAsArrayBuffer } from 'promise-file-reader'
3-
import PipelineInput from '../pipeline/PipelineInput.js'
4-
import TextStream from '../core/TextStream.js'
5-
6-
import config from '../itkConfig.js'
72

83
import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
9-
import InterfaceTypes from '../core/InterfaceTypes.js'
4+
import readDICOMTagsArrayBuffer from './readDICOMTagsArrayBuffer.js'
105

116
async function readDICOMTags (webWorker: Worker, file: File, tags: string[] | null = null): Promise<ReadDICOMTagsResult> {
12-
let worker = webWorker
13-
const { webworkerPromise, worker: usedWorker } = await createWebWorkerPromise(
14-
'pipeline',
15-
worker
16-
)
17-
worker = usedWorker
18-
197
const arrayBuffer = await readAsArrayBuffer(file)
20-
const dataArray = new Uint8Array(arrayBuffer)
21-
22-
const path = `./${file.name}`
23-
const args = [path, '0', '--memory-io']
24-
const inputs = [
25-
{ type: InterfaceTypes.BinaryFile, data: { data: dataArray, path } }
26-
] as PipelineInput[]
27-
if (tags != null) {
28-
args.push('--tags-to-read')
29-
args.push('1')
30-
inputs.push({ type: InterfaceTypes.TextStream, data: { data: JSON.stringify({ tags: tags }) } })
31-
}
32-
const outputs = [
33-
{ type: InterfaceTypes.TextStream }
34-
]
35-
36-
interface PipelineResult {
37-
stdout: string
38-
stderr: string
39-
outputs: any[]
40-
}
41-
42-
const result: PipelineResult = await webworkerPromise.postMessage(
43-
{
44-
operation: 'readDICOMTags',
45-
config: config,
46-
pipelinePath: 'ReadDICOMTags', // placeholder
47-
args,
48-
outputs,
49-
inputs
50-
},
51-
[arrayBuffer]
52-
)
53-
const tagsJSON = (result.outputs[0].data as TextStream).data
54-
const tagsResult = JSON.parse(tagsJSON)
55-
const tagsMap: Map<string, string> = new Map(tagsResult.tags)
56-
return { tags: tagsMap, webWorker: worker }
8+
return await readDICOMTagsArrayBuffer(webWorker, arrayBuffer, tags)
579
}
5810

5911
export default readDICOMTags

src/io/readDICOMTagsArrayBuffer.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import createWebWorkerPromise from '../core/internal/createWebWorkerPromise.js'
2+
import PipelineInput from '../pipeline/PipelineInput.js'
3+
import TextStream from '../core/TextStream.js'
4+
5+
import config from '../itkConfig.js'
6+
7+
import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
8+
import InterfaceTypes from '../core/InterfaceTypes.js'
9+
10+
async function readDICOMTagsArrayBuffer (webWorker: Worker, arrayBuffer: ArrayBuffer, tags: string[] | null = null): Promise<ReadDICOMTagsResult> {
11+
let worker = webWorker
12+
const { webworkerPromise, worker: usedWorker } = await createWebWorkerPromise(
13+
'pipeline',
14+
worker
15+
)
16+
worker = usedWorker
17+
18+
const dataArray = new Uint8Array(arrayBuffer)
19+
20+
const path = './file.dcm'
21+
const args = [path, '0', '--memory-io']
22+
const inputs = [
23+
{ type: InterfaceTypes.BinaryFile, data: { data: dataArray, path } }
24+
] as PipelineInput[]
25+
if (tags != null) {
26+
args.push('--tags-to-read')
27+
args.push('1')
28+
inputs.push({ type: InterfaceTypes.TextStream, data: { data: JSON.stringify({ tags: tags }) } })
29+
}
30+
const outputs = [
31+
{ type: InterfaceTypes.TextStream }
32+
]
33+
34+
interface PipelineResult {
35+
stdout: string
36+
stderr: string
37+
outputs: any[]
38+
}
39+
40+
const result: PipelineResult = await webworkerPromise.postMessage(
41+
{
42+
operation: 'readDICOMTags',
43+
config: config,
44+
pipelinePath: 'ReadDICOMTags', // placeholder
45+
args,
46+
outputs,
47+
inputs
48+
},
49+
[arrayBuffer]
50+
)
51+
const tagsJSON = (result.outputs[0].data as TextStream).data
52+
const tagsResult = JSON.parse(tagsJSON)
53+
const tagsMap: Map<string, string> = new Map(tagsResult.tags)
54+
return { tags: tagsMap, webWorker: worker }
55+
}
56+
57+
export default readDICOMTagsArrayBuffer

test/browser/io/DICOMTest.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import test from 'tape'
22
import axios from 'axios'
33

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

66
export default function () {
77
test('Test reading a DICOM file', t => {
@@ -65,6 +65,27 @@ export default function () {
6565
t.end()
6666
})
6767

68+
test('Test reading DICOM tags ArrayBuffer', async t => {
69+
const expected = {
70+
'0010|0020': 'NOID',
71+
'0020|0032': '-3.295510e+01\\-1.339286e+02\\1.167857e+02',
72+
'0020|0037': '0.00000e+00\\ 1.00000e+00\\-0.00000e+00\\-0.00000e+00\\ 0.00000e+00\\-1.00000e+00',
73+
// case sensitivity test
74+
'0008|103e': 'SAG/RF-FAST/VOL/FLIP 30 ',
75+
'0008|103E': 'SAG/RF-FAST/VOL/FLIP 30 '
76+
}
77+
const fileName = '1.3.6.1.4.1.5962.99.1.3814087073.479799962.1489872804257.100.0.dcm'
78+
const testFilePath = 'base/build/ExternalData/test/Input/' + fileName
79+
const response = await axios.get(testFilePath, { responseType: 'arraybuffer' })
80+
const arrayBuffer = response.data
81+
const { tags: result, webWorker } = await readDICOMTagsArrayBuffer(null, arrayBuffer, Object.keys(expected))
82+
webWorker.terminate()
83+
t.true(result instanceof Map)
84+
Object.keys(expected).forEach((tag) => {
85+
t.is(result.get(tag), expected[tag], tag)
86+
})
87+
t.end()
88+
})
6889
test('Test reading all DICOM tags', async t => {
6990
const expected = {
7091
'0010|0020': 'NOID',

0 commit comments

Comments
 (0)