Getting: Error parsing byte stream RangeError: Invalid typed array length: ####
See original GitHub issueI’m trying to use the simple example to read in a dicom file and display it on the page using cornerstone and the cornerstoneWADOImageLoader libraries. I have this working fine using regular files and the wado fileuri loader, but I’m trying to get it working with byte arrays so I can do work with it with server-processed data. The simple example is throwing an error based on an incorrect Uint16Array length, I believe. Does anyone see anything wrong with this code?
const reader = new FileReader();
reader.addEventListener('load', (e) => {
let pixelData = self.loadP10Data(reader.result);
dicomImageData['example://1'] = pixelData;
self.loadAndViewP10Image('example://1');
}, false);
reader.readAsArrayBuffer(file);
loadP10Data(readerResult) {
const self = this;
try
{
let byteArray = new Uint8Array(readerResult);
// Parse the byte array to get a DataSet object that has the parsed contents
var dataSet = dicomParser.parseDicom(byteArray/*, options */);
// get the pixel data element (contains the offset and length of the data)
var pixelDataElement = dataSet.elements.x7fe00010;
// create a typed array on the pixel data (this example assumes 16 bit unsigned data)
// FAILS HERE:
var pixelData = new Uint16Array(dataSet.byteArray.buffer, pixelDataElement.dataOffset, pixelDataElement.length);
return pixelData;
}
catch(ex)
{
console.log('Error parsing byte stream', ex);
}
return '';
}
Error:
Got pixel data {tag: “x7fe00010”, vr: “OW”, length: 89456, dataOffset: 2098, hadUndefinedLength: true, …} app.js:56571 LENGTH 89456 app.js:56577 Error parsing byte stream RangeError: Invalid typed array length: 89456 at typedArrayConstructByArrayBuffer (<anonymous>) at new Uint16Array (native) at StringBase64DicomFile.loadP10Data (http://localhost:3000/app.js:56573:29) at FileReader.reader.addEventListener (http://localhost:3000/app.js:56539:26)
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (1 by maintainers)
I can’t speak to the cornerstone side, but the RangeError is most likely coming from using the length in the UInt16Array constructor. It should be the number of elements, whereas the length field from the data element is the number of bytes. So this should be more accurate, assuming each pixel is 2 bytes:
var pixelData = new Uint16Array(dataSet.byteArray.buffer, pixelDataElement.dataOffset, pixelDataElement.length / 2);
Also remember to take the BitsStored field into account: if it’s 8, you’ll need to put the pixels in a UInt8Array; if it’s 16, UInt16Array works.
Thanks for posting your solution, @rw3iss!
@swederik is this within your realm of expertise? This doesn’t sound like supported functionality, but I’ve seen similar requests floating around. It might be worth marking it as an enhancement? How hard would it be to create a custom loader that takes a “key” that corresponds to a local store, and grabs the value (byte array) and successfully creates a new image object w/ it?