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;
}