All files / packages/tools/src/utilities/stackPrefetch stackPrefetchUtils.ts

6.52% Statements 3/46
0% Branches 0/28
0% Functions 0/8
6.52% Lines 3/46

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119      1x 1x                                                                                                                                                                                                                       1x            
import { getEnabledElement, StackViewport, Enums } from '@cornerstonejs/core';
import { getToolState } from './state';
 
export const requestType = Enums.RequestType.Prefetch;
export const priority = 0;
 
export function range(lowEnd, highEnd) {
  // Javascript version of Python's range function
  // http://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-an-array-based-on-suppl
  lowEnd = Math.round(lowEnd) || 0;
  highEnd = Math.round(highEnd) || 0;
 
  const arr = [];
  let c = highEnd - lowEnd + 1;
 
  if (c <= 0) {
    return arr;
  }
 
  while (c--) {
    arr[c] = highEnd--;
  }
 
  return arr;
}
 
export function nearestIndex(arr, x) {
  // Return index of nearest values in array
  // http://stackoverflow.com/questions/25854212/return-index-of-nearest-values-in-an-array
  let low = 0;
  let high = arr.length - 1;
 
  arr.forEach((v, idx) => {
    if (v < x) {
      low = Math.max(idx, low);
    } else if (v > x) {
      high = Math.min(idx, high);
    }
  });
 
  return { low, high };
}
 
export function getStackData(element) {
  const enabledElement = getEnabledElement(element);
 
  if (!enabledElement) {
    // Can be not valid if the data is changed part way through prefetch
    return null;
  }
 
  const { viewport } = enabledElement;
 
  if (!(viewport instanceof StackViewport)) {
    // we shouldn't throw error here, since the viewport might have
    // changed from stack to volume during prefetch
    console.warn(
      'stackPrefetch: element must be a StackViewport, VolumeViewport stackPrefetch not yet implemented'
    );
 
    return null;
  }
 
  return {
    currentImageIdIndex: viewport.getCurrentImageIdIndex(),
    imageIds: viewport.getImageIds(),
  };
}
 
export function getPromiseRemovedHandler(element) {
  return function (e) {
    const eventData = e.detail;
 
    // When an imagePromise has been pushed out of the cache, re-add its index
    // It to the indicesToRequest list so that it will be retrieved later if the
    // CurrentImageIdIndex is changed to an image nearby
    let stackData;
 
    try {
      // It will throw an exception in some cases (eg: thumbnails)
      stackData = getStackData(element);
    } catch (error) {
      return;
    }
 
    if (!stackData || !stackData.imageIds || stackData.imageIds.length === 0) {
      return;
    }
 
    const stack = stackData;
    const imageIdIndex = stack.imageIds.indexOf(eventData.imageId);
 
    // Make sure the image that was removed is actually in this stack
    // Before adding it to the indicesToRequest array
    if (imageIdIndex < 0) {
      return;
    }
 
    const stackPrefetchData = getToolState(element);
 
    if (
      !stackPrefetchData ||
      !stackPrefetchData.data ||
      !stackPrefetchData.data.length
    ) {
      return;
    }
 
    stackPrefetchData.indicesToRequest.push(imageIdIndex);
  };
}
 
export const clearFromImageIds = (stack) => {
  const imageIdSet = new Set<string>(stack.imageIds);
  return (requestDetails) =>
    requestDetails.type !== requestType ||
    !imageIdSet.has(requestDetails.additionalDetails.imageId);
};