comparison OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp @ 1679:5b8b88e5bfd6

successfully running unit tests in WebAssembly
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 24 Nov 2020 12:59:10 +0100
parents 51bab5188a13
children 9ac2a65d4172
comparison
equal deleted inserted replaced
1678:1393e3393a0b 1679:5b8b88e5bfd6
180 } 180 }
181 } 181 }
182 182
183 bool ok = false; 183 bool ok = false;
184 184
185 if (LinearAlgebra::ParseVector(presetWindowingCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) && 185 if (LinearAlgebra::ParseVector(windowingPresetCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) &&
186 LinearAlgebra::ParseVector(presetWindowingWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH)) 186 LinearAlgebra::ParseVector(windowingPresetWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH))
187 { 187 {
188 if (presetWindowingCenters_.size() == presetWindowingWidths_.size()) 188 if (windowingPresetCenters_.size() == windowingPresetWidths_.size())
189 { 189 {
190 ok = true; 190 ok = true;
191 } 191 }
192 else 192 else
193 { 193 {
197 } 197 }
198 198
199 if (!ok) 199 if (!ok)
200 { 200 {
201 // Don't use "Vector::clear()", as it has not the same meaning as "std::vector::clear()" 201 // Don't use "Vector::clear()", as it has not the same meaning as "std::vector::clear()"
202 presetWindowingCenters_.resize(0); 202 windowingPresetCenters_.resize(0);
203 presetWindowingWidths_.resize(0); 203 windowingPresetWidths_.resize(0);
204 } 204 }
205 205
206 // This computes the "IndexInSeries" metadata from Orthanc (check 206 // This computes the "IndexInSeries" metadata from Orthanc (check
207 // out "Orthanc::ServerIndex::Store()") 207 // out "Orthanc::ServerIndex::Store()")
208 hasIndexInSeries_ = ( 208 hasIndexInSeries_ = (
395 return Orthanc::PixelFormat_Grayscale16; // Rough guess 395 return Orthanc::PixelFormat_Grayscale16; // Rough guess
396 } 396 }
397 } 397 }
398 398
399 399
400 size_t DicomInstanceParameters::GetPresetWindowingsCount() const 400 size_t DicomInstanceParameters::GetWindowingPresetsCount() const
401 { 401 {
402 assert(data_.presetWindowingCenters_.size() == data_.presetWindowingWidths_.size()); 402 assert(data_.windowingPresetCenters_.size() == data_.windowingPresetWidths_.size());
403 return data_.presetWindowingCenters_.size(); 403 return data_.windowingPresetCenters_.size();
404 } 404 }
405 405
406 406
407 float DicomInstanceParameters::GetPresetWindowingCenter(size_t i) const 407 float DicomInstanceParameters::GetWindowingPresetCenter(size_t i) const
408 { 408 {
409 if (i < GetPresetWindowingsCount()) 409 if (i < GetWindowingPresetsCount())
410 { 410 {
411 return static_cast<float>(data_.presetWindowingCenters_[i]); 411 return static_cast<float>(data_.windowingPresetCenters_[i]);
412 } 412 }
413 else 413 else
414 { 414 {
415 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 415 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
416 } 416 }
417 } 417 }
418 418
419 419
420 float DicomInstanceParameters::GetPresetWindowingWidth(size_t i) const 420 float DicomInstanceParameters::GetWindowingPresetWidth(size_t i) const
421 { 421 {
422 if (i < GetPresetWindowingsCount()) 422 if (i < GetWindowingPresetsCount())
423 { 423 {
424 return static_cast<float>(data_.presetWindowingWidths_[i]); 424 return static_cast<float>(data_.windowingPresetWidths_[i]);
425 } 425 }
426 else 426 else
427 { 427 {
428 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 428 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
429 } 429 }
430 } 430 }
431 431
432
433 static void GetWindowingBounds(float& low,
434 float& high,
435 double center, // in
436 double width) // in
437 {
438 low = static_cast<float>(center - width / 2.0);
439 high = static_cast<float>(center + width / 2.0);
440 }
441
432 442
443 void DicomInstanceParameters::GetWindowingPresetsUnion(float& center,
444 float& width) const
445 {
446 assert(tags_.get() != NULL);
447 size_t s = GetWindowingPresetsCount();
448
449 if (s > 0)
450 {
451 // Use the largest windowing given all the preset windowings
452 // that are available in the DICOM tags
453 float low, high;
454 GetWindowingBounds(low, high, GetWindowingPresetCenter(0), GetWindowingPresetWidth(0));
455
456 for (size_t i = 1; i < s; i++)
457 {
458 float a, b;
459 GetWindowingBounds(a, b, GetWindowingPresetCenter(i), GetWindowingPresetWidth(i));
460 low = std::min(low, a);
461 high = std::max(high, b);
462 }
463
464 assert(low <= high);
465
466 if (LinearAlgebra::IsNear(low, high))
467 {
468 // Cannot infer a suitable windowing from the available tags
469 center = 128.0f;
470 width = 256.0f;
471 }
472 else
473 {
474 center = (low + high) / 2.0f;
475 width = (high - low);
476 }
477 }
478 else
479 {
480 float a, b;
481 if (tags_->ParseFloat(a, Orthanc::DICOM_TAG_SMALLEST_IMAGE_PIXEL_VALUE) &&
482 tags_->ParseFloat(b, Orthanc::DICOM_TAG_LARGEST_IMAGE_PIXEL_VALUE) &&
483 a < b)
484 {
485 center = (a + b) / 2.0f;
486 width = (b - a);
487 }
488 else
489 {
490 // Cannot infer a suitable windowing from the available tags
491 center = 128.0f;
492 width = 256.0f;
493 }
494 }
495 }
496
497
433 Orthanc::ImageAccessor* DicomInstanceParameters::ConvertToFloat(const Orthanc::ImageAccessor& pixelData) const 498 Orthanc::ImageAccessor* DicomInstanceParameters::ConvertToFloat(const Orthanc::ImageAccessor& pixelData) const
434 { 499 {
435 std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32, 500 std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32,
436 pixelData.GetWidth(), 501 pixelData.GetWidth(),
437 pixelData.GetHeight(), 502 pixelData.GetHeight(),
492 { 557 {
493 std::unique_ptr<Orthanc::ImageAccessor> converted(ConvertToFloat(pixelData)); 558 std::unique_ptr<Orthanc::ImageAccessor> converted(ConvertToFloat(pixelData));
494 texture.reset(new FloatTextureSceneLayer(*converted)); 559 texture.reset(new FloatTextureSceneLayer(*converted));
495 } 560 }
496 561
497 if (GetPresetWindowingsCount() > 0) 562 if (GetWindowingPresetsCount() > 0)
498 { 563 {
499 texture->SetCustomWindowing(GetPresetWindowingCenter(0), GetPresetWindowingWidth(0)); 564 texture->SetCustomWindowing(GetWindowingPresetCenter(0), GetWindowingPresetWidth(0));
500 } 565 }
501 566
502 switch (GetImageInformation().GetPhotometricInterpretation()) 567 switch (GetImageInformation().GetPhotometricInterpretation())
503 { 568 {
504 case Orthanc::PhotometricInterpretation_Monochrome1: 569 case Orthanc::PhotometricInterpretation_Monochrome1: