comparison Framework/Deprecated/Radiography/RadiographySceneReader.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/RadiographySceneReader.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 "RadiographySceneReader.h"
23
24 #include "../Deprecated/Toolbox/DicomFrameConverter.h"
25
26 #include <Core/Images/FontRegistry.h>
27 #include <Core/Images/PngReader.h>
28 #include <Core/OrthancException.h>
29 #include <Core/Toolbox.h>
30
31 namespace OrthancStone
32 {
33
34 void RadiographySceneBuilder::Read(const Json::Value& input, Orthanc::ImageAccessor* dicomImage /* takes ownership */,
35 Deprecated::DicomFrameConverter* dicomFrameConverter /* takes ownership */,
36 RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode
37 )
38 {
39 dicomImage_.reset(dicomImage);
40 dicomFrameConverter_.reset(dicomFrameConverter);
41 preferredPhotometricDisplayMode_ = preferredPhotometricDisplayMode;
42 Read(input);
43 }
44
45 RadiographyDicomLayer* RadiographySceneBuilder::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
46 {
47 return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomImage(dicomImage_.release(), instanceId, frame, dicomFrameConverter_.release(), preferredPhotometricDisplayMode_, geometry)));
48 }
49
50
51 RadiographyDicomLayer* RadiographySceneReader::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
52 {
53 return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(orthancApiClient_, instanceId, frame, false, geometry)));
54 }
55
56 RadiographyDicomLayer* RadiographySceneGeometryReader::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
57 {
58 std::unique_ptr<RadiographyPlaceholderLayer> layer(new RadiographyPlaceholderLayer(scene_));
59 layer->SetGeometry(*geometry);
60 layer->SetSize(dicomImageWidth_, dicomImageHeight_);
61 scene_.RegisterLayer(layer.get());
62
63 return layer.release();
64 }
65
66 void RadiographySceneBuilder::Read(const Json::Value& input)
67 {
68 unsigned int version = input["version"].asUInt();
69
70 if (version != 1)
71 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
72
73 if (input.isMember("hasWindowing") && input["hasWindowing"].asBool())
74 {
75 scene_.SetWindowing(input["windowCenter"].asFloat(), input["windowWidth"].asFloat());
76 }
77
78 RadiographyDicomLayer* dicomLayer = NULL;
79 for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++)
80 {
81 const Json::Value& jsonLayer = input["layers"][(int)layerIndex];
82 RadiographyLayer::Geometry geometry;
83
84 if (jsonLayer["type"].asString() == "dicom")
85 {
86 ReadLayerGeometry(geometry, jsonLayer);
87 dicomLayer = LoadDicom(jsonLayer["instanceId"].asString(), jsonLayer["frame"].asUInt(), &geometry);
88 }
89 else if (jsonLayer["type"].asString() == "mask")
90 {
91 if (dicomLayer == NULL)
92 {
93 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // we always assumed the dicom layer was read before the mask
94 }
95 ReadLayerGeometry(geometry, jsonLayer);
96
97 float foreground = jsonLayer["foreground"].asFloat();
98 std::vector<Orthanc::ImageProcessing::ImagePoint> corners;
99 for (size_t i = 0; i < jsonLayer["corners"].size(); i++)
100 {
101 Orthanc::ImageProcessing::ImagePoint corner(jsonLayer["corners"][(int)i]["x"].asInt(),
102 jsonLayer["corners"][(int)i]["y"].asInt());
103 corners.push_back(corner);
104 }
105
106 scene_.LoadMask(corners, *dicomLayer, foreground, &geometry);
107 }
108 else if (jsonLayer["type"].asString() == "text")
109 {
110 ReadLayerGeometry(geometry, jsonLayer);
111 scene_.LoadText(jsonLayer["text"].asString(), jsonLayer["font"].asString(), jsonLayer["fontSize"].asUInt(), static_cast<uint8_t>(jsonLayer["foreground"].asUInt()), &geometry, false);
112 }
113 else if (jsonLayer["type"].asString() == "alpha")
114 {
115 ReadLayerGeometry(geometry, jsonLayer);
116
117 const std::string& pngContentBase64 = jsonLayer["content"].asString();
118 std::string pngContent;
119 std::string mimeType;
120 Orthanc::Toolbox::DecodeDataUriScheme(mimeType, pngContent, pngContentBase64);
121
122 std::unique_ptr<Orthanc::ImageAccessor> image;
123 if (mimeType == "image/png")
124 {
125 image.reset(new Orthanc::PngReader());
126 dynamic_cast<Orthanc::PngReader*>(image.get())->ReadFromMemory(pngContent);
127 }
128 else
129 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
130
131 RadiographyAlphaLayer& layer = dynamic_cast<RadiographyAlphaLayer&>(scene_.LoadAlphaBitmap(image.release(), &geometry));
132
133 if (!jsonLayer["isUsingWindowing"].asBool())
134 {
135 layer.SetForegroundValue((float)(jsonLayer["foreground"].asDouble()));
136 }
137 }
138 else
139 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
140 }
141 }
142
143
144
145
146 void RadiographySceneBuilder::ReadDicomLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& input)
147 {
148 for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++)
149 {
150 const Json::Value& jsonLayer = input["layers"][(int)layerIndex];
151 if (jsonLayer["type"].asString() == "dicom")
152 {
153 ReadLayerGeometry(geometry, jsonLayer);
154 return;
155 }
156 }
157 }
158
159 void RadiographySceneBuilder::ReadLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& jsonLayer)
160 {
161 {// crop
162 unsigned int x, y, width, height;
163 if (jsonLayer["crop"]["hasCrop"].asBool())
164 {
165 x = jsonLayer["crop"]["x"].asUInt();
166 y = jsonLayer["crop"]["y"].asUInt();
167 width = jsonLayer["crop"]["width"].asUInt();
168 height = jsonLayer["crop"]["height"].asUInt();
169 geometry.SetCrop(x, y, width, height);
170 }
171 }
172
173 geometry.SetAngle(jsonLayer["angle"].asDouble());
174 geometry.SetResizeable(jsonLayer["isResizable"].asBool());
175 geometry.SetPan(jsonLayer["pan"]["x"].asDouble(), jsonLayer["pan"]["y"].asDouble());
176 geometry.SetPixelSpacing(jsonLayer["pixelSpacing"]["x"].asDouble(), jsonLayer["pixelSpacing"]["y"].asDouble());
177
178 // these fields were introduced later -> they might not exist
179 if (jsonLayer.isMember("flipVertical"))
180 {
181 geometry.SetFlipVertical(jsonLayer["flipVertical"].asBool());
182 }
183 if (jsonLayer.isMember("flipHorizontal"))
184 {
185 geometry.SetFlipHorizontal(jsonLayer["flipHorizontal"].asBool());
186 }
187
188 }
189 }