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

41.3% Statements 19/46
35.71% Branches 10/28
37.5% Functions 3/8
41.3% Lines 19/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                                                                               5x   5x         5x   5x                   5x             3x 2x             2x   2x         2x       2x 2x       2x       2x   2x         2x             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);
 
  Iif (!enabledElement) {
    // Can be not valid if the data is changed part way through prefetch
    return null;
  }
 
  const { viewport } = enabledElement;
 
  Iif (!(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;
    }
 
    Iif (!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
    Iif (imageIdIndex < 0) {
      return;
    }
 
    const stackPrefetchData = getToolState(element);
 
    Eif (
      !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);
};