colorMonochromeImageFrame (frameData) {
    const {
      img,
      frames,
      bitsAllocated,
      pixelRepresentation,
      thresholdValues,
      limitValues,
      color,
      opacity,
      columns,
      rows
    } = frameData

    const signed = pixelRepresentation === 1
    if (frames) {
      let {
        pixelData,
        decodedframeInfo
      } = this._checkImageTypeAndDecode(frames)

      let bitsPerSample
      if (decodedframeInfo) {
        bitsPerSample = decodedframeInfo.bitsPerSample
      }

      if (!pixelData) {
        // data downloaded uncompressed
        switch (bitsAllocated) {
          case 8:
            if (signed) {
              pixelData = new Int8Array(frames)
            } else {
              pixelData = new Uint8Array(frames)
            }
            break
          case 16:
            if (signed) {
              pixelData = new Int16Array(frames)
            } else {
              pixelData = new Uint16Array(frames)
            }
            break
          default:
            throw new Error(
              'The pixel bit ' + bitsAllocated + 'is not supported by the offscreen render.'
            )
        }
        bitsPerSample = bitsAllocated
      }

      // NOTE: we store the pixelData array and bitsPerSample in img, so we can apply again colorImageFrame
      //       at the change of any blending parameter (opacity, color, clipping).
      img.pixelData = pixelData
      img.bitsPerSample = bitsPerSample
    }

    if (img.pixelData) {
      // run offscreen render to color images
      const renderedCanvas = this._render(
        img.pixelData,
        img.bitsPerSample,
        columns,
        rows,
        color,
        opacity,
        thresholdValues,
        limitValues
      )

      // econde back the image in png
      img.src = renderedCanvas.toDataURL('image/png')

      // NOTE: ToBlob is async and provides smaller images,
      // but here the renderingEngine is synch/sequential (one object, one gl context, etc..).
      // When the OffscreenCanvas will be fully supported,
      // it can be used for a full web-workers async approach
      // https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas

      return true
    }

    return false
  }
/** Runs the offscreen render applying the channel visualization/presentation parameters
   * to monochrome images (1 color channel).
   * The pipeline consists in 3 steps:
   * 1) decode the image if is jpeg (libJPEG-turbo), jp2/jpx (OpenJPEG) or jls (CharLS).
   *    The image type is automatically detected by checking the magic number
   *    https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files
   *    (see https://github.com/sindresorhus/file-type).
   * 2) apply coloring to the images with the offscreen webgl canvas.
   * 3) recompress the image in lossless png format.
   *
   * NOTE: The actual render time is < respect to the recompression of the data in png (toDataURL).
   *       Using lossy compression (jpeg), would improve the compression step.
   *       However, the images are originally stored in the server as lossy jpeg and
   *       we would have lossy re-compression issues
   *       (al least for IDC data, https://imaging.datacommons.cancer.gov/).
   *
   * @param {object} frameData - interface to pass the frame data to the offscreen render
   * @param {object} frameData.img - Image object
   * @param {number[]} frameData.frames - compressed image array
   * @param {number} frameData.bitsAllocated - bits per pixel
   * @param {number} frameData.pixelRepresentation - pixel sign
   * @param {number[]} frameData.thresholdValues - clipping values
   * @param {number[]} frameData.limitValues - min and max color function values
   * @param {number[]} frameData.color - rgb color
   * @param {number} frameData.opacity - opacity
   * @param {number} frameData.columns - horizontal image size
   * @param {number} frameData.rows - vertical image size
   *
   * @returns {boolean} image was colored.
   */
Runs the offscreen render applying the channel visualization/presentation parameters
to monochrome images (1 color channel).
The pipeline consists in 3 steps:
1) decode the image if is jpeg (libJPEG-turbo), jp2/jpx (OpenJPEG) or jls (CharLS).

The actual render time is < respect to the recompression of the data in png (toDataURL).
Using lossy compression (jpeg), would improve the compression step.



@returns {boolean} image was colored.
Runs the offscreen render applying the channel visualization / presentation parameters to monochrome images ( 1 color channel ) . The pipeline consists in 3 steps : 1 ) decode the image if is jpeg ( libJPEG - turbo ) jp2 / jpx ( OpenJPEG ) or jls ( CharLS ) . The actual render time is < respect to the recompression of the data in png ( toDataURL ) . Using lossy compression ( jpeg ) would improve the compression step . @returns { boolean } image was colored .
colorMonochromeImageFrame (frameData) {
    const {
      img,
      frames,
      bitsAllocated,
      pixelRepresentation,
      thresholdValues,
      limitValues,
      color,
      opacity,
      columns,
      rows
    } = frameData
    const signed = pixelRepresentation === 1
    if (frames) {
      let {
        pixelData,
        decodedframeInfo
      } = this._checkImageTypeAndDecode(frames)
      let bitsPerSample
      if (decodedframeInfo) {
        bitsPerSample = decodedframeInfo.bitsPerSample
      }
      if (!pixelData) {
        switch (bitsAllocated) {
          case 8:
            if (signed) {
              pixelData = new Int8Array(frames)
            } else {
              pixelData = new Uint8Array(frames)
            }
            break
          case 16:
            if (signed) {
              pixelData = new Int16Array(frames)
            } else {
              pixelData = new Uint16Array(frames)
            }
            break
          default:
            throw new Error(
              'The pixel bit ' + bitsAllocated + 'is not supported by the offscreen render.'
            )
        }
        bitsPerSample = bitsAllocated
      }
      img.pixelData = pixelData
      img.bitsPerSample = bitsPerSample
    }
    if (img.pixelData) {
      const renderedCanvas = this._render(
        img.pixelData,
        img.bitsPerSample,
        columns,
        rows,
        color,
        opacity,
        thresholdValues,
        limitValues
      )
      img.src = renderedCanvas.toDataURL('image/png')
      return true
    }
    return false
  }
colorMonochromeImageFrame ( frameData ) { const { img , frames , bitsAllocated , pixelRepresentation , thresholdValues , limitValues , color , opacity , columns , rows } = frameData const signed = pixelRepresentation === 1 if ( frames ) { let { pixelData , decodedframeInfo } = this . _checkImageTypeAndDecode ( frames ) let bitsPerSample if ( decodedframeInfo ) { bitsPerSample = decodedframeInfo . bitsPerSample } if ( ! pixelData ) { switch ( bitsAllocated ) { case 8 : if ( signed ) { pixelData = new Int8Array ( frames ) } else { pixelData = new Uint8Array ( frames ) } break case 16 : if ( signed ) { pixelData = new Int16Array ( frames ) } else { pixelData = new Uint16Array ( frames ) } break default : throw new Error ( 'The pixel bit ' + bitsAllocated + 'is not supported by the offscreen render.' ) } bitsPerSample = bitsAllocated } img . pixelData = pixelData img . bitsPerSample = bitsPerSample } if ( img . pixelData ) { const renderedCanvas = this . _render ( img . pixelData , img . bitsPerSample , columns , rows , color , opacity , thresholdValues , limitValues ) img . src = renderedCanvas . toDataURL ( 'image/png' ) return true } return false }
Runs the offscreen render applying the channel visualization/presentation parameters
 to monochrome images (1 color channel).
Runs the offscreen render applying the channel visualization / presentation parameters to monochrome images ( 1 color channel ) .
// data downloaded uncompressed // NOTE: we store the pixelData array and bitsPerSample in img, so we can apply again colorImageFrame //       at the change of any blending parameter (opacity, color, clipping). // run offscreen render to color images // econde back the image in png // NOTE: ToBlob is async and provides smaller images, // but here the renderingEngine is synch/sequential (one object, one gl context, etc..). // When the OffscreenCanvas will be fully supported, // it can be used for a full web-workers async approach // https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas