Mercurial > hg > orthanc-stone
comparison Framework/Deprecated/Radiography/RadiographyAlphaLayer.cpp @ 1398:c5403d52078c
moved Radiography into Deprecated
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 29 Apr 2020 20:43:09 +0200 |
parents | Framework/Radiography/RadiographyAlphaLayer.cpp@257f2c9a02ac |
children | 30deba7bc8e2 |
comparison
equal
deleted
inserted
replaced
1397:1c2d065ba372 | 1398:c5403d52078c |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "RadiographyAlphaLayer.h" | |
23 | |
24 #include "RadiographyScene.h" | |
25 | |
26 #include <Core/Compatibility.h> | |
27 #include <Core/Images/Image.h> | |
28 #include <Core/OrthancException.h> | |
29 | |
30 #include "../Toolbox/ImageGeometry.h" | |
31 | |
32 namespace OrthancStone | |
33 { | |
34 | |
35 void RadiographyAlphaLayer::SetAlpha(Orthanc::ImageAccessor* image) | |
36 { | |
37 std::unique_ptr<Orthanc::ImageAccessor> raii(image); | |
38 | |
39 if (image == NULL) | |
40 { | |
41 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); | |
42 } | |
43 | |
44 if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8) | |
45 { | |
46 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
47 } | |
48 | |
49 SetSize(image->GetWidth(), image->GetHeight()); | |
50 | |
51 #if __cplusplus < 201103L | |
52 alpha_.reset(raii.release()); | |
53 #else | |
54 alpha_ = std::move(raii); | |
55 #endif | |
56 | |
57 BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this)); | |
58 } | |
59 | |
60 void RadiographyAlphaLayer::Render(Orthanc::ImageAccessor& buffer, | |
61 const AffineTransform2D& viewTransform, | |
62 ImageInterpolation interpolation, | |
63 float windowCenter, | |
64 float windowWidth, | |
65 bool applyWindowing) const | |
66 { | |
67 if (alpha_.get() == NULL) | |
68 { | |
69 return; | |
70 } | |
71 | |
72 if (buffer.GetFormat() != Orthanc::PixelFormat_Float32) | |
73 { | |
74 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
75 } | |
76 | |
77 unsigned int cropX, cropY, cropWidth, cropHeight; | |
78 GetCrop(cropX, cropY, cropWidth, cropHeight); | |
79 | |
80 const AffineTransform2D t = AffineTransform2D::Combine( | |
81 viewTransform, GetTransform(), | |
82 AffineTransform2D::CreateOffset(cropX, cropY)); | |
83 | |
84 Orthanc::ImageAccessor cropped; | |
85 alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); | |
86 | |
87 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); | |
88 | |
89 unsigned int x1, y1, x2, y2; | |
90 | |
91 if (!OrthancStone::GetProjectiveTransformExtent(x1, y1, x2, y2, | |
92 t.GetHomogeneousMatrix(), | |
93 cropped.GetWidth(), | |
94 cropped.GetHeight(), | |
95 buffer.GetWidth(), | |
96 buffer.GetHeight())) | |
97 { | |
98 return; // layer is outside the buffer | |
99 } | |
100 | |
101 t.Apply(tmp, cropped, interpolation, true /* clear */); | |
102 | |
103 float value = foreground_; | |
104 | |
105 if (!applyWindowing) // if applying the windowing, it means we are ie rendering the image for a realtime visualization -> the foreground_ value is the value we want to see on the screen -> don't change it | |
106 { | |
107 // if not applying the windowing, it means ie that we are saving a dicom image to file and the windowing will be applied by a viewer later on -> we want the "foreground" value to be correct once the windowing will be applied | |
108 value = windowCenter - windowWidth/2 + (foreground_ / 65535.0f) * windowWidth; | |
109 | |
110 if (value < 0.0f) | |
111 { | |
112 value = 0.0f; | |
113 } | |
114 if (value > 65535.0f) | |
115 { | |
116 value = 65535.0f; | |
117 } | |
118 } | |
119 | |
120 for (unsigned int y = y1; y <= y2; y++) | |
121 { | |
122 float *q = reinterpret_cast<float*>(buffer.GetRow(y)) + x1; | |
123 const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)) + x1; | |
124 | |
125 for (unsigned int x = x1; x <= x2; x++, p++, q++) | |
126 { | |
127 float a = static_cast<float>(*p) / 255.0f; | |
128 | |
129 *q = (a * value + (1.0f - a) * (*q)); | |
130 } | |
131 } | |
132 } | |
133 | |
134 bool RadiographyAlphaLayer::GetRange(float& minValue, | |
135 float& maxValue) const | |
136 { | |
137 minValue = 0; | |
138 maxValue = 0; | |
139 | |
140 if (foreground_ < 0) | |
141 { | |
142 minValue = foreground_; | |
143 } | |
144 | |
145 if (foreground_ > 0) | |
146 { | |
147 maxValue = foreground_; | |
148 } | |
149 | |
150 return true; | |
151 } | |
152 } |