Update dicomParser. Small bug fix in hangingProtocol to avoid errors on non-image files

This commit is contained in:
Erik Ziegler 2015-11-05 19:57:07 +01:00
parent 48a9990f32
commit 1bcf4fc02d
2 changed files with 1580 additions and 1523 deletions

View File

@ -1,4 +1,4 @@
/*! dicom-parser - v1.1.5 - 2015-08-17 | (c) 2014 Chris Hafey | https://github.com/chafey/dicomParser */
/*! dicom-parser - v1.2.0 - 2015-11-02 | (c) 2014 Chris Hafey | https://github.com/chafey/dicomParser */
(function (root, factory) {
// node.js
@ -46,49 +46,12 @@
throw "dicomParser.parseDicom: missing required parameter 'byteArray'";
}
var littleEndianByteStream = new dicomParser.ByteStream(dicomParser.littleEndianByteArrayParser, byteArray);
function readPrefix()
{
littleEndianByteStream.seek(128);
var prefix = littleEndianByteStream.readFixedString(4);
if(prefix !== "DICM")
{
throw "dicomParser.parseDicom: DICM prefix not found at location 132";
}
}
function readPart10Header()
{
// Per the DICOM standard, the header is always encoded in Explicit VR Little Endian (see PS3.10, section 7.1)
// so use littleEndianByteStream throughout this method regardless of the transfer syntax
readPrefix();
var warnings = [];
var elements = {};
while(littleEndianByteStream.position < littleEndianByteStream.byteArray.length) {
var position = littleEndianByteStream.position;
var element = dicomParser.readDicomElementExplicit(littleEndianByteStream, warnings);
if(element.tag > 'x0002ffff') {
littleEndianByteStream.position = position;
break;
}
// Cache the littleEndianByteArrayParser for meta header elements, since the rest of the data set may be big endian
// and this parser will be needed later if the meta header values are to be read.
element.parser = dicomParser.littleEndianByteArrayParser;
elements[element.tag] = element;
}
var metaHeaderDataSet = new dicomParser.DataSet(littleEndianByteStream.byteArrayParser, littleEndianByteStream.byteArray, elements);
metaHeaderDataSet.warnings = littleEndianByteStream.warnings;
return metaHeaderDataSet;
}
function readTransferSyntax(metaHeaderDataSet) {
if(metaHeaderDataSet.elements.x00020010 === undefined) {
throw 'dicomParser.parseDicom: missing required meta header attribute 0002,0010';
}
var transferSyntaxElement = metaHeaderDataSet.elements.x00020010;
return dicomParser.readFixedString(littleEndianByteStream.byteArray, transferSyntaxElement.dataOffset, transferSyntaxElement.length);
return dicomParser.readFixedString(byteArray, transferSyntaxElement.dataOffset, transferSyntaxElement.length);
}
function isExplicit(transferSyntax) {
@ -100,16 +63,30 @@
return true;
}
function getDataSetByteStream(transferSyntax) {
function getDataSetByteStream(transferSyntax, position) {
if(transferSyntax === '1.2.840.10008.1.2.1.99')
{
if(typeof(pako) === "undefined") {
throw 'dicomParser.parseDicom: deflated transfer syntax encountered but pako not loaded';
}
var deflated = byteArray.slice(position);
var inflated = pako.inflateRaw(deflated);
// create a single byte array with the full header bytes and the inflated bytes
var fullByteArray = new Uint8Array(inflated.length + position);
fullByteArray.set(byteArray.slice(0, position), 0);
fullByteArray.set(inflated, position);
return new dicomParser.ByteStream(dicomParser.littleEndianByteArrayParser, fullByteArray, 0);
}
if(transferSyntax === '1.2.840.10008.1.2.2') // explicit big endian
{
return new dicomParser.ByteStream(dicomParser.bigEndianByteArrayParser, byteArray, littleEndianByteStream.position);
return new dicomParser.ByteStream(dicomParser.bigEndianByteArrayParser, byteArray, position);
}
else
{
// all other transfer syntaxes are little endian; only the pixel encoding differs
// make a new stream so the metaheader warnings don't come along for the ride
return new dicomParser.ByteStream(dicomParser.littleEndianByteArrayParser, byteArray, littleEndianByteStream.position);
return new dicomParser.ByteStream(dicomParser.littleEndianByteArrayParser, byteArray, position);
}
}
@ -132,7 +109,7 @@
{
var transferSyntax = readTransferSyntax(metaHeaderDataSet);
var explicit = isExplicit(transferSyntax);
var dataSetByteStream = getDataSetByteStream(transferSyntax);
var dataSetByteStream = getDataSetByteStream(transferSyntax, metaHeaderDataSet.position);
var elements = {};
var dataSet = new dicomParser.DataSet(dataSetByteStream.byteArrayParser, dataSetByteStream.byteArray, elements);
@ -159,7 +136,7 @@
// main function here
function parseTheByteStream() {
var metaHeaderDataSet = readPart10Header();
var metaHeaderDataSet = dicomParser.readPart10Header(byteArray, options);
var dataSet = readDataSet(metaHeaderDataSet);
@ -604,12 +581,15 @@
// move to the start of this frame
var frameOffset = pixelDataElement.basicOffsetTable[frame];
var firstFragment = byteStream.position;
byteStream.seek(frameOffset);
// Find the end of this frame
var endOfFrameOffset = pixelDataElement.basicOffsetTable[frame + 1];
if(endOfFrameOffset === undefined) { // special case for last frame
endOfFrameOffset = byteStream.position + pixelDataElement.length;
} else {
endOfFrameOffset += firstFragment;
}
// read this frame
@ -1895,6 +1875,75 @@
return dicomParser;
}(dicomParser));
/**
* Parses a DICOM P10 byte array and returns a DataSet object with the parsed elements. If the options
* argument is supplied and it contains the untilTag property, parsing will stop once that
* tag is encoutered. This can be used to parse partial byte streams.
*
* @param byteArray the byte array
* @param options object to control parsing behavior (optional)
* @returns {DataSet}
* @throws error if an error occurs while parsing. The exception object will contain a property dataSet with the
* elements successfully parsed before the error.
*/
var dicomParser = (function(dicomParser) {
if(dicomParser === undefined)
{
dicomParser = {};
}
dicomParser.readPart10Header = function(byteArray, options) {
if(byteArray === undefined)
{
throw "dicomParser.readPart10Header: missing required parameter 'byteArray'";
}
var littleEndianByteStream = new dicomParser.ByteStream(dicomParser.littleEndianByteArrayParser, byteArray);
function readPrefix()
{
littleEndianByteStream.seek(128);
var prefix = littleEndianByteStream.readFixedString(4);
if(prefix !== "DICM")
{
throw "dicomParser.readPart10Header: DICM prefix not found at location 132";
}
}
// main function here
function readTheHeader() {
// Per the DICOM standard, the header is always encoded in Explicit VR Little Endian (see PS3.10, section 7.1)
// so use littleEndianByteStream throughout this method regardless of the transfer syntax
readPrefix();
var warnings = [];
var elements = {};
while(littleEndianByteStream.position < littleEndianByteStream.byteArray.length) {
var position = littleEndianByteStream.position;
var element = dicomParser.readDicomElementExplicit(littleEndianByteStream, warnings);
if(element.tag > 'x0002ffff') {
littleEndianByteStream.position = position;
break;
}
// Cache the littleEndianByteArrayParser for meta header elements, since the rest of the data set may be big endian
// and this parser will be needed later if the meta header values are to be read.
element.parser = dicomParser.littleEndianByteArrayParser;
elements[element.tag] = element;
}
var metaHeaderDataSet = new dicomParser.DataSet(littleEndianByteStream.byteArrayParser, littleEndianByteStream.byteArray, elements);
metaHeaderDataSet.warnings = littleEndianByteStream.warnings;
metaHeaderDataSet.position = littleEndianByteStream.position;
return metaHeaderDataSet;
}
// This is where we actually start parsing
return readTheHeader();
};
return dicomParser;
})(dicomParser);
/**
* Internal helper functions for parsing DICOM elements
*/
@ -2204,7 +2253,7 @@
dicomParser = {};
}
dicomParser.version = "1.1.5";
dicomParser.version = "1.2.0";
return dicomParser;
}(dicomParser));

View File

@ -9,6 +9,14 @@ function defaultHangingProtocol(inputData) {
var stacks = [];
studies.forEach(function(study) {
study.seriesList.forEach(function(series) {
// Ensure that the series has image data
// (All images have rows)
var anInstance = series.instances[0];
if (!anInstance || !anInstance.rows) {
return;
}
var stack = {
series: series,
study: study