Skip to content

Commit

Permalink
feat(readImageArrayBuffer): Support componentType, pixelType options
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Nov 4, 2022
1 parent 149721d commit 6d1c20a
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 39 deletions.
7 changes: 7 additions & 0 deletions src/io/ReadImageArrayBufferOptions.ts
@@ -0,0 +1,7 @@
import CastImageOptions from '../core/CastImageOptions.js'

interface ReadImageArrayBufferOptions extends CastImageOptions {
mimeType: string
}

export default ReadImageArrayBufferOptions
1 change: 1 addition & 0 deletions src/io/browser/index.ts
Expand Up @@ -4,6 +4,7 @@ export { default as getFileExtension } from './../getFileExtension.js'
export { default as extensionToImageIO } from './../extensionToImageIO.js'
export { default as extensionToMeshIO } from './../extensionToMeshIO.js'

export { default as ReadImageArrayBufferOptions } from './../ReadImageArrayBufferOptions.js'
export { default as readImageArrayBuffer } from './../readImageArrayBuffer.js'
export { default as readMeshArrayBuffer } from './../readMeshArrayBuffer.js'
export { default as readArrayBuffer } from './../readArrayBuffer.js'
Expand Down
21 changes: 19 additions & 2 deletions src/io/readImageArrayBuffer.ts
Expand Up @@ -2,12 +2,14 @@ import createWebWorkerPromise from '../core/internal/createWebWorkerPromise.js'
import Image from '../core/Image.js'
import InterfaceTypes from '../core/InterfaceTypes.js'
import PipelineInput from '../pipeline/PipelineInput.js'
import castImage from '../core/castImage.js'

import config from '../itkConfig.js'

import ReadImageResult from './ReadImageResult.js'
import ReadImageArrayBufferOptions from './ReadImageArrayBufferOptions.js'

async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, mimeType: string): Promise<ReadImageResult> {
async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, options?: ReadImageArrayBufferOptions | string): Promise<ReadImageResult> {
let worker = webWorker
const { webworkerPromise, worker: usedWorker } = await createWebWorkerPromise(worker)
worker = usedWorker
Expand All @@ -27,6 +29,16 @@ async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: Arra
stderr: string
outputs: any[]
}
let mimeType = undefined
if (typeof options === 'undefined') {
} else if (typeof options === 'string') {
// backwards compatibility
mimeType = options
} else if (typeof options === 'object') {
if (typeof options.mimeType === 'string') {
mimeType = options.mimeType
}
}
const result: RunReadImagePipelineResult = await webworkerPromise.postMessage(
{
operation: 'readImage',
Expand All @@ -40,7 +52,12 @@ async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: Arra
},
transferables
)
return { image: result.outputs[0].data as Image, webWorker: worker }
let image = result.outputs[0].data as Image
if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
image = castImage(image, options)
}

return { image, webWorker: worker }
}

export default readImageArrayBuffer
80 changes: 47 additions & 33 deletions test/browser/io/readImageTest.js
Expand Up @@ -13,10 +13,10 @@ for (let ii = 0; ii < byteString.length; ++ii) {
const cthead1SmallBlob = new window.Blob([intArray], { type: mimeString })
const cthead1SmallFile = new window.File([cthead1SmallBlob], 'cthead1Small.png')

const verifyImage = (t, image) => {
function verifyImage(t, image, componentType, pixelType) {
t.is(image.imageType.dimension, 2, 'dimension')
t.is(image.imageType.componentType, IntTypes.UInt8, 'componentType')
t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
t.is(image.imageType.componentType, componentType)
t.is(image.imageType.pixelType, pixelType)
t.is(image.imageType.components, 1, 'components')
t.is(image.origin[0], 0.0, 'origin[0]')
t.is(image.origin[1], 0.0, 'origin[1]')
Expand All @@ -34,42 +34,56 @@ const verifyImage = (t, image) => {
}

export default function () {
test('readImageArrayBuffer reads an ArrayBuffer', (t) => {
return PromiseFileReader.readAsArrayBuffer(cthead1SmallFile)
.then(arrayBuffer => {
return readImageArrayBuffer(null, arrayBuffer, 'cthead1Small.png')
.then(function ({ image, webWorker }) {
webWorker.terminate()
verifyImage(t, image)
})
})
test('readImageArrayBuffer reads an ArrayBuffer', async (t) => {
const arrayBuffer = await PromiseFileReader.readAsArrayBuffer(cthead1SmallFile)
const { image, webWorker } = await readImageArrayBuffer(null, arrayBuffer, 'cthead1Small.png')
webWorker.terminate()
const componentType = IntTypes.UInt8
const pixelType = PixelTypes.Scalar
verifyImage(t, image, componentType, pixelType)
})

test('readImageBlob reads a Blob', (t) => {
return readImageBlob(null, cthead1SmallBlob, 'cthead1Small.png')
.then(function ({ image, webWorker }) {
webWorker.terminate()
verifyImage(t, image)
})
test('readImageArrayBuffer casts to the specified componentType', async (t) => {
const arrayBuffer = await PromiseFileReader.readAsArrayBuffer(cthead1SmallFile)
const componentType = IntTypes.UInt16
const { image, webWorker } = await readImageArrayBuffer(null, arrayBuffer, 'cthead1Small.png', { componentType })
webWorker.terminate()
const pixelType = PixelTypes.Scalar
verifyImage(t, image, componentType, pixelType)
})

test('readImageFile reads a File', (t) => {
return readImageFile(null, cthead1SmallFile)
.then(function ({ image, webWorker }) {
webWorker.terminate()
verifyImage(t, image)
})
test('readImageArrayBuffer casts to the specified pixelType', async (t) => {
const arrayBuffer = await PromiseFileReader.readAsArrayBuffer(cthead1SmallFile)
const componentType = IntTypes.UInt16
const pixelType = PixelTypes.Scalar
const { image, webWorker } = await readImageArrayBuffer(null, arrayBuffer, 'cthead1Small.png', { componentType, pixelType })
webWorker.terminate()
verifyImage(t, image, componentType, pixelType)
})

test('readImageFile re-uses a WebWorker', (t) => {
return readImageFile(null, cthead1SmallFile)
.then(function ({ image, webWorker }) {
return readImageFile(webWorker, cthead1SmallFile)
.then(function ({ image, webWorker }) {
webWorker.terminate()
verifyImage(t, image)
})
})
test('readImageBlob reads a Blob', async (t) => {
const { image, webWorker } = await readImageBlob(null, cthead1SmallBlob, 'cthead1Small.png')
webWorker.terminate()
const componentType = IntTypes.UInt8
const pixelType = PixelTypes.Scalar
verifyImage(t, image, componentType, pixelType)
})

test('readImageFile reads a File', async (t) => {
const { image, webWorker } = await readImageFile(null, cthead1SmallFile)
webWorker.terminate()
const componentType = IntTypes.UInt8
const pixelType = PixelTypes.Scalar
verifyImage(t, image, componentType, pixelType)
})

test('readImageFile re-uses a WebWorker', async (t) => {
const { webWorker } = await readImageFile(null, cthead1SmallFile)
const { image } = await readImageFile(webWorker, cthead1SmallFile)
webWorker.terminate()
const componentType = IntTypes.UInt8
const pixelType = PixelTypes.Scalar
verifyImage(t, image, componentType, pixelType)
})

test('readImageFile throws a catchable error for an invalid file', (t) => {
Expand Down
7 changes: 3 additions & 4 deletions test/node/io/image/PNGTest.js
Expand Up @@ -24,10 +24,9 @@ const verifyImage = (t, image) => {
t.is(image.data.length, 196608, 'data.length')
}

test('Test reading a PNG file', t => {
return readImageLocalFile(testInputFilePath).then(function (image) {
verifyImage(t, image)
})
test('Test reading a PNG file', async t => {
const image = await readImageLocalFile(testInputFilePath)
verifyImage(t, image)
})

test('Test writing a PNG file', t => {
Expand Down

0 comments on commit 6d1c20a

Please sign in to comment.