Mercurial > hg > orthanc-stone
comparison Framework/Volumes/ImageBuffer3D.cpp @ 119:ba83e38cf3ff wasm
rendering of rt-dose
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 02 Oct 2017 22:01:41 +0200 |
parents | 2eca030792aa |
children | e2fe9352f240 |
comparison
equal
deleted
inserted
replaced
118:a4d0b6c82b29 | 119:ba83e38cf3ff |
---|---|
110 | 110 |
111 | 111 |
112 ImageBuffer3D::ImageBuffer3D(Orthanc::PixelFormat format, | 112 ImageBuffer3D::ImageBuffer3D(Orthanc::PixelFormat format, |
113 unsigned int width, | 113 unsigned int width, |
114 unsigned int height, | 114 unsigned int height, |
115 unsigned int depth) : | 115 unsigned int depth, |
116 bool computeRange) : | |
116 image_(format, width, height * depth, false), | 117 image_(format, width, height * depth, false), |
117 format_(format), | 118 format_(format), |
118 width_(width), | 119 width_(width), |
119 height_(height), | 120 height_(height), |
120 depth_(depth) | 121 depth_(depth), |
122 computeRange_(computeRange), | |
123 hasRange_(false) | |
121 { | 124 { |
122 GeometryToolbox::AssignVector(voxelDimensions_, 1, 1, 1); | 125 GeometryToolbox::AssignVector(voxelDimensions_, 1, 1, 1); |
123 | 126 |
124 LOG(INFO) << "Created an image of " | 127 LOG(INFO) << "Created an image of " |
125 << (GetEstimatedMemorySize() / (1024ll * 1024ll)) << "MB"; | 128 << (GetEstimatedMemorySize() / (1024ll * 1024ll)) << "MB"; |
263 { | 266 { |
264 return image_.GetPitch() * image_.GetHeight() * Orthanc::GetBytesPerPixel(format_); | 267 return image_.GetPitch() * image_.GetHeight() * Orthanc::GetBytesPerPixel(format_); |
265 } | 268 } |
266 | 269 |
267 | 270 |
271 void ImageBuffer3D::ExtendImageRange(const Orthanc::ImageAccessor& slice) | |
272 { | |
273 if (!computeRange_ || | |
274 slice.GetWidth() == 0 || | |
275 slice.GetHeight() == 0) | |
276 { | |
277 return; | |
278 } | |
279 | |
280 float sliceMin, sliceMax; | |
281 | |
282 switch (slice.GetFormat()) | |
283 { | |
284 case Orthanc::PixelFormat_Grayscale8: | |
285 case Orthanc::PixelFormat_Grayscale16: | |
286 case Orthanc::PixelFormat_Grayscale32: | |
287 case Orthanc::PixelFormat_SignedGrayscale16: | |
288 { | |
289 int64_t a, b; | |
290 Orthanc::ImageProcessing::GetMinMaxIntegerValue(a, b, slice); | |
291 sliceMin = static_cast<float>(a); | |
292 sliceMax = static_cast<float>(b); | |
293 break; | |
294 } | |
295 | |
296 case Orthanc::PixelFormat_Float32: | |
297 Orthanc::ImageProcessing::GetMinMaxFloatValue(sliceMin, sliceMax, slice); | |
298 break; | |
299 | |
300 default: | |
301 return; | |
302 } | |
303 | |
304 if (hasRange_) | |
305 { | |
306 minValue_ = std::min(minValue_, sliceMin); | |
307 maxValue_ = std::max(maxValue_, sliceMax); | |
308 } | |
309 else | |
310 { | |
311 hasRange_ = true; | |
312 minValue_ = sliceMin; | |
313 maxValue_ = sliceMax; | |
314 } | |
315 } | |
316 | |
317 | |
318 bool ImageBuffer3D::GetRange(float& minValue, | |
319 float& maxValue) const | |
320 { | |
321 if (hasRange_) | |
322 { | |
323 minValue = minValue_; | |
324 maxValue = maxValue_; | |
325 return true; | |
326 } | |
327 else | |
328 { | |
329 return false; | |
330 } | |
331 } | |
332 | |
333 | |
334 bool ImageBuffer3D::FitWindowingToRange(RenderStyle& style, | |
335 const DicomFrameConverter& converter) const | |
336 { | |
337 if (hasRange_) | |
338 { | |
339 style.windowing_ = ImageWindowing_Custom; | |
340 style.customWindowCenter_ = converter.Apply((minValue_ + maxValue_) / 2.0); | |
341 style.customWindowWidth_ = converter.Apply(maxValue_ - minValue_); | |
342 | |
343 if (style.customWindowWidth_ > 1) | |
344 { | |
345 return true; | |
346 } | |
347 } | |
348 | |
349 style.windowing_ = ImageWindowing_Custom; | |
350 style.customWindowCenter_ = 128.0; | |
351 style.customWindowWidth_ = 256.0; | |
352 return false; | |
353 } | |
354 | |
355 | |
268 ImageBuffer3D::SliceReader::SliceReader(ImageBuffer3D& that, | 356 ImageBuffer3D::SliceReader::SliceReader(ImageBuffer3D& that, |
269 VolumeProjection projection, | 357 VolumeProjection projection, |
270 unsigned int slice) | 358 unsigned int slice) |
271 { | 359 { |
272 switch (projection) | 360 switch (projection) |
297 if (sagittal_.get() != NULL) | 385 if (sagittal_.get() != NULL) |
298 { | 386 { |
299 // TODO | 387 // TODO |
300 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); | 388 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
301 } | 389 } |
390 | |
391 // Update the dynamic range of the underlying image, if | |
392 // "computeRange_" is set to true | |
393 that_.ExtendImageRange(accessor_); | |
302 } | 394 } |
303 } | 395 } |
304 | 396 |
305 | 397 |
306 ImageBuffer3D::SliceWriter::SliceWriter(ImageBuffer3D& that, | 398 ImageBuffer3D::SliceWriter::SliceWriter(ImageBuffer3D& that, |
307 VolumeProjection projection, | 399 VolumeProjection projection, |
308 unsigned int slice) : | 400 unsigned int slice) : |
309 modified_(false) | 401 that_(that), |
402 modified_(false) | |
310 { | 403 { |
311 switch (projection) | 404 switch (projection) |
312 { | 405 { |
313 case VolumeProjection_Axial: | 406 case VolumeProjection_Axial: |
314 accessor_ = that.GetAxialSliceAccessor(slice, false); | 407 accessor_ = that.GetAxialSliceAccessor(slice, false); |