bool DICOMFileFrameRegionReader::readRegion()

in src/dicom_file_region_reader.cpp [221:319]


bool DICOMFileFrameRegionReader::readRegion(int64_t layerX,
int64_t layerY, int64_t memWidth, int64_t memHeight, uint32_t *memory) {
  // Reads a sub region from the a set of dicom frames spread across file(s).
  //
  // Memory pixels in ARGB format.
  // Memory pixel value = 0x00000000 for positions outside image dim.
  //
  // Args:
  //   layerX : upper left X coordinate in image coordinates.
  //   layerY : upper left Y coordinate in image coordinates.
  //   memWidth : Width of memory to copy into.
  //   memHeight : Height of memory to copy into.
  //   memory : Memory to copy into .
  //
  // Returns: True if has files, false if no DICOM files set.
  if (dicomFileCount() <= 0) {
    return false;
  }
  const uint64_t frameMemSizeBytes = frameWidth_ * frameHeight_ *
                                                      sizeof(uint32_t);
  std::unique_ptr<uint32_t[]> frameMem = std::make_unique<uint32_t[]>(
                                                  frameWidth_ * frameHeight_);
  // compute first and last frames to read.
  int64_t firstFrameX, firstFrameY, lastFrameX, lastFrameY;
  xyFrameSpan(layerX, layerY, memWidth, memHeight, &firstFrameX,
              &firstFrameY, &lastFrameX, &lastFrameY);

  /*BOOST_LOG_TRIVIAL(debug) << "DICOMFileFrameRegionReader::readRegion" <<
                              "\n" << "layerX, layerY: " << layerX <<
                              ", " << layerY << "\n" <<
                              "memWidth, height: " << memWidth <<
                              ", " << memHeight << "\n" <<
                              "frameWidth, frameHeight: " << frameWidth_ <<
                              ", " << frameHeight_ << "\n" <<
                              "imageWidth, imageHeight: " << imageWidth_ <<
                              ", " << imageHeight_ << "\n" <<
                              "framesPerRow: " << framesPerRow_ << "\n" <<
                              "firstFrameX, firstFrameY: " <<
                              firstFrameX << ", " << firstFrameY  <<
                              "\n" << "lastFrameX, lastFrameY: " <<
                              lastFrameX << ", " << lastFrameY;*/

  // read offset in first frame.
  const int64_t frameStartXInit = layerX % frameWidth_;
  int64_t frameStartY = layerY % frameHeight_;
  int64_t frameYCOffset = firstFrameY * framesPerRow_;

  // write position in memory buffer
  int64_t myStart = 0;
  // increment over frame rows
  for (int64_t frameYC = firstFrameY; frameYC <= lastFrameY; ++frameYC) {
    // init starting position to read from in frame and write to in mem.
    int64_t frameStartX = frameStartXInit;
    int64_t mxStart = 0;

    // height to copy from frame to mem buffer.  clip to data in frame
    // or remaining in memory buffer.  Which ever is smaller.
    const int64_t heightCopied =
      std::min<int64_t>(frameHeight_ - frameStartY, memHeight - myStart);

    // iterate over frame columns.
    for (int64_t frameXC = firstFrameX; frameXC <= lastFrameX; ++frameXC) {
      // Get Frame memory
      uint32_t *rawFrameBytes = nullptr;
      if ((frameXC < framesPerRow_) && (frameYC < framesPerColumn_)) {
        if (frameBytes(frameXC + frameYCOffset, frameMem.get(),
                        frameMemSizeBytes)) {
          rawFrameBytes = frameMem.get();
        } else {
          // if unable to read region. e.g., jpeg decode failed.
          return false;
        }
      }
      // width to copy from frame to mem buffer.  clip to data in frame
      // or remaining in memory buffer.  Which ever is smaller.
      const int64_t widthCopeid =
        std::min<int64_t>(frameWidth_ - frameStartX, memWidth - mxStart);

      // copy frame memory to buffer mem.
      copyRegionFromFrames(layerX, layerY, rawFrameBytes,
                            frameStartX, frameStartY, widthCopeid,
                            heightCopied, memory, memWidth, mxStart,
                            myStart);

      // increment write cusor X position
      mxStart += widthCopeid;

      // set next frame to start reading at the begining frame column
      frameStartX = 0;
    }
    // increment write cusor Y position
    myStart += heightCopied;
    // set next frame to start reading at the begining frame row
    frameStartY = 0;
    // increment row offset into frame buffer memory.
    frameYCOffset += framesPerRow_;
  }
  return true;
}