Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16866a47a0 | ||
|
|
77ab0ad9a1 | ||
|
|
1c306dd243 | ||
|
|
404d52fe5c |
No files matched your search
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.3.4](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.3...@ohif/extension-vtk@1.3.4) (2020-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.2...@ohif/extension-vtk@1.3.3) (2020-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.1...@ohif/extension-vtk@1.3.2) (2020-03-23)
|
## [1.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.3.1...@ohif/extension-vtk@1.3.2) (2020-03-23)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-vtk
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-vtk",
|
"name": "@ohif/extension-vtk",
|
||||||
"version": "1.3.2",
|
"version": "1.3.4",
|
||||||
"description": "OHIF extension for VTK.js",
|
"description": "OHIF extension for VTK.js",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"react-vtkjs-viewport": "^0.8.3"
|
"react-vtkjs-viewport": "^0.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ohif/core": "^2.6.1",
|
"@ohif/core": "^2.6.3",
|
||||||
"@ohif/ui": "^1.4.1",
|
"@ohif/ui": "^1.4.1",
|
||||||
"cornerstone-tools": "4.12.5",
|
"cornerstone-tools": "4.12.5",
|
||||||
"cornerstone-wado-image-loader": "^3.0.0",
|
"cornerstone-wado-image-loader": "^3.0.0",
|
||||||
|
|||||||
@@ -3,6 +3,28 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.6.3](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.2...@ohif/core@2.6.3) (2020-03-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Ensure we take into account pixel spacing fields properly ([#1555](https://github.com/OHIF/Viewers/issues/1555)) ([77ab0ad](https://github.com/OHIF/Viewers/commit/77ab0ad9a14a135b5560741fc1600704df08c141))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.6.2](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.1...@ohif/core@2.6.2) (2020-03-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* OverlayPlane module usage for ArrayBuffer, BulkDataURI, and InlineBinary cases, as well as PaletteColor LUTs for ArrayBuffer (i.e. local drag/drop) case ([#1546](https://github.com/OHIF/Viewers/issues/1546)) ([404d52f](https://github.com/OHIF/Viewers/commit/404d52fe5c0442dd13e4d407bb0687d72fa5f32c))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.6.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.0...@ohif/core@2.6.1) (2020-03-23)
|
## [2.6.1](https://github.com/OHIF/Viewers/compare/@ohif/core@2.6.0...@ohif/core@2.6.1) (2020-03-23)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/core",
|
"name": "@ohif/core",
|
||||||
"version": "2.6.1",
|
"version": "2.6.3",
|
||||||
"description": "Generic business logic for web-based medical imaging applications",
|
"description": "Generic business logic for web-based medical imaging applications",
|
||||||
"author": "OHIF Core Team",
|
"author": "OHIF Core Team",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as dcmjs from 'dcmjs';
|
import * as dcmjs from 'dcmjs';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
import dicomParser from 'dicom-parser';
|
import dicomParser from 'dicom-parser';
|
||||||
import { getFallbackTagFromInstance } from '../utils/metadataProvider/metadataProviderFallbackTags';
|
import getPixelSpacingInformation from '../utils/metadataProvider/getPixelSpacingInformation';
|
||||||
import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';
|
import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData';
|
||||||
import fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';
|
import fetchOverlayData from '../utils/metadataProvider/fetchOverlayData';
|
||||||
|
|
||||||
@@ -58,9 +58,7 @@ class MetadataProvider {
|
|||||||
|
|
||||||
Object.assign(instance, naturalizedDataset);
|
Object.assign(instance, naturalizedDataset);
|
||||||
|
|
||||||
if (options.server) {
|
await this._checkBulkDataAndInlineBinaries(instance, options.server);
|
||||||
await this._checkBulkDataAndInlineBinaries(instance, options.server);
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@@ -163,18 +161,6 @@ class MetadataProvider {
|
|||||||
return instance[naturalizedTagOrWADOImageLoaderTag];
|
return instance[naturalizedTagOrWADOImageLoaderTag];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.fallback) {
|
|
||||||
// Perhaps the tag has fallbacks?
|
|
||||||
const fallbackTag = getFallbackTagFromInstance(
|
|
||||||
naturalizedTagOrWADOImageLoaderTag,
|
|
||||||
instance
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fallbackTag) {
|
|
||||||
return fallbackTag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maybe its a legacy CornerstoneWADOImageLoader tag then:
|
// Maybe its a legacy CornerstoneWADOImageLoader tag then:
|
||||||
return this._getCornerstoneWADOImageLoaderTag(
|
return this._getCornerstoneWADOImageLoaderTag(
|
||||||
naturalizedTagOrWADOImageLoaderTag,
|
naturalizedTagOrWADOImageLoaderTag,
|
||||||
@@ -220,10 +206,9 @@ class MetadataProvider {
|
|||||||
const { ImageOrientationPatient } = instance;
|
const { ImageOrientationPatient } = instance;
|
||||||
|
|
||||||
// Fallback for DX images.
|
// Fallback for DX images.
|
||||||
const PixelSpacing = getFallbackTagFromInstance(
|
// TODO: We should use the rest of the results of this function
|
||||||
'PixelSpacing',
|
// to update the UI somehow
|
||||||
instance
|
const { PixelSpacing } = getPixelSpacingInformation(instance);
|
||||||
);
|
|
||||||
|
|
||||||
let rowPixelSpacing;
|
let rowPixelSpacing;
|
||||||
let columnPixelSpacing;
|
let columnPixelSpacing;
|
||||||
@@ -344,7 +329,7 @@ class MetadataProvider {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case WADO_IMAGE_LOADER_TAGS.OVERLAY_PLANE_MODULE:
|
case WADO_IMAGE_LOADER_TAGS.OVERLAY_PLANE_MODULE:
|
||||||
metadata = [];
|
const overlays = [];
|
||||||
|
|
||||||
for (
|
for (
|
||||||
let overlayGroup = 0x00;
|
let overlayGroup = 0x00;
|
||||||
@@ -389,9 +374,13 @@ class MetadataProvider {
|
|||||||
roiStandardDeviation: instance[ROIStandardDeviationTag],
|
roiStandardDeviation: instance[ROIStandardDeviationTag],
|
||||||
};
|
};
|
||||||
|
|
||||||
metadata.push(overlay);
|
overlays.push(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
overlays
|
||||||
|
};
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WADO_IMAGE_LOADER_TAGS.PATIENT_MODULE:
|
case WADO_IMAGE_LOADER_TAGS.PATIENT_MODULE:
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { api } from 'dicomweb-client';
|
import { api } from 'dicomweb-client';
|
||||||
import DICOMWeb from '../../DICOMWeb';
|
import DICOMWeb from '../../DICOMWeb';
|
||||||
|
import str2ab from '../str2ab';
|
||||||
|
import unpackOverlay from './unpackOverlay';
|
||||||
|
|
||||||
export default async function fetchOverlayData(instance, server) {
|
export default async function fetchOverlayData(instance, server) {
|
||||||
const OverlayDataPromises = [];
|
const OverlayDataPromises = [];
|
||||||
@@ -15,11 +17,18 @@ export default async function fetchOverlayData(instance, server) {
|
|||||||
|
|
||||||
const OverlayDataTag = `${groupStr}3000`;
|
const OverlayDataTag = `${groupStr}3000`;
|
||||||
|
|
||||||
if (instance[OverlayDataTag] && instance[OverlayDataTag].BulkDataURI) {
|
if (instance[OverlayDataTag] && instance[OverlayDataTag].InlineBinary) {
|
||||||
|
const inlineBinaryData = atob(instance[OverlayDataTag].InlineBinary);
|
||||||
|
const arraybuffer = str2ab(inlineBinaryData);
|
||||||
|
|
||||||
|
instance[OverlayDataTag] = unpackOverlay(arraybuffer)
|
||||||
|
} else if (instance[OverlayDataTag] && instance[OverlayDataTag].BulkDataURI) {
|
||||||
OverlayDataPromises.push(
|
OverlayDataPromises.push(
|
||||||
_getOverlayData(instance[OverlayDataTag], server)
|
_getOverlayData(instance[OverlayDataTag], server)
|
||||||
);
|
);
|
||||||
OverlayDataTags.push(OverlayDataTag);
|
OverlayDataTags.push(OverlayDataTag);
|
||||||
|
} else if (instance[OverlayDataTag] && instance[OverlayDataTag] instanceof ArrayBuffer) {
|
||||||
|
instance[OverlayDataTag] = unpackOverlay(instance[OverlayDataTag])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,19 +69,7 @@ async function _getOverlayData(tag, server) {
|
|||||||
return dicomWeb
|
return dicomWeb
|
||||||
.retrieveBulkData(options)
|
.retrieveBulkData(options)
|
||||||
.then(result => result[0])
|
.then(result => result[0])
|
||||||
.then(_unpackOverlay);
|
.then(unpackOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _unpackOverlay(arrayBuffer) {
|
|
||||||
const bitArray = new Uint8Array(arrayBuffer);
|
|
||||||
const byteArray = new Uint8Array(8 * bitArray.length);
|
|
||||||
|
|
||||||
for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {
|
|
||||||
const bitIndex = byteIndex % 8;
|
|
||||||
const bitByteIndex = Math.floor(byteIndex / 8);
|
|
||||||
byteArray[byteIndex] =
|
|
||||||
1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return byteArray;
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { api } from 'dicomweb-client';
|
import { api } from 'dicomweb-client';
|
||||||
import DICOMWeb from '../../DICOMWeb';
|
import DICOMWeb from '../../DICOMWeb';
|
||||||
|
import str2ab from '../str2ab';
|
||||||
|
|
||||||
export default async function fetchPaletteColorLookupTableData(
|
export default async function fetchPaletteColorLookupTableData(
|
||||||
instance,
|
instance,
|
||||||
@@ -157,31 +158,12 @@ function _getPaletteColor(server, paletteColorLookupTableData, lutDescriptor) {
|
|||||||
.then(arrayBufferToPaletteColorLUT);
|
.then(arrayBufferToPaletteColorLUT);
|
||||||
} else if (paletteColorLookupTableData.InlineBinary) {
|
} else if (paletteColorLookupTableData.InlineBinary) {
|
||||||
const inlineBinaryData = atob(paletteColorLookupTableData.InlineBinary);
|
const inlineBinaryData = atob(paletteColorLookupTableData.InlineBinary);
|
||||||
const arraybuffer = _str2ab(inlineBinaryData);
|
const arraybuffer = str2ab(inlineBinaryData);
|
||||||
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
resolve(arrayBufferToPaletteColorLUT(arraybuffer));
|
resolve(arrayBufferToPaletteColorLUT(arraybuffer));
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(arrayBufferToPaletteColorLUT(paletteColorLookupTableData));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(
|
|
||||||
'Palette Color LUT was not provided as InlineBinary or BulkDataURI'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert String to ArrayBuffer
|
|
||||||
*
|
|
||||||
* @param {String} str Input String
|
|
||||||
* @return {ArrayBuffer} Output converted ArrayBuffer
|
|
||||||
*/
|
|
||||||
function _str2ab(str) {
|
|
||||||
const strLen = str.length;
|
|
||||||
const bytes = new Uint8Array(strLen);
|
|
||||||
|
|
||||||
for (let i = 0; i < strLen; i++) {
|
|
||||||
bytes[i] = str.charCodeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes.buffer;
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import log from '../../log';
|
||||||
|
|
||||||
|
export default function getPixelSpacingInformation(instance) {
|
||||||
|
// See http://gdcm.sourceforge.net/wiki/index.php/Imager_Pixel_Spacing
|
||||||
|
|
||||||
|
// TODO: Add Ultrasound region spacing
|
||||||
|
// TODO: Add manual calibration
|
||||||
|
|
||||||
|
// TODO: Use ENUMS from dcmjs
|
||||||
|
const projectionRadiographSOPClassUIDs = [
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1', // CR Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.1', // Digital X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.1.1', // Digital X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.2', // Digital Mammography X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.2.1', // Digital Mammography X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.3', // Digital Intra – oral X-Ray Image Storage – for Presentation
|
||||||
|
'1.2.840.10008.5.1.4.1.1.1.3.1', // Digital Intra – oral X-Ray Image Storage – for Processing
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.1', // X-Ray Angiographic Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.1.1', // Enhanced XA Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.2', // X-Ray Radiofluoroscopic Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.2.1', // Enhanced XRF Image Storage
|
||||||
|
'1.2.840.10008.5.1.4.1.1.12.3' // X-Ray Angiographic Bi-plane Image Storage Retired
|
||||||
|
];
|
||||||
|
|
||||||
|
const { PixelSpacing, ImagerPixelSpacing, SOPClassUID, PixelSpacingCalibrationType, PixelSpacingCalibrationDescription, EstimatedRadiographicMagnificationFactor } = instance;
|
||||||
|
const isProjection = projectionRadiographSOPClassUIDs.includes(SOPClassUID);
|
||||||
|
|
||||||
|
const TYPES = {
|
||||||
|
NOT_APPLICABLE: 'NOT_APPLICABLE',
|
||||||
|
UNKNOWN: 'UNKNOWN',
|
||||||
|
CALIBRATED: 'CALIBRATED',
|
||||||
|
DETECTOR: 'DETECTOR'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isProjection === false && !ImagerPixelSpacing) {
|
||||||
|
// If only Pixel Spacing is present, and this is not a projection radiograph,
|
||||||
|
// we can stop here
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.NOT_APPLICABLE,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (isProjection && !ImagerPixelSpacing) {
|
||||||
|
// If only Pixel Spacing is present, and this is a projection radiograph,
|
||||||
|
// PixelSpacing should be used, but the user should be informed that
|
||||||
|
// what it means is unknown
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.UNKNOWN,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing === ImagerPixelSpacing) {
|
||||||
|
// If Imager Pixel Spacing and Pixel Spacing are present and they have the same values,
|
||||||
|
// then the user should be informed that the measurements are at the detector plane
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.DETECTOR,
|
||||||
|
isProjection
|
||||||
|
};
|
||||||
|
} else if (PixelSpacing && ImagerPixelSpacing && PixelSpacing !== ImagerPixelSpacing) {
|
||||||
|
// If Imager Pixel Spacing and Pixel Spacing are present and they have different values,
|
||||||
|
// then the user should be informed that these are "calibrated"
|
||||||
|
// (in some unknown manner if Pixel Spacing Calibration Type and/or
|
||||||
|
// Pixel Spacing Calibration Description are absent)
|
||||||
|
return {
|
||||||
|
PixelSpacing,
|
||||||
|
type: TYPES.CALIBRATED,
|
||||||
|
isProjection,
|
||||||
|
PixelSpacingCalibrationType,
|
||||||
|
PixelSpacingCalibrationDescription
|
||||||
|
};
|
||||||
|
} else if (!PixelSpacing && ImagerPixelSpacing) {
|
||||||
|
let CorrectedImagerPixelSpacing = ImagerPixelSpacing;
|
||||||
|
if (EstimatedRadiographicMagnificationFactor) {
|
||||||
|
// Note that in IHE Mammo profile compliant displays, the value of Imager Pixel Spacing is required to be corrected by
|
||||||
|
// Estimated Radiographic Magnification Factor and the user informed of that.
|
||||||
|
// TODO: should this correction be done before all of this logic?
|
||||||
|
CorrectedImagerPixelSpacing = ImagerPixelSpacing.map(pixelSpacing => pixelSpacing / EstimatedRadiographicMagnificationFactor);
|
||||||
|
} else {
|
||||||
|
log.info('EstimatedRadiographicMagnificationFactor was not present. Unable to correct ImagerPixelSpacing.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
PixelSpacing: CorrectedImagerPixelSpacing,
|
||||||
|
isProjection,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('Unknown combination of PixelSpacing and ImagerPixelSpacing identified. Unable to determine spacing.');
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import log from '../../log';
|
|
||||||
|
|
||||||
function getFallbackTagFromInstance(tag, instance) {
|
|
||||||
if (instance[tag]) {
|
|
||||||
return instance[tag];
|
|
||||||
}
|
|
||||||
|
|
||||||
const fallbackTags = fallbackTagsMap[tag];
|
|
||||||
|
|
||||||
if (fallbackTags) {
|
|
||||||
for (let i = 0; i < fallbackTags.length; i++) {
|
|
||||||
const fallbackTag = fallbackTags[i];
|
|
||||||
|
|
||||||
if (instance[fallbackTag]) {
|
|
||||||
log.info(`metadata provider fallback tag ${tag} to ${fallbackTag}`);
|
|
||||||
|
|
||||||
return instance[fallbackTag];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fallbackTagsMap = {
|
|
||||||
PixelSpacing: ['ImagerPixelSpacing'],
|
|
||||||
};
|
|
||||||
|
|
||||||
export { fallbackTagsMap, getFallbackTagFromInstance };
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export default function unpackOverlay(arrayBuffer) {
|
||||||
|
const bitArray = new Uint8Array(arrayBuffer);
|
||||||
|
const byteArray = new Uint8Array(8 * bitArray.length);
|
||||||
|
|
||||||
|
for (let byteIndex = 0; byteIndex < byteArray.length; byteIndex++) {
|
||||||
|
const bitIndex = byteIndex % 8;
|
||||||
|
const bitByteIndex = Math.floor(byteIndex / 8);
|
||||||
|
byteArray[byteIndex] =
|
||||||
|
1 * ((bitArray[bitByteIndex] & (1 << bitIndex)) >> bitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Convert String to ArrayBuffer
|
||||||
|
*
|
||||||
|
* @param {String} str Input String
|
||||||
|
* @return {ArrayBuffer} Output converted ArrayBuffer
|
||||||
|
*/
|
||||||
|
export default function str2ab(str) {
|
||||||
|
const strLen = str.length;
|
||||||
|
const bytes = new Uint8Array(strLen);
|
||||||
|
|
||||||
|
for (let i = 0; i < strLen; i++) {
|
||||||
|
bytes[i] = str.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.buffer;
|
||||||
|
}
|
||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [3.8.7](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.6...@ohif/viewer@3.8.7) (2020-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.8.6](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.5...@ohif/viewer@3.8.6) (2020-03-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [3.8.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.4...@ohif/viewer@3.8.5) (2020-03-23)
|
## [3.8.5](https://github.com/OHIF/Viewers/compare/@ohif/viewer@3.8.4...@ohif/viewer@3.8.5) (2020-03-23)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/viewer",
|
"name": "@ohif/viewer",
|
||||||
"version": "3.8.5",
|
"version": "3.8.7",
|
||||||
"description": "OHIF Viewer",
|
"description": "OHIF Viewer",
|
||||||
"author": "OHIF Contributors",
|
"author": "OHIF Contributors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -48,14 +48,14 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"@ohif/core": "^2.6.1",
|
"@ohif/core": "^2.6.3",
|
||||||
"@ohif/extension-cornerstone": "^2.5.0",
|
"@ohif/extension-cornerstone": "^2.5.0",
|
||||||
"@ohif/extension-dicom-html": "^1.1.1",
|
"@ohif/extension-dicom-html": "^1.1.1",
|
||||||
"@ohif/extension-dicom-microscopy": "^0.50.7",
|
"@ohif/extension-dicom-microscopy": "^0.50.7",
|
||||||
"@ohif/extension-dicom-pdf": "^1.0.2",
|
"@ohif/extension-dicom-pdf": "^1.0.2",
|
||||||
"@ohif/extension-dicom-segmentation": "^0.1.0",
|
"@ohif/extension-dicom-segmentation": "^0.1.0",
|
||||||
"@ohif/extension-lesion-tracker": "^0.2.0",
|
"@ohif/extension-lesion-tracker": "^0.2.0",
|
||||||
"@ohif/extension-vtk": "^1.3.2",
|
"@ohif/extension-vtk": "^1.3.4",
|
||||||
"@ohif/i18n": "^0.52.7",
|
"@ohif/i18n": "^0.52.7",
|
||||||
"@ohif/ui": "^1.4.1",
|
"@ohif/ui": "^1.4.1",
|
||||||
"@tanem/react-nprogress": "^1.1.25",
|
"@tanem/react-nprogress": "^1.1.25",
|
||||||
|
|||||||
Reference in new issue
Block a user