custom-cornerstone-tools
Version:
Medical imaging tools for the Cornerstone library - customized for DrNuvem
1,434 lines (1,102 loc) • 242 kB
JavaScript
/*! cornerstone-core - 1.1.3 - 2017-11-17 | (c) 2016 Chris Hafey | https://github.com/chafey/cornerstone */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("cornerstone-core", [], factory);
else if(typeof exports === 'object')
exports["cornerstone-core"] = factory();
else
root["cornerstone"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 41);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getEnabledElement = getEnabledElement;
exports.addEnabledElement = addEnabledElement;
exports.getEnabledElementsByImageId = getEnabledElementsByImageId;
exports.getEnabledElements = getEnabledElements;
var enabledElements = [];
/**
* A two-dimensional vector
*
* @typedef {Object} vec2
* @param {Number} x - The x distance
* @param {Number} y - The y distance
*/
/**
* VOI
*
* @typedef {Object} VOI
* @param {Number} windowWidth - Window Width for display
* @param {Number} windowCenter - Window Center for display
*/
/**
* Lookup Table Array
*
* @typedef {Object} LUT
* @property {Number} firstValueMapped
* @property {Number} numBitsPerEntry
* @property {Array} lut
*/
/**
* Image Statistics Object
*
* @typedef {Object} ImageStats
*
* @property {Number} [lastGetPixelDataTime] The time in ms taken to retrieve stored pixels required to draw the image
* @property {Number} [lastStoredPixelDataToCanvasImageDataTime] The time in ms taken to map from stored pixel array to canvas pixel array
* @property {Number} [lastPutImageDataTime] The time in ms taken for putImageData to put the canvas pixel data into the canvas context
* @property {Number} [lastRenderTime] The total time in ms taken for the entire rendering function to run
* @property {Number} [lastLutGenerateTime] The time in ms taken to generate the lookup table for the image
*/
/**
* An Image Object in Cornerstone
*
* @typedef {Object} Image
*
* @property {string} imageId - The imageId associated with this image object
* @property {Number} minPixelValue - the minimum stored pixel value in the image
* @property {Number} maxPixelValue - the maximum stored pixel value in the image
* @property {Number} slope - the rescale slope to convert stored pixel values to modality pixel values or 1 if not specified
* @property {Number} intercept - the rescale intercept used to convert stored pixel values to modality values or 0 if not specified
* @property {Number} windowCenter - the default windowCenter to apply to the image
* @property {Number} windowWidth - the default windowWidth to apply to the image
* @property {function} getPixelData - a function that returns the underlying pixel data. An array of integers for grayscale and an array of RGBA for color
* @property {function} getImageData - a function that returns a canvas imageData object for the image. This is only needed for color images
* @property {function} getCanvas - a function that returns a canvas element with the image loaded into it. This is only needed for color images.
* @property {function} getImage - a function that returns a JavaScript Image object with the image data. This is optional and typically used for images encoded in standard web JPEG and PNG formats
* @property {Number} rows - number of rows in the image. This is the same as height but duplicated for convenience
* @property {Number} columns - number of columns in the image. This is the same as width but duplicated for convenience
* @property {Number} height - the height of the image. This is the same as rows but duplicated for convenience
* @property {Number} width - the width of the image. This is the same as columns but duplicated for convenience
* @property {Boolean} color - true if pixel data is RGB, false if grayscale
* @property {Object} lut - The Lookup Table
* @property {Boolean} rgba - Is the color pixel data stored in RGBA?
* @property {Number} columnPixelSpacing - horizontal distance between the middle of each pixel (or width of each pixel) in mm or undefined if not known
* @property {Number} rowPixelSpacing - vertical distance between the middle of each pixel (or heigh of each pixel) in mm or undefined if not known
* @property {Boolean} invert - true if the the image should initially be displayed be inverted, false if not. This is here mainly to support DICOM images with a photometric interpretation of MONOCHROME1
* @property {Number} sizeInBytes - the number of bytes used to store the pixels for this image.
* @property {Boolean} [falseColor=false] - Whether or not the image has undergone false color mapping
* @property {Array} [origPixelData] - Original pixel data for an image after it has undergone false color mapping
* @property {ImageStats} [stats] - Statistics for the last redraw of the image
* @property {Object} cachedLut - Cached Lookup Table for this image.
* @property {String|Colormap} [colormap] - an optional colormap ID or colormap object (from colors/colormap.js). This will be applied during rendering to convert the image to pseudocolor
* @property {Boolean} [labelmap=false] - whether or not to render this image as a label map (i.e. skip modality and VOI LUT pipelines and use only a color lookup table)
*/
/**
* A Viewport Settings Object Cornerstone
*
* @typedef {Object} Viewport
*
* @property {Number} [scale=1.0] - The scale applied to the image. A scale of 1.0 will display no zoom (one image pixel takes up one screen pixel). A scale of 2.0 will be double zoom and a scale of .5 will be zoomed out by 2x
* @param {vec2} [translation] - An object with properties x and y which describe the translation to apply in the pixel coordinate system. Note that the image is initially displayed centered in the enabled element with a x and y translation of 0 and 0 respectively.
* @param {VOI} [voi] - an object with properties windowWidth and windowCenter.
* @property {boolean} [invert=false] - Whether or not the image is inverted.
* @property {boolean} [pixelReplication=false] - true if the image smooth / interpolation should be used when zoomed in on the image or false if pixel replication should be used.
* @property {boolean} [hflip=false] - true if the image is flipped horizontally. Default is false
* @property {boolean} [vflip=false] - true if the image is flipped vertically. Default is false
* @property {Number} [rotation=0] - the rotation of the image (90 degree increments). Default is 0
* @property {LUT} [modalityLUT] - the modality LUT to apply or undefined if none
* @property {LUT} [voiLUT] - the modality LUT to apply or undefined if none
* @property {String|Colormap} [colormap] - an optional colormap ID or colormap object (from colors/colormap.js). This will be applied during rendering to convert the image to pseudocolor
* @property {Boolean} [labelmap=false] - whether or not to render this image as a label map (i.e. skip modality and VOI LUT pipelines and use only a color lookup table)
*/
/**
* An Enabled Element in Cornerstone
*
* @typedef {Object} EnabledElement
*
* @property {HTMLElement} element - The DOM element which has been enabled for use by Cornerstone
* @property {Image} [image] - The image currently displayed in the enabledElement
* @property {Viewport} [viewport] - The current viewport settings of the enabledElement
* @property {HTMLCanvasElement} [canvas] - The current canvas for this enabledElement
* @property {Boolean} invalid - Whether or not the image pixel data underlying the enabledElement has been changed, necessitating a redraw
* @property {Boolean} needsRedraw - A flag for triggering a redraw of the canvas without re-retrieving the pixel data, since it remains valid
* @property {EnabledElementLayer[]} [layers] - The layers that have been added to the enabledElement
* @property {Boolean} [syncViewports] - Whether or not to synchronize the viewport parameters
* for each of the enabled element's layers
* @property {Boolean} [lastSyncViewportsState] - The previous state for the sync viewport boolean
*/
/**
* An Enabled Element Layer in Cornerstone
*
* @typedef {Object} EnabledElementLayer
*
* @property {HTMLElement} element - The DOM element which has been enabled for use by Cornerstone
* @property {Image} [image] - The image currently displayed in the enabledElement
* @property {Viewport} [viewport] - The current viewport settings of the enabledElement
* @property {HTMLCanvasElement} [canvas] - The current canvas for this enabledElement
* @property {Object} [options] - Layer drawing options
* @property {Boolean} invalid - Whether or not the image pixel data underlying the enabledElement has been changed, necessitating a redraw
* @property {Boolean} needsRedraw - A flag for triggering a redraw of the canvas without re-retrieving the pixel data, since it remains valid
*/
/**
* Retrieves a Cornerstone Enabled Element object
*
* @param {HTMLElement} element An HTML Element enabled for Cornerstone
*
* @returns {EnabledElement} A Cornerstone Enabled Element
*/
function getEnabledElement(element) {
if (element === undefined) {
throw new Error('getEnabledElement: parameter element must not be undefined');
}
for (var i = 0; i < enabledElements.length; i++) {
if (enabledElements[i].element === element) {
return enabledElements[i];
}
}
throw new Error('element not enabled');
}
/**
* Adds a Cornerstone Enabled Element object to the central store of enabledElements
*
* @param {EnabledElement} enabledElement A Cornerstone enabledElement Object
* @returns {void}
*/
function addEnabledElement(enabledElement) {
if (enabledElement === undefined) {
throw new Error('getEnabledElement: enabledElement element must not be undefined');
}
enabledElements.push(enabledElement);
}
/**
* Adds a Cornerstone Enabled Element object to the central store of enabledElements
*
* @param {string} imageId A Cornerstone Image ID
* @returns {EnabledElement[]} An Array of Cornerstone enabledElement Objects
*/
function getEnabledElementsByImageId(imageId) {
var ees = [];
enabledElements.forEach(function (enabledElement) {
if (enabledElement.image && enabledElement.image.imageId === imageId) {
ees.push(enabledElement);
}
});
return ees;
}
/**
* Retrieve all of the currently enabled Cornerstone elements
*
* @return {EnabledElement[]} An Array of Cornerstone enabledElement Objects
*/
function getEnabledElements() {
return enabledElements;
}
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function () {
if (window.performance) {
return performance.now();
}
return Date.now();
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = triggerEvent;
var _externalModules = __webpack_require__(33);
/**
* Trigger a CustomEvent
*
* @param {EventTarget} el The element or EventTarget to trigger the event upon
* @param {String} type The event type name
* @param {Object|null} detail=null The event data to be sent
* @returns {void}
*/
function triggerEvent(el, type) {
var detail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var event = void 0;
// This check is needed to polyfill CustomEvent on IE11-
if (typeof window.CustomEvent === 'function') {
event = new CustomEvent(type.toLocaleLowerCase(), { detail: detail });
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type.toLocaleLowerCase(), true, true, detail);
}
// TODO: remove jQuery event triggers
_externalModules.external.$(el).trigger(type, detail);
el.dispatchEvent(event);
}
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement, context, scale) {
if (enabledElement === undefined) {
throw new Error('setToPixelCoordinateSystem: parameter enabledElement must not be undefined');
}
if (context === undefined) {
throw new Error('setToPixelCoordinateSystem: parameter context must not be undefined');
}
var transform = (0, _calculateTransform2.default)(enabledElement, scale);
context.setTransform(transform.m[0], transform.m[1], transform.m[2], transform.m[3], transform.m[4], transform.m[5]);
};
var _calculateTransform = __webpack_require__(22);
var _calculateTransform2 = _interopRequireDefault(_calculateTransform);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (element) {
var invalidated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var enabledElement = (0, _enabledElements.getEnabledElement)(element);
if (enabledElement.image === undefined && !enabledElement.layers.length) {
throw new Error('updateImage: image has not been loaded yet');
}
(0, _drawImage2.default)(enabledElement, invalidated);
};
var _enabledElements = __webpack_require__(0);
var _drawImage = __webpack_require__(5);
var _drawImage2 = _interopRequireDefault(_drawImage);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement) {
var invalidated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
enabledElement.needsRedraw = true;
if (invalidated) {
enabledElement.invalid = true;
}
};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (canvas, image) {
if (canvas === undefined) {
throw new Error('getDefaultViewport: parameter canvas must not be undefined');
}
if (image === undefined) {
return {
scale: 1,
translation: {
x: 0,
y: 0
},
voi: {
windowWidth: undefined,
windowCenter: undefined
},
invert: false,
pixelReplication: false,
rotation: 0,
hflip: false,
vflip: false,
modalityLUT: undefined,
voiLUT: undefined,
colormap: undefined,
labelmap: false
};
}
// Fit image to window
var verticalScale = canvas.height / image.rows;
var horizontalScale = canvas.width / image.columns;
var scale = Math.min(horizontalScale, verticalScale);
return {
scale: scale,
translation: {
x: 0,
y: 0
},
voi: {
windowWidth: image.windowWidth,
windowCenter: image.windowCenter
},
invert: image.invert,
pixelReplication: false,
rotation: 0,
hflip: false,
vflip: false,
modalityLUT: image.modalityLUT,
voiLUT: image.voiLUT,
colormap: image.colormap,
labelmap: Boolean(image.labelmap)
};
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _colormap = __webpack_require__(27);
var _lookupTable = __webpack_require__(28);
var _lookupTable2 = _interopRequireDefault(_lookupTable);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = {
getColormap: _colormap.getColormap,
getColormapsList: _colormap.getColormapsList,
LookupTable: _lookupTable2.default
};
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.renderColorImage = renderColorImage;
exports.addColorLayer = addColorLayer;
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
var _generateLut = __webpack_require__(9);
var _generateLut2 = _interopRequireDefault(_generateLut);
var _storedColorPixelDataToCanvasImageData = __webpack_require__(19);
var _storedColorPixelDataToCanvasImageData2 = _interopRequireDefault(_storedColorPixelDataToCanvasImageData);
var _storedRGBAPixelDataToCanvasImageData = __webpack_require__(45);
var _storedRGBAPixelDataToCanvasImageData2 = _interopRequireDefault(_storedRGBAPixelDataToCanvasImageData);
var _setToPixelCoordinateSystem = __webpack_require__(3);
var _setToPixelCoordinateSystem2 = _interopRequireDefault(_setToPixelCoordinateSystem);
var _index = __webpack_require__(14);
var _index2 = _interopRequireDefault(_index);
var _doesImageNeedToBeRendered = __webpack_require__(13);
var _doesImageNeedToBeRendered2 = _interopRequireDefault(_doesImageNeedToBeRendered);
var _initializeRenderCanvas = __webpack_require__(11);
var _initializeRenderCanvas2 = _interopRequireDefault(_initializeRenderCanvas);
var _saveLastRendered = __webpack_require__(12);
var _saveLastRendered2 = _interopRequireDefault(_saveLastRendered);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getLut(image, viewport) {
// If we have a cached lut and it has the right values, return it immediately
if (image.cachedLut !== undefined && image.cachedLut.windowCenter === viewport.voi.windowCenter && image.cachedLut.windowWidth === viewport.voi.windowWidth && image.cachedLut.invert === viewport.invert) {
return image.cachedLut.lutArray;
}
// Lut is invalid or not present, regenerate it and cache it
(0, _generateLut2.default)(image, viewport.voi.windowWidth, viewport.voi.windowCenter, viewport.invert);
image.cachedLut.windowWidth = viewport.voi.windowWidth;
image.cachedLut.windowCenter = viewport.voi.windowCenter;
image.cachedLut.invert = viewport.invert;
return image.cachedLut.lutArray;
} /**
* This module is responsible for drawing an image to an enabled elements canvas element
*/
function getRenderCanvas(enabledElement, image, invalidated) {
if (!enabledElement.renderingTools.renderCanvas) {
enabledElement.renderingTools.renderCanvas = document.createElement('canvas');
}
var renderCanvas = enabledElement.renderingTools.renderCanvas;
// The ww/wc is identity and not inverted - get a canvas with the image rendered into it for
// Fast drawing
if (enabledElement.viewport.voi.windowWidth === 255 && enabledElement.viewport.voi.windowCenter === 128 && enabledElement.viewport.invert === false && image.getCanvas && image.getCanvas()) {
return image.getCanvas();
}
// Apply the lut to the stored pixel data onto the render canvas
if ((0, _doesImageNeedToBeRendered2.default)(enabledElement, image) === false && invalidated !== true) {
return renderCanvas;
}
// If our render canvas does not match the size of this image reset it
// NOTE: This might be inefficient if we are updating multiple images of different
// Sizes frequently.
if (renderCanvas.width !== image.width || renderCanvas.height !== image.height) {
(0, _initializeRenderCanvas2.default)(enabledElement, image);
}
// Get the lut to use
var start = (0, _now2.default)();
var colorLut = getLut(image, enabledElement.viewport);
image.stats = image.stats || {};
image.stats.lastLutGenerateTime = (0, _now2.default)() - start;
var renderCanvasData = enabledElement.renderingTools.renderCanvasData;
var renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;
// The color image voi/invert has been modified - apply the lut to the underlying
// Pixel data and put it into the renderCanvas
if (image.rgba) {
(0, _storedRGBAPixelDataToCanvasImageData2.default)(image, colorLut, renderCanvasData.data);
} else {
(0, _storedColorPixelDataToCanvasImageData2.default)(image, colorLut, renderCanvasData.data);
}
start = (0, _now2.default)();
renderCanvasContext.putImageData(renderCanvasData, 0, 0);
image.stats.lastPutImageDataTime = (0, _now2.default)() - start;
return renderCanvas;
}
/**
* API function to render a color image to an enabled element
*
* @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw
* @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used
* @returns {void}
*/
function renderColorImage(enabledElement, invalidated) {
if (enabledElement === undefined) {
throw new Error('renderColorImage: enabledElement parameter must not be undefined');
}
var image = enabledElement.image;
if (image === undefined) {
throw new Error('renderColorImage: image must be loaded before it can be drawn');
}
// Get the canvas context and reset the transform
var context = enabledElement.canvas.getContext('2d');
context.setTransform(1, 0, 0, 1, 0, 0);
// Clear the canvas
context.fillStyle = 'black';
context.fillRect(0, 0, enabledElement.canvas.width, enabledElement.canvas.height);
// Turn off image smooth/interpolation if pixelReplication is set in the viewport
context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;
context.mozImageSmoothingEnabled = context.imageSmoothingEnabled;
// Save the canvas context state and apply the viewport properties
(0, _setToPixelCoordinateSystem2.default)(enabledElement, context);
var renderCanvas = void 0;
if (enabledElement.options && enabledElement.options.renderer && enabledElement.options.renderer.toLowerCase() === 'webgl') {
// If this enabled element has the option set for WebGL, we should
// User it as our renderer.
renderCanvas = _index2.default.renderer.render(enabledElement);
} else {
// If no options are set we will retrieve the renderCanvas through the
// Normal Canvas rendering path
renderCanvas = getRenderCanvas(enabledElement, image, invalidated);
}
context.drawImage(renderCanvas, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
enabledElement.renderingTools = (0, _saveLastRendered2.default)(enabledElement);
}
function addColorLayer(layer, invalidated) {
if (layer === undefined) {
throw new Error('addColorLayer: layer parameter must not be undefined');
}
var image = layer.image;
if (image === undefined) {
throw new Error('addColorLayer: image must be loaded before it can be drawn');
}
// All multi-layer images should include the alpha value
image.rgba = true;
layer.canvas = getRenderCanvas(layer, image, invalidated);
var context = layer.canvas.getContext('2d');
// Turn off image smooth/interpolation if pixelReplication is set in the viewport
context.imageSmoothingEnabled = !layer.viewport.pixelReplication;
context.mozImageSmoothingEnabled = context.imageSmoothingEnabled;
layer.renderingTools = (0, _saveLastRendered2.default)(layer);
}
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (image, windowWidth, windowCenter, invert, modalityLUT, voiLUT) {
var maxPixelValue = image.maxPixelValue;
var minPixelValue = image.minPixelValue;
var offset = Math.min(minPixelValue, 0);
if (image.cachedLut === undefined) {
var length = maxPixelValue - offset + 1;
image.cachedLut = {};
image.cachedLut.lutArray = new Uint8ClampedArray(length);
}
var lut = image.cachedLut.lutArray;
var mlutfn = (0, _getModalityLUT2.default)(image.slope, image.intercept, modalityLUT);
var vlutfn = (0, _getVOILut2.default)(windowWidth, windowCenter, voiLUT);
if (invert === true) {
for (var storedValue = minPixelValue; storedValue <= maxPixelValue; storedValue++) {
lut[storedValue + -offset] = 255 - vlutfn(mlutfn(storedValue));
}
} else {
for (var _storedValue = minPixelValue; _storedValue <= maxPixelValue; _storedValue++) {
lut[_storedValue + -offset] = vlutfn(mlutfn(_storedValue));
}
}
return lut;
};
var _getModalityLUT = __webpack_require__(26);
var _getModalityLUT2 = _interopRequireDefault(_getModalityLUT);
var _getVOILut = __webpack_require__(42);
var _getVOILut2 = _interopRequireDefault(_getVOILut);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement) {
// For now we will calculate it every time it is requested.
// In the future, we may want to cache it in the enabled element to speed things up.
return (0, _calculateTransform2.default)(enabledElement);
};
var _calculateTransform = __webpack_require__(22);
var _calculateTransform2 = _interopRequireDefault(_calculateTransform);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement, image) {
var renderCanvas = enabledElement.renderingTools.renderCanvas;
// Resize the canvas
renderCanvas.width = image.width;
renderCanvas.height = image.height;
var canvasContext = renderCanvas.getContext('2d');
// NOTE - we need to fill the render canvas with white pixels since we
// control the luminance using the alpha channel to improve rendering performance.
canvasContext.fillStyle = 'white';
canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height);
var renderCanvasData = canvasContext.getImageData(0, 0, image.width, image.height);
enabledElement.renderingTools.renderCanvasContext = canvasContext;
enabledElement.renderingTools.renderCanvasData = renderCanvasData;
};
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement) {
var imageId = enabledElement.image.imageId;
var viewport = enabledElement.viewport;
enabledElement.renderingTools.lastRenderedImageId = imageId;
enabledElement.renderingTools.lastRenderedViewport = {
windowCenter: viewport.voi.windowCenter,
windowWidth: viewport.voi.windowWidth,
invert: viewport.invert,
rotation: viewport.rotation,
hflip: viewport.hflip,
vflip: viewport.vflip,
modalityLUT: viewport.modalityLUT,
voiLUT: viewport.voiLUT,
colormap: viewport.colormap
};
return enabledElement.renderingTools;
};
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (enabledElement, image) {
var lastRenderedImageId = enabledElement.renderingTools.lastRenderedImageId;
var lastRenderedViewport = enabledElement.renderingTools.lastRenderedViewport;
return image.imageId !== lastRenderedImageId || !lastRenderedViewport || lastRenderedViewport.windowCenter !== enabledElement.viewport.voi.windowCenter || lastRenderedViewport.windowWidth !== enabledElement.viewport.voi.windowWidth || lastRenderedViewport.invert !== enabledElement.viewport.invert || lastRenderedViewport.rotation !== enabledElement.viewport.rotation || lastRenderedViewport.hflip !== enabledElement.viewport.hflip || lastRenderedViewport.vflip !== enabledElement.viewport.vflip || lastRenderedViewport.modalityLUT !== enabledElement.viewport.modalityLUT || lastRenderedViewport.voiLUT !== enabledElement.viewport.voiLUT || lastRenderedViewport.colormap !== enabledElement.viewport.colormap;
};
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _renderer = __webpack_require__(46);
var _createProgramFromString = __webpack_require__(34);
var _createProgramFromString2 = _interopRequireDefault(_createProgramFromString);
var _textureCache = __webpack_require__(32);
var _textureCache2 = _interopRequireDefault(_textureCache);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var mod = {
createProgramFromString: _createProgramFromString2.default,
renderer: {
render: _renderer.render,
initRenderer: _renderer.initRenderer,
getRenderCanvas: _renderer.getRenderCanvas,
isWebGLAvailable: _renderer.isWebGLAvailable
},
textureCache: _textureCache2.default
};
Object.defineProperty(mod, 'isWebGLInitialized', {
enumerable: true,
configurable: false,
get: function get() {
return _renderer.isWebGLInitialized;
}
});
exports.default = mod;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var EventTarget = function () {
function EventTarget() {
_classCallCheck(this, EventTarget);
this.listeners = {};
}
_createClass(EventTarget, [{
key: "addEventListener",
value: function addEventListener(type, callback) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push(callback);
}
}, {
key: "removeEventListener",
value: function removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
var stack = this.listeners[type];
for (var i = 0, l = stack.length; i < l; i++) {
if (stack[i] === callback) {
stack.splice(i, 1);
return;
}
}
}
}, {
key: "dispatchEvent",
value: function dispatchEvent(event) {
if (!(event.type in this.listeners)) {
return true;
}
var stack = this.listeners[event.type];
for (var i = 0, l = stack.length; i < l; i++) {
stack[i].call(this, event);
}
return !event.defaultPrevented;
}
}]);
return EventTarget;
}();
var events = new EventTarget();
exports.default = events;
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.renderGrayscaleImage = renderGrayscaleImage;
exports.addGrayscaleLayer = addGrayscaleLayer;
var _storedPixelDataToCanvasImageData = __webpack_require__(18);
var _storedPixelDataToCanvasImageData2 = _interopRequireDefault(_storedPixelDataToCanvasImageData);
var _storedPixelDataToCanvasImageDataRGBA = __webpack_require__(29);
var _storedPixelDataToCanvasImageDataRGBA2 = _interopRequireDefault(_storedPixelDataToCanvasImageDataRGBA);
var _setToPixelCoordinateSystem = __webpack_require__(3);
var _setToPixelCoordinateSystem2 = _interopRequireDefault(_setToPixelCoordinateSystem);
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
var _index = __webpack_require__(14);
var _index2 = _interopRequireDefault(_index);
var _getLut = __webpack_require__(31);
var _getLut2 = _interopRequireDefault(_getLut);
var _doesImageNeedToBeRendered = __webpack_require__(13);
var _doesImageNeedToBeRendered2 = _interopRequireDefault(_doesImageNeedToBeRendered);
var _initializeRenderCanvas = __webpack_require__(11);
var _initializeRenderCanvas2 = _interopRequireDefault(_initializeRenderCanvas);
var _saveLastRendered = __webpack_require__(12);
var _saveLastRendered2 = _interopRequireDefault(_saveLastRendered);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function getRenderCanvas(enabledElement, image, invalidated) {
var useAlphaChannel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
if (!enabledElement.renderingTools.renderCanvas) {
enabledElement.renderingTools.renderCanvas = document.createElement('canvas');
}
var renderCanvas = enabledElement.renderingTools.renderCanvas;
if ((0, _doesImageNeedToBeRendered2.default)(enabledElement, image) === false && invalidated !== true) {
return renderCanvas;
}
// If our render canvas does not match the size of this image reset it
// NOTE: This might be inefficient if we are updating multiple images of different
// Sizes frequently.
if (renderCanvas.width !== image.width || renderCanvas.height !== image.height) {
(0, _initializeRenderCanvas2.default)(enabledElement, image);
}
// Get the lut to use
var start = (0, _now2.default)();
var lut = (0, _getLut2.default)(image, enabledElement.viewport, invalidated);
image.stats = image.stats || {};
image.stats.lastLutGenerateTime = (0, _now2.default)() - start;
var renderCanvasData = enabledElement.renderingTools.renderCanvasData;
var renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;
// Gray scale image - apply the lut and put the resulting image onto the render canvas
if (useAlphaChannel) {
(0, _storedPixelDataToCanvasImageData2.default)(image, lut, renderCanvasData.data);
} else {
(0, _storedPixelDataToCanvasImageDataRGBA2.default)(image, lut, renderCanvasData.data);
}
start = (0, _now2.default)();
renderCanvasContext.putImageData(renderCanvasData, 0, 0);
image.stats.lastPutImageDataTime = (0, _now2.default)() - start;
return renderCanvas;
}
/**
* API function to draw a grayscale image to a given enabledElement
*
* @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw
* @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used
* @returns {void}
*/
function renderGrayscaleImage(enabledElement, invalidated) {
if (enabledElement === undefined) {
throw new Error('drawImage: enabledElement parameter must not be undefined');
}
var image = enabledElement.image;
if (image === undefined) {
throw new Error('drawImage: image must be loaded before it can be drawn');
}
// Get the canvas context and reset the transform
var context = enabledElement.canvas.getContext('2d');
context.setTransform(1, 0, 0, 1, 0, 0);
// Clear the canvas
context.fillStyle = 'black';
context.fillRect(0, 0, enabledElement.canvas.width, enabledElement.canvas.height);
// Turn off image smooth/interpolation if pixelReplication is set in the viewport
context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;
context.mozImageSmoothingEnabled = context.imageSmoothingEnabled;
// Save the canvas context state and apply the viewport properties
(0, _setToPixelCoordinateSystem2.default)(enabledElement, context);
var renderCanvas = void 0;
if (enabledElement.options && enabledElement.options.renderer && enabledElement.options.renderer.toLowerCase() === 'webgl') {
// If this enabled element has the option set for WebGL, we should
// User it as our renderer.
renderCanvas = _index2.default.renderer.render(enabledElement);
} else {
// If no options are set we will retrieve the renderCanvas through the
// Normal Canvas rendering path
renderCanvas = getRenderCanvas(enabledElement, image, invalidated);
}
context.drawImage(renderCanvas, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
enabledElement.renderingTools = (0, _saveLastRendered2.default)(enabledElement);
}
/**
* API function to draw a grayscale image to a given layer
*
* @param {EnabledElementLayer} layer The layer that the image will be added to
* @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used
* @param {Boolean} [useAlphaChannel] - Whether or not to render the grayscale image using only the alpha channel.
This does not work if this layer is not the first layer in the enabledElement.
* @returns {void}
*/
function addGrayscaleLayer(layer, invalidated) {
var useAlphaChannel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
if (layer === undefined) {
throw new Error('addGrayscaleLayer: layer parameter must not be undefined');
}
var image = layer.image;
if (image === undefined) {
throw new Error('addGrayscaleLayer: image must be loaded before it can be drawn');
}
layer.canvas = getRenderCanvas(layer, image, invalidated, useAlphaChannel);
var context = layer.canvas.getContext('2d');
// Turn off image smooth/interpolation if pixelReplication is set in the viewport
context.imageSmoothingEnabled = !layer.viewport.pixelReplication;
context.mozImageSmoothingEnabled = context.imageSmoothingEnabled;
layer.renderingTools = (0, _saveLastRendered2.default)(layer);
}
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (callback) {
return window.requestAnimationFrame(callback) || window.webkitRequestAnimationFrame(callback) || window.mozRequestAnimationFrame(callback) || window.oRequestAnimationFrame(callback) || window.msRequestAnimationFrame(callback) || requestFrame(callback);
};
function requestFrame(callback) {
window.setTimeout(callback, 1000 / 60);
}
/**
* Polyfills requestAnimationFrame for older browsers.
*
* @param {Function} callback A parameter specifying a function to call when it's time to update your animation for the next repaint. The callback has one single argument, a DOMHighResTimeStamp, which indicates the current time (the time returned from performance.now() ) for when requestAnimationFrame starts to fire callbacks.
*
* @return {Number} A long integer value, the request id, that uniquely identifies the entry in the callback list. This is a non-zero value, but you may not make any other assumptions about its value. You can pass this value to window.cancelAnimationFrame() to cancel the refresh callback request.
*/
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (image, lut, canvasImageDataData) {
var start = (0, _now2.default)();
var pixelData = image.getPixelData();
image.stats.lastGetPixelDataTime = (0, _now2.default)() - start;
var numPixels = pixelData.length;
var minPixelValue = image.minPixelValue;
var canvasImageDataIndex = 3;
var storedPixelDataIndex = 0;
// NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.
// We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement
// Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.
start = (0, _now2.default)();
if (pixelData instanceof Int16Array) {
if (minPixelValue < 0) {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha
canvasImageDataIndex += 4;
}
} else {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex++]]; // Alpha
canvasImageDataIndex += 4;
}
}
} else if (pixelData instanceof Uint16Array) {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex++]]; // Alpha
canvasImageDataIndex += 4;
}
} else if (minPixelValue < 0) {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha
canvasImageDataIndex += 4;
}
} else {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex++]]; // Alpha
canvasImageDataIndex += 4;
}
}
image.stats.lastStoredPixelDataToCanvasImageDataTime = (0, _now2.default)() - start;
};
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (image, lut, canvasImageDataData) {
var start = (0, _now2.default)();
var pixelData = image.getPixelData();
image.stats.lastGetPixelDataTime = (0, _now2.default)() - start;
var minPixelValue = image.minPixelValue;
var canvasImageDataIndex = 0;
var storedPixelDataIndex = 0;
var numPixels = pixelData.length;
// NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.
// We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement
start = (0, _now2.default)();
if (minPixelValue < 0) {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex++] = lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red
canvasImageDataData[canvasImageDataIndex++] = lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex] + -minPixelValue]; // Blue
storedPixelDataIndex += 2;
canvasImageDataIndex += 2;
}
} else {
while (storedPixelDataIndex < numPixels) {
canvasImageDataData[canvasImageDataIndex++] = lut[pixelData[storedPixelDataIndex++]]; // Red
canvasImageDataData[canvasImageDataIndex++] = lut[pixelData[storedPixelDataIndex++]]; // Green
canvasImageDataData[canvasImageDataIndex] = lut[pixelData[storedPixelDataIndex]]; // Blue
storedPixelDataIndex += 2;
canvasImageDataIndex += 2;
}
}
image.stats.lastStoredPixelDataToCanvasImageDataTime = (0, _now2.default)() - start;
};
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _index = __webpack_require__(7);
var _index2 = _interopRequireDefault(_index);
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* @param {Image} image A Cornerstone Image Object
* @param {LookupTable|Array} colorLut Lookup table array
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
*
* @returns {void}
*/
function storedPixelDataToCanvasImageDataColorLUT(image, colorLut, canvasImageDataData) {
var start = (0, _now2.default)();
var pixelData = image.getPixelData();
image.stats.lastGetPixelDataTime = (0, _now2.default)() - start;
var numPixels = pixelData.length;
var minPixelValue = image.minPixelValue;
var canvasImageDataIndex = 0;
var storedPixelDataIndex = 0;
var rgba = void 0;
var clut = void 0;
start = (0, _now2.default)();
if (colorLut instanceof _index2.default.LookupTable) {
clut = colorLut.Table;
} else {
clut = colorLut;
}
if (minPixelValue < 0) {
while (storedPixelDataIndex < numPixels) {
rgba = clut[pixelData[storedPixelDataIndex++] + -minPixelValue];
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
canvasImageDataData[canvasImageDataIndex++] = rgba[3];
}
} else {
while (storedPixelDataIndex < numPixels) {
rgba = clut[pixelData[storedPixelDataIndex++]];
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
canvasImageDataData[canvasImageDataIndex++] = rgba[3];
}
}
image.stats.lastStoredPixelDataToCanvasImageDataTime = (0, _now2.default)() - start;
}
exports.default = storedPixelDataToCanvasImageDataColorLUT;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _index = __webpack_require__(7);
var _index2 = _interopRequireDefault(_index);
var _now = __webpack_require__(1);
var _now2 = _interopRequireDefault(_now);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* @param {Image} image A Cornerstone Image Object
* @param {Array} grayscaleLut Lookup table array
* @param {LookupTable|Array} colorLut Lookup table array
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
*
* @returns {void}
*/
function storedPixelDataToCanvasImageDataPseudocolorLUT(image, grayscaleLut, colorLut, canvasImageDataData) {
var start = (0, _now2.default)();
var pixelData = image.getPixelData();
image.stats.lastGetPixelDataTime = (0, _now2.default)() - start;
var numPixels = pixelData.length;
var minPixelValue = image.minPixelValue;
var canvasImageDataIndex = 0;
var storedPixelDataIndex = 0;
var grayscale = void 0;
var rgba = void 0;
var clut = void 0;
start = (0, _now2.default)();
if (colorLut instanceof _index2.default.LookupTable) {
clut = colorLut.Table;
} else {
clut = colorLut;
}
if (minPixelValue < 0) {
while (storedPixelDataIndex < numPixels) {
grayscale = grayscaleLut[pixelData[storedPixelDataIndex++] + -minPixelValue];
rgba = clut[grayscale];
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
canvasImageDataData[canvasImageDataIndex++] = rgba[3];
}
} else {
while (storedPixelDataIndex < numPixels) {
grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]];
rgba = clut[grayscale];
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
canvasImageDataData[canv