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 }