All files / dicomImageLoader/src/shared/decoders decodeDeflatedFrame.ts

0% Statements 0/4
100% Branches 0/0
0% Functions 0/1
0% Lines 0/4

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                                                                                               
import type { ByteArray } from 'dicom-parser';
import type { Types } from '@cornerstonejs/core';
import pako from 'pako';
 
import decodeLittleEndian from './decodeLittleEndian';
import { trimToNativeFrame } from './nativeFrameBytes';
 
/**
 * Decodes one frame of Deflated Image Frame Compression
 * (1.2.840.10008.1.2.8.1).
 *
 * Each frame is separately compressed with the raw Deflate algorithm of
 * RFC 1951 and encapsulated as a single fragment (PS3.5 A.4.13). Raw here is
 * load bearing: the frame carries no zlib header or Adler-32 trailer, so it is
 * `inflateRaw` rather than `inflate`. This is the same framing the whole-
 * dataset Deflated Explicit VR Little Endian syntax uses, applied per frame
 * instead of once over the data set - which is why that syntax is handled by
 * dicomParser at parse time and never reaches here.
 *
 * Inflating yields the frame's native uncompressed pixel data, so the result
 * is interpreted exactly as Explicit VR Little Endian would be.
 */
async function decodeDeflatedFrame(
  imageFrame: Types.IImageFrame,
  pixelData: ByteArray
): Promise<Types.IImageFrame> {
  let inflated: Uint8Array;
 
  try {
    inflated = pako.inflateRaw(
      // pako wants a plain Uint8Array view; a dicom-parser ByteArray already is
      // one, but may be a view onto a much larger buffer.
      new Uint8Array(pixelData.buffer, pixelData.byteOffset, pixelData.length)
    );
  } catch (error) {
    throw new Error(
      `decodeDeflatedFrame: could not inflate the frame (${error})`
    );
  }
 
  return decodeLittleEndian(
    imageFrame,
    trimToNativeFrame(imageFrame, inflated, 'decodeDeflatedFrame')
  );
}
 
export default decodeDeflatedFrame;