解析Dicom Tag

uat_us
caiyiling 2024-01-23 14:50:28 +08:00
parent 8156c43525
commit 82915b6860
1 changed files with 608 additions and 0 deletions

View File

@ -0,0 +1,608 @@
/*! dicom-character-set - 1.0.5 - 2024-01-10 | (c) 2018 Radialogica, LLC | https://github.com/radialogica/dicom-character-set */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["dicom-character-set"] = factory();
else
root["dicom-character-set"] = factory();
})(typeof self !== "undefined" ? self : this, () => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./character-sets.js":
/*!***************************!*\
!*** ./character-sets.js ***!
\***************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ characterSets: () => (/* binding */ characterSets)
/* harmony export */ });
const asciiElement = {
codeElement: 'G0',
escapeSequence: [0x1B, 0x28, 0x42],
encoding: 'windows-1252',
isASCII: true,
bytesPerCodePoint: 1
};
const characterSets = {
/** ********************************
* Single-byte without extensions *
**********************************/
// Default
'ISO_IR 6': {
encoding: 'utf-8'
},
// Latin alphabet No. 1
'ISO_IR 100': {
encoding: 'windows-1252'
},
// Latin alphabet No. 2
'ISO_IR 101': {
encoding: 'iso-8859-2'
},
// Latin alphabet No. 3
'ISO_IR 109': {
encoding: 'iso-8859-3'
},
// Latin alphabet No. 4
'ISO_IR 110': {
encoding: 'iso-8859-4'
},
// Cyrillic
'ISO_IR 144': {
encoding: 'iso-8859-5'
},
// Arabic
'ISO_IR 127': {
encoding: 'iso-8859-6'
},
// Greek
'ISO_IR 126': {
encoding: 'iso-8859-7'
},
// Hebrew
'ISO_IR 138': {
encoding: 'iso-8859-8'
},
// Latin alphabet No. 5
'ISO_IR 148': {
encoding: 'windows-1254'
},
// Japanese
'ISO_IR 13': {
encoding: 'shift-jis'
},
// Thai
'ISO_IR 166': {
encoding: 'tis-620'
},
/** *****************************
* Single-byte with extensions *
*******************************/
// Default
'ISO 2022 IR 6': {
extension: true,
elements: [asciiElement]
},
// Latin alphabet No. 1
'ISO 2022 IR 100': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x41],
encoding: 'windows-1252',
bytesPerCodePoint: 1
}]
},
// Latin alphabet No. 2
'ISO 2022 IR 101': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x42],
encoding: 'iso-8859-2',
bytesPerCodePoint: 1
}]
},
// Latin alphabet No. 3
'ISO 2022 IR 109': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x43],
encoding: 'iso-8859-3',
bytesPerCodePoint: 1
}]
},
// Latin alphabet No. 4
'ISO 2022 IR 110': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x44],
encoding: 'iso-8859-4',
bytesPerCodePoint: 1
}]
},
// Cyrillic
'ISO 2022 IR 144': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x4C],
encoding: 'iso-8859-5',
bytesPerCodePoint: 1
}]
},
// Arabic
'ISO 2022 IR 127': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x47],
encoding: 'iso-8859-6',
bytesPerCodePoint: 1
}]
},
// Greek
'ISO 2022 IR 126': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x46],
encoding: 'iso-8859-7',
bytesPerCodePoint: 1
}]
},
// Hebrew
'ISO 2022 IR 138': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x48],
encoding: 'iso-8859-8',
bytesPerCodePoint: 1
}]
},
// Latin alphabet No. 5
'ISO 2022 IR 148': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x4D],
encoding: 'windows-1254',
bytesPerCodePoint: 1
}]
},
// Japanese
'ISO 2022 IR 13': {
extension: true,
elements: [{
codeElement: 'G0',
escapeSequence: [0x1B, 0x28, 0x4A],
encoding: 'shift-jis',
bytesPerCodePoint: 1
}, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x29, 0x49],
encoding: 'shift-jis',
bytesPerCodePoint: 1
}]
},
// Thai
'ISO 2022 IR 166': {
extension: true,
elements: [asciiElement, {
codeElement: 'G1',
escapeSequence: [0x1B, 0x2D, 0x54],
encoding: 'tis-620',
bytesPerCodePoint: 1
}]
},
/** ****************************
* Multi-byte with extensions *
******************************/
// Japanese
'ISO 2022 IR 87': {
extension: true,
multiByte: true,
elements: [{
codeElement: 'G0',
escapeSequence: [0x1B, 0x24, 0x42],
encoding: 'euc-jp',
setHighBit: true,
bytesPerCodePoint: 2
}]
},
'ISO 2022 IR 159': {
extension: true,
multiByte: true,
elements: [{
codeElement: 'G0',
escapeSequence: [0x1B, 0x24, 0x28, 0x44],
encoding: 'euc-jp',
isJISX0212: true,
bytesPerCodePoint: 2
}]
},
// Korean
'ISO 2022 IR 149': {
extension: true,
multiByte: true,
elements: [{
codeElement: 'G1',
escapeSequence: [0x1B, 0x24, 0x29, 0x43],
encoding: 'euc-kr',
bytesPerCodePoint: 2
}]
},
// Simplified Chinese
'ISO 2022 IR 58': {
extension: true,
multiByte: true,
elements: [{
codeElement: 'G1',
escapeSequence: [0x1B, 0x24, 0x29, 0x41],
encoding: 'gb18030',
bytesPerCodePoint: 2
}]
},
/** *******************************
* Multi-byte without extensions *
*********************************/
'ISO_IR 192': {
encoding: 'utf-8',
multiByte: true
},
GB18030: {
encoding: 'gb18030',
multiByte: true
},
GBK: {
encoding: 'gbk',
multiByte: true
}
};
/***/ }),
/***/ "./convert-bytes.js":
/*!**************************!*\
!*** ./convert-bytes.js ***!
\**************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ convertBytes: () => (/* binding */ convertBytes),
/* harmony export */ convertBytesPromise: () => (/* binding */ convertBytesPromise)
/* harmony export */ });
/* harmony import */ var _character_sets_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./character-sets.js */ "./character-sets.js");
const ESCAPE_BYTE = 0x1B;
const CARRIAGE_RETURN = 0xA;
const LINE_FEED = 0xC;
const FORM_FEED = 0xD;
const TAB = 0x9;
const BACKSLASH = 0x5C; // Aka yen symbol in Romaji
const EQUAL_SIGN = 0x3D;
const CARET = 0x5E;
function adjustShiftJISResult(delimiters, str) {
// browsers do strict ASCII for \ and ~, so to be compliant with Shift JIS we replace them
const fixedTildes = str.replace(/~/g, '‾');
// If 0x5c is being used as a multi-value separator, we must not replace it so it stays as U+005c
return delimiters.includes(BACKSLASH) ? fixedTildes : fixedTildes.replace(/\\/g, '¥');
}
function appendRunWithoutPromise(output, byteRunCharacterSet, delimiters, bytes, byteRunStart, byteRunEnd) {
const oneRunBytes = preprocessBytes(byteRunCharacterSet, bytes, byteRunStart, byteRunEnd);
return output + convertWithoutExtensions(byteRunCharacterSet.encoding, delimiters, oneRunBytes);
}
function appendRunWithPromise(output, byteRunCharacterSet, delimiters, bytes, byteRunStart, byteRunEnd) {
const oneRunBytes = preprocessBytes(byteRunCharacterSet, bytes, byteRunStart, byteRunEnd);
return (output === '' ? Promise.resolve('') : output).then(lhs => convertWithoutExtensionsPromise(byteRunCharacterSet.encoding, delimiters, oneRunBytes).then(rhs => lhs + rhs));
}
function checkParameters(specificCharacterSet, bytes) {
if (bytes && !(bytes instanceof Uint8Array)) {
throw new Error('bytes must be a Uint8Array');
}
if (specificCharacterSet && typeof specificCharacterSet !== 'string') {
throw new Error('specificCharacterSet must be a string');
}
}
function convertBytesCore(withoutExtensionsFunc, appendFunc, specificCharacterSet, bytes, options) {
checkParameters(specificCharacterSet, bytes);
const characterSetStrings = getCharacterSetStrings(specificCharacterSet);
const checkedOptions = options || {};
const delimiters = getDelimitersForVR(checkedOptions.vr);
if (characterSetStrings.length === 1 && !characterSetStrings[0].startsWith('ISO 2022')) {
return withoutExtensionsFunc(_character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[characterSetStrings[0]].encoding, delimiters, bytes);
}
return convertWithExtensions(characterSetStrings.map(characterSet => _character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[characterSet]), bytes, delimiters, appendFunc);
}
function convertWithExtensions(allowedCharacterSets, bytes, delimiters, appendRun) {
let output = '';
if (!bytes || bytes.length === 0) {
return output;
}
const initialCharacterSets = {
G0: allowedCharacterSets[0].elements.find(element => element.codeElement === 'G0'),
G1: allowedCharacterSets[0].elements.find(element => element.codeElement === 'G1')
};
const activeCharacterSets = Object.assign({}, initialCharacterSets);
let byteRunStart = 0;
let byteRunCharacterSet;
let nextSetIndex = 0;
// Group bytes into runs based on their encoding so we don't have to use a different
// decoder for each character. Note that G0 and G1 planes can be different encodings,
// so we can't just group by character set.
while (nextSetIndex < bytes.length) {
if (!byteRunCharacterSet) {
byteRunCharacterSet = getCharacterSet(bytes[byteRunStart], activeCharacterSets);
}
const next = findNextCharacterSet(bytes, byteRunStart, byteRunCharacterSet, activeCharacterSets, initialCharacterSets, delimiters);
nextSetIndex = next.index;
if (nextSetIndex > byteRunStart) {
output = appendRun(output, byteRunCharacterSet, delimiters, bytes, byteRunStart, nextSetIndex);
}
byteRunStart = nextSetIndex;
byteRunCharacterSet = next.characterSet;
if (next.escapeSequence) {
const nextCharacterSet = readEscapeSequence(bytes, nextSetIndex, allowedCharacterSets);
activeCharacterSets[nextCharacterSet.codeElement] = nextCharacterSet;
byteRunStart += nextCharacterSet.escapeSequence.length;
}
}
return output;
}
function convertWithoutExtensions(encoding, delimiters, bytes) {
const retVal = new TextDecoder(encoding).decode(bytes);
return encoding === 'shift-jis' ? adjustShiftJISResult(delimiters, retVal) : retVal;
}
function convertWithoutExtensionsPromise(encoding, delimiters, bytes) {
return new Promise(resolve => {
const fileReader = new FileReader();
if (encoding === 'shift-jis') {
fileReader.onload = () => resolve(adjustShiftJISResult(delimiters, fileReader.result));
} else {
fileReader.onload = () => resolve(fileReader.result);
}
const blob = new Blob([bytes]);
fileReader.readAsText(blob, encoding);
});
}
// Multibyte non-extension character sets must stand on their own or else be ignored. This method enforces that.
function filterMultiByteCharacterSetStrings(characterSetStrings) {
const initialCharacterSet = _character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[characterSetStrings[0]];
if (initialCharacterSet.multiByte && !initialCharacterSet.extension) {
return [characterSetStrings[0]];
}
return characterSetStrings.filter(str => !_character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[str].multiByte || _character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[str].extension);
}
function findNextCharacterSet(bytes, start, currentCodeElement, activeCodeElements, initialCharacterSets, delimiters) {
for (let i = start; i < bytes.length; i += currentCodeElement.bytesPerCodePoint) {
if (bytes[i] === ESCAPE_BYTE) {
return {
escapeSequence: true,
index: i
};
}
if (currentCodeElement.bytesPerCodePoint === 1 && delimiters.includes(bytes[i])) {
Object.assign(activeCodeElements, initialCharacterSets);
}
const nextCodeElement = getCharacterSet(bytes[i], activeCodeElements);
if (currentCodeElement && nextCodeElement !== currentCodeElement) {
return {
characterSet: nextCodeElement,
index: i
};
}
}
return {
index: bytes.length
};
}
function forceExtensionsIfApplicable(characterSetStrings) {
const forceExtensions = characterSetStrings.length > 1;
const returnValue = [];
for (let i = 0; i < characterSetStrings.length; i++) {
const characterSetString = characterSetStrings[i];
if (!returnValue.includes(characterSetString)) {
returnValue.push(forceExtensions ? characterSetString.replace('ISO_IR', 'ISO 2022 IR') : characterSetString);
}
}
return returnValue;
}
function getCharacterSet(byte, activeCharacterSets) {
if (byte > 0x7F && activeCharacterSets.G1) {
return activeCharacterSets.G1;
}
if (activeCharacterSets.G0) {
return activeCharacterSets.G0;
}
// for robustness if byte <= 0x7F, try to output using G1 if no G0 is selected
if (activeCharacterSets.G1 && activeCharacterSets.G1.bytesPerCodePoint === 1) {
return activeCharacterSets.G1;
}
// If G1 is multibyte, default to ASCII
return _character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets['ISO 2022 IR 6'].elements[0];
}
function getCharacterSetStrings(specificCharacterSet) {
let characterSetStrings = specificCharacterSet ? specificCharacterSet.split('\\').map(characterSet => characterSet.trim().toUpperCase()) : [''];
if (characterSetStrings[0] === '') {
characterSetStrings[0] = characterSetStrings.length > 1 ? 'ISO 2022 IR 6' : 'ISO_IR 6';
}
if (characterSetStrings.some(characterSet => _character_sets_js__WEBPACK_IMPORTED_MODULE_0__.characterSets[characterSet] === undefined)) {
throw new Error('Invalid specific character set specified.');
}
characterSetStrings = filterMultiByteCharacterSetStrings(characterSetStrings);
return forceExtensionsIfApplicable(characterSetStrings);
}
function getDelimitersForVR(incomingVR) {
const vr = (incomingVR || '').trim().toUpperCase();
const delimiters = [CARRIAGE_RETURN, LINE_FEED, FORM_FEED, TAB];
if (!['UT', 'ST', 'LT'].includes(vr)) {
// for delimiting multi-valued items
delimiters.push(BACKSLASH);
}
if (vr === 'PN') {
delimiters.push(EQUAL_SIGN);
delimiters.push(CARET);
}
return delimiters;
}
function preprocessBytes(characterSet, bytes, byteStart, byteEnd) {
let oneEncodingBytes;
if (characterSet.isJISX0212) {
oneEncodingBytes = processJISX0212(bytes, byteStart, byteEnd);
} else {
oneEncodingBytes = new Uint8Array(byteEnd - byteStart);
oneEncodingBytes.set(new Uint8Array(bytes.buffer, bytes.byteOffset + byteStart, byteEnd - byteStart));
if (characterSet.setHighBit) {
setHighBit(oneEncodingBytes);
}
}
return oneEncodingBytes;
}
function processJISX0212(bytes, bytesStart, bytesEnd) {
const length = bytesEnd - bytesStart;
if (length % 2 !== 0) {
throw new Error('JIS X string with a character not having exactly two bytes!');
}
const processedBytes = new Uint8Array(length + length / 2);
let outIndex = 0;
for (let i = bytesStart; i < bytesEnd; i += 2) {
processedBytes[outIndex++] = 0x8F;
processedBytes[outIndex++] = bytes[i] | 0x80;
processedBytes[outIndex++] = bytes[i + 1] | 0x80;
}
return processedBytes;
}
function escapeSequenceMatches(escapeSequence, bytes, startIndex) {
for (let escapeByteIndex = 0; escapeByteIndex < escapeSequence.length; escapeByteIndex++) {
if (startIndex + escapeByteIndex >= bytes.length) {
return false;
} else if (bytes[startIndex + escapeByteIndex] !== escapeSequence[escapeByteIndex]) {
return false;
}
}
return true;
}
function readEscapeSequence(bytes, start, extensionSets) {
for (let setIndex = 0; setIndex < extensionSets.length; setIndex++) {
const extensionSet = extensionSets[setIndex];
for (let elementIndex = 0; elementIndex < extensionSet.elements.length; elementIndex++) {
const element = extensionSet.elements[elementIndex];
if (escapeSequenceMatches(element.escapeSequence, bytes, start)) {
return element;
}
}
}
throw new Error(`Unknown escape sequence encountered at byte ${start}`);
}
function setHighBit(bytes) {
for (let i = 0; i < bytes.length; i++) {
bytes[i] |= 0x80;
}
}
function convertBytes(specificCharacterSet, bytes, options) {
return convertBytesCore(convertWithoutExtensions, appendRunWithoutPromise, specificCharacterSet, bytes, options);
}
function convertBytesPromise(specificCharacterSet, bytes, options) {
return convertBytesCore(convertWithoutExtensionsPromise, appendRunWithPromise, specificCharacterSet, bytes, options);
}
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/*!******************!*\
!*** ./index.js ***!
\******************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ characterSets: () => (/* reexport safe */ _character_sets_js__WEBPACK_IMPORTED_MODULE_1__.characterSets),
/* harmony export */ convertBytes: () => (/* reexport safe */ _convert_bytes_js__WEBPACK_IMPORTED_MODULE_0__.convertBytes),
/* harmony export */ convertBytesPromise: () => (/* reexport safe */ _convert_bytes_js__WEBPACK_IMPORTED_MODULE_0__.convertBytesPromise)
/* harmony export */ });
/* harmony import */ var _convert_bytes_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./convert-bytes.js */ "./convert-bytes.js");
/* harmony import */ var _character_sets_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./character-sets.js */ "./character-sets.js");
})();
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=dicom-character-set.js.map