/*! 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