static saveVolumeSliceToFile()

in src/engine/actvolume/actvol.js [307:433]


  static saveVolumeSliceToFile(pixelsSrc, xDim, yDim, zDim, zSlice, fileName) {
    const SIZE_HEADER = 14;
    const SIZE_INFO = 40;
    const COMPS_IN_COLOR = 3;
    const numPixels = xDim * yDim;
    let pixStride = COMPS_IN_COLOR * xDim;
    pixStride = (pixStride + COMPS_IN_COLOR) & ~COMPS_IN_COLOR;
    const totalBufSize = SIZE_HEADER + SIZE_INFO + numPixels * COMPS_IN_COLOR;
    const buf = new Uint8Array(totalBufSize);
    for (let j = 0; j < totalBufSize; j++) {
      buf[j] = 0;
    }
    const BYTE_MASK = 255;
    const BITS_IN_BYTE = 8;
    // write header
    const BYTES_IN_DWORD = 4;

    let i = 0;
    // bfType[16]
    buf[i++] = 0x42;
    buf[i++] = 0x4d;
    // bfSize[32]
    let bfSize = SIZE_HEADER + SIZE_INFO + pixStride * yDim;
    buf[i++] = bfSize & BYTE_MASK;
    bfSize >>= BITS_IN_BYTE;
    buf[i++] = bfSize & BYTE_MASK;
    bfSize >>= BITS_IN_BYTE;
    buf[i++] = bfSize & BYTE_MASK;
    bfSize >>= BITS_IN_BYTE;
    buf[i++] = bfSize & BYTE_MASK;
    // bfReserved1 + bfReserved2
    i += BYTES_IN_DWORD;
    // bfOffBits[32]
    let bfOffBits = SIZE_HEADER + SIZE_INFO;
    buf[i++] = bfOffBits & BYTE_MASK;
    bfOffBits >>= BITS_IN_BYTE;
    buf[i++] = bfOffBits & BYTE_MASK;
    bfOffBits >>= BITS_IN_BYTE;
    buf[i++] = bfOffBits & BYTE_MASK;
    bfOffBits >>= BITS_IN_BYTE;
    buf[i++] = bfOffBits & BYTE_MASK;

    // write info

    // biSize[32]
    let biSize = SIZE_INFO;
    buf[i++] = biSize & BYTE_MASK;
    biSize >>= BITS_IN_BYTE;
    buf[i++] = biSize & BYTE_MASK;
    biSize >>= BITS_IN_BYTE;
    buf[i++] = biSize & BYTE_MASK;
    biSize >>= BITS_IN_BYTE;
    buf[i++] = biSize & BYTE_MASK;
    // biWidth[32]
    let biWidth = xDim;
    buf[i++] = biWidth & BYTE_MASK;
    biWidth >>= BITS_IN_BYTE;
    buf[i++] = biWidth & BYTE_MASK;
    biWidth >>= BITS_IN_BYTE;
    buf[i++] = biWidth & BYTE_MASK;
    biWidth >>= BITS_IN_BYTE;
    buf[i++] = biWidth & BYTE_MASK;
    // biHeight[32]
    let biHeight = yDim;
    buf[i++] = biHeight & BYTE_MASK;
    biHeight >>= BITS_IN_BYTE;
    buf[i++] = biHeight & BYTE_MASK;
    biHeight >>= BITS_IN_BYTE;
    buf[i++] = biHeight & BYTE_MASK;
    biHeight >>= BITS_IN_BYTE;
    buf[i++] = biHeight & BYTE_MASK;
    // biPlanes[16]
    buf[i++] = 1;
    buf[i++] = 0;
    // biBitCount[16]
    buf[i++] = 24;
    buf[i++] = 0;
    // biCompression[32]
    i += BYTES_IN_DWORD;
    // biSizeImage[32]
    let biSizeImage = pixStride * yDim;
    buf[i++] = biSizeImage & BYTE_MASK;
    biSizeImage >>= BITS_IN_BYTE;
    buf[i++] = biSizeImage & BYTE_MASK;
    biSizeImage >>= BITS_IN_BYTE;
    buf[i++] = biSizeImage & BYTE_MASK;
    biSizeImage >>= BITS_IN_BYTE;
    buf[i++] = biSizeImage & BYTE_MASK;
    // biXPelsPerMeter[32]
    i += BYTES_IN_DWORD;
    // biYPelsPerMeter[32]
    i += BYTES_IN_DWORD;
    // biClrUsed[32]
    i += BYTES_IN_DWORD;
    // biClrImportant[32]
    i += BYTES_IN_DWORD;

    let j;
    // get max volume
    const offSlice = zSlice * xDim * yDim;
    let valMax = 0;
    for (j = 0; j < numPixels; j++) {
      const valGrey = pixelsSrc[offSlice + j];
      valMax = valGrey > valMax ? valGrey : valMax;
    } // for (j)
    console.log(`saveVolumeSlice. valMax = ${valMax}`);

    // write pixels
    const MAX_COLOR = 255;
    for (j = 0; j < numPixels; j++) {
      const valGrey = Math.floor((pixelsSrc[offSlice + j] * MAX_COLOR) / valMax);
      // write rgb components
      buf[i++] = valGrey;
      buf[i++] = valGrey;
      buf[i++] = valGrey;
    } // for (j)

    // write buffer to file
    const blob = new Blob([buf], { type: 'application/octet-stream' });
    const url = URL.createObjectURL(blob);
    const linkGen = document.createElement('a');
    linkGen.setAttribute('href', url);
    linkGen.setAttribute('download', fileName);
    const eventGen = document.createEvent('MouseEvents');
    eventGen.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
    linkGen.dispatchEvent(eventGen);
  }