UNPKG

@abasb75/dicom-parser

Version:

a javascript powerfull dicom parser

318 lines (317 loc) 12.1 kB
import Dataset from "./Dataset"; import Tag from "./Tag"; import Value from "./Value"; import * as pako from "pako"; var Parser = /** @class */ (function () { function Parser(arrayBuffer) { Object.defineProperty(this, "start", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "end", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "arrayBuffer", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "offset", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "startOfset", { enumerable: true, configurable: true, writable: true, value: 132 }); Object.defineProperty(this, "dataView", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "tags", { enumerable: true, configurable: true, writable: true, value: {} }); Object.defineProperty(this, "dataSet", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "EXEPTED", { enumerable: true, configurable: true, writable: true, value: ["OB", "OW", "SQ", "UN", "UT", "OF", "UC", "OD"] }); Object.defineProperty(this, "VRS", { enumerable: true, configurable: true, writable: true, value: ["AE", "AS", "AT", "CS", "DA", "DS", "DT", "FL", "FD", "IS", "LO", "LT", "OB", "OD", "OF", "OW", "PN", "SH", "SL", "SS", "ST", "TM", "UI", "UL", "UN", "US", "UT", "UC"] }); Object.defineProperty(this, "IMPLICT_TRANSFER_SYNTAXES", { enumerable: true, configurable: true, writable: true, value: ["1.2.840.10008.1.2"] }); Object.defineProperty(this, "BIG_ENDIAN_TRANSFER_SYNTAXES", { enumerable: true, configurable: true, writable: true, value: ["1.2.840.10008.1.2.2"] }); Object.defineProperty(this, "DEFLATED_TRANSFER_SYNTAXES", { enumerable: true, configurable: true, writable: true, value: ["1.2.840.10008.1.2.1.99"] }); Object.defineProperty(this, "littleEndian", { enumerable: true, configurable: true, writable: true, value: true }); Object.defineProperty(this, "implicit", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "transferSyntaxUID", { enumerable: true, configurable: true, writable: true, value: "" }); // private UNDEFIENED_LEN:number = 0xffffffff; Object.defineProperty(this, "inflated", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "concatArrayBuffers", { enumerable: true, configurable: true, writable: true, value: function (buffer1, buffer2) { var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); tmp.set(new Uint8Array(buffer1), 0); tmp.set(new Uint8Array(buffer2), buffer1.byteLength); return tmp.buffer; } }); this.start = Date.now(); this.offset = 0; this.arrayBuffer = arrayBuffer; this.dataView = new DataView(arrayBuffer); if (this.arrayBuffer.byteLength < 132) { return; } var prefix = Value.getString(new Uint8Array(arrayBuffer, 128, 4)); if (prefix === 'DICM') { this.offset = 132; } else { this.offset = 0; while (Value.getString(this.dataView.buffer.slice(this.offset, this.offset + 1)) === "") { this.offset++; } this.startOfset = this.offset; } this.parse(); } Object.defineProperty(Parser.prototype, "parse", { enumerable: false, configurable: true, writable: true, value: function () { this.tags = this.getElements(); this.end = Date.now(); this.dataSet = new Dataset(this.tags, this.dataView, this.littleEndian, this.start, this.end); this.dataSet.transferSyntaxUID = this.transferSyntaxUID; return this.dataSet; } }); Object.defineProperty(Parser.prototype, "getDataset", { enumerable: false, configurable: true, writable: true, value: function () { return this.dataSet; } }); Object.defineProperty(Parser.prototype, "getElements", { enumerable: false, configurable: true, writable: true, value: function (sqLen) { var tags = {}; var targetOfset = (sqLen !== undefined) ? (this.offset + sqLen) : this.arrayBuffer.byteLength; while (this.offset < targetOfset) { var _a = this.getNextGroupAndElement(), group = _a.group, element = _a.element; if (!group && !element) { break; } if (sqLen && group === 0xFFFE && (element === 0xE00D || element === 0xE0DD)) { this.offset += 4; return tags; } if (group === 0xFFFE && (element === 0xE0DD || element === 0xE00D || element === 0xE000)) { this.offset += 4; continue; } if (!this.implicit && group !== 0x0002 && this.IMPLICT_TRANSFER_SYNTAXES.includes(this.transferSyntaxUID)) { this.implicit = true; } if (this.littleEndian && group !== 0x0002 && this.BIG_ENDIAN_TRANSFER_SYNTAXES.includes(this.transferSyntaxUID)) { this.littleEndian = false; } if (!this.inflated && group !== 0x0002 && this.DEFLATED_TRANSFER_SYNTAXES.includes(this.transferSyntaxUID)) { this.offset -= 4; var meta = this.dataView.buffer.slice(0, this.offset); var body = this.dataView.buffer.slice(this.offset); var infaltedBody = pako.inflateRaw(body); this.arrayBuffer = this.concatArrayBuffers(meta, infaltedBody); this.dataView = new DataView(this.arrayBuffer); this.inflated = true; return this.getElements(); } var vr = this.getNextVR(group, element); var len = 0; if (this.implicit) { len = this.dataView.getUint32(this.offset, this.littleEndian); this.offset += 4; } else if (this.EXEPTED.includes(vr)) { this.offset += 2; // skip 2 byte reserved len = this.dataView.getUint32(this.offset, this.littleEndian); this.offset += 4; } else if (this.VRS.includes(vr)) { len = this.dataView.getUint16(this.offset, this.littleEndian); this.offset += 2; } else if ((!vr || !vr.match(/^[A-Z]{2}$/)) && group === 0x0002 && element === 0x0000) { this.offset = this.startOfset; this.tags = {}; this.implicit = true; continue; } else { this.offset -= 6; this.implicit = true; continue; } if (group === 0x0002 && element === 0x0010) { this.transferSyntaxUID = (Value.getString(new Uint8Array(this.arrayBuffer, this.offset, len))).replace('\0', ''); } // find dataset thats may be as big endian dicom. // if( // this.littleEndian // && Object.keys(tags)?.length===0 // && len > this.dataView.byteLength // ){ // console.log({group,element,len,vr}); // this.littleEndian =false; // this.offset = this.startOfset; // return this.getElements(); // }else{ // console.log({group,element,len,vr}); // return tags; // } var tag = new Tag(group, element, vr, len, this.offset); if (len === 0xFFFFFFFF && group === 0x7FE0 && element === 0x0010) { var _b = this.getNextGroupAndElement(), group_1 = _b.group, element_1 = _b.element; while (true) { if (group_1 === 0xFFFE && element_1 === 0xE000) { var len_1 = this.dataView.getUint32(this.offset, this.littleEndian); this.offset += 4; var t = this.getNextGroupAndElement(); group_1 = t.group; element_1 = t.element; this.offset += len_1; } else { break; } } this.offset -= 4; } if (vr === "SQ") { tag.value = this.getElements(len); } else { this.offset += len; } var key = tag.generateKey(); tags[key] = tag; } return tags; } }); Object.defineProperty(Parser.prototype, "getValue", { enumerable: false, configurable: true, writable: true, value: function (len) { var value = this.arrayBuffer.slice(this.offset, len); this.offset += len; return value; } }); Object.defineProperty(Parser.prototype, "getNextGroupAndElement", { enumerable: false, configurable: true, writable: true, value: function () { try { var group = this.dataView.getUint16(this.offset, this.littleEndian); this.offset += 2; var element = this.dataView.getUint16(this.offset, this.littleEndian); this.offset += 2; return { group: group, element: element }; } catch (_a) { return { group: 0, element: 0 }; } } }); Object.defineProperty(Parser.prototype, "getNextVR", { enumerable: false, configurable: true, writable: true, value: function (groupInt, elementInt) { if (this.offset >= this.dataView.byteLength) { return ""; } if (this.implicit) { return Tag.getTagVRFromDictionary(groupInt, elementInt) || "AA"; } var vr = Value.getString(new Uint8Array(this.arrayBuffer, this.offset, 2)); this.offset += 2; return vr; } }); return Parser; }()); export default Parser;