Mercurial > hg > orthanc-stone
comparison Framework/Layers/OrthancFrameLayerSource.cpp @ 66:298f375dcb68 wasm
LayerWidget
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 17 May 2017 22:03:09 +0200 |
parents | 885932a893de |
children | f5f54ed8d307 |
comparison
equal
deleted
inserted
replaced
65:885932a893de | 66:298f375dcb68 |
---|---|
63 OrthancFrameLayerSource::OrthancFrameLayerSource(IWebService& orthanc, | 63 OrthancFrameLayerSource::OrthancFrameLayerSource(IWebService& orthanc, |
64 const std::string& instanceId, | 64 const std::string& instanceId, |
65 unsigned int frame) : | 65 unsigned int frame) : |
66 orthanc_(orthanc), | 66 orthanc_(orthanc), |
67 instanceId_(instanceId), | 67 instanceId_(instanceId), |
68 frame_(frame) | 68 frame_(frame), |
69 frameWidth_(0), | |
70 frameHeight_(0), | |
71 pixelSpacingX_(1), | |
72 pixelSpacingY_(1), | |
73 observer2_(NULL) | |
74 { | |
75 } | |
76 | |
77 | |
78 void OrthancFrameLayerSource::StartInternal() | |
69 { | 79 { |
70 orthanc_.ScheduleGetRequest(*this, | 80 orthanc_.ScheduleGetRequest(*this, |
71 "/instances/" + instanceId + "/tags", | 81 "/instances/" + instanceId_ + "/tags", |
72 new Operation(Content_Tags)); | 82 new Operation(Content_Tags)); |
73 } | 83 } |
74 | 84 |
75 | 85 |
76 void OrthancFrameLayerSource::SetObserver(IObserver& observer) | 86 void OrthancFrameLayerSource::SetObserver(IObserver& observer) |
77 { | 87 { |
78 LayerSourceBase::SetObserver(observer); | 88 LayerSourceBase::SetObserver(observer); |
79 | 89 |
80 if (dataset_.get() != NULL) | 90 if (dataset_.get() != NULL) |
81 { | 91 { |
82 NotifySourceChange(); | 92 NotifySourceChange(); |
83 } | 93 } |
84 } | 94 } |
95 | |
96 | |
97 void OrthancFrameLayerSource::SetObserver(IVolumeSlicesObserver& observer) | |
98 { | |
99 if (IsStarted()) | |
100 { | |
101 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
102 } | |
103 | |
104 if (observer2_ == NULL) | |
105 { | |
106 observer2_ = &observer; | |
107 } | |
108 else | |
109 { | |
110 // Cannot add more than one observer | |
111 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
112 } | |
113 } | |
114 | |
85 | 115 |
86 void OrthancFrameLayerSource::NotifyError(const std::string& uri, | 116 void OrthancFrameLayerSource::NotifyError(const std::string& uri, |
87 Orthanc::IDynamicObject* payload) | 117 Orthanc::IDynamicObject* payload) |
88 { | 118 { |
119 std::auto_ptr<Operation> operation(reinterpret_cast<Operation*>(payload)); | |
120 | |
89 LOG(ERROR) << "Cannot download " << uri; | 121 LOG(ERROR) << "Cannot download " << uri; |
90 } | 122 NotifyLayerError(operation->GetViewportSlice()); |
123 } | |
124 | |
91 | 125 |
92 void OrthancFrameLayerSource::NotifySuccess(const std::string& uri, | 126 void OrthancFrameLayerSource::NotifySuccess(const std::string& uri, |
93 const void* answer, | 127 const void* answer, |
94 size_t answerSize, | 128 size_t answerSize, |
95 Orthanc::IDynamicObject* payload) | 129 Orthanc::IDynamicObject* payload) |
105 dataset_.reset(new OrthancPlugins::FullOrthancDataset(answer, answerSize)); | 139 dataset_.reset(new OrthancPlugins::FullOrthancDataset(answer, answerSize)); |
106 | 140 |
107 DicomFrameConverter converter; | 141 DicomFrameConverter converter; |
108 converter.ReadParameters(*dataset_); | 142 converter.ReadParameters(*dataset_); |
109 format_ = converter.GetExpectedPixelFormat(); | 143 format_ = converter.GetExpectedPixelFormat(); |
110 | 144 GeometryToolbox::GetPixelSpacing(pixelSpacingX_, pixelSpacingY_, *dataset_); |
111 NotifySourceChange(); | 145 |
146 OrthancPlugins::DicomDatasetReader reader(*dataset_); | |
147 if (!reader.GetUnsignedIntegerValue(frameWidth_, OrthancPlugins::DICOM_TAG_COLUMNS) || | |
148 !reader.GetUnsignedIntegerValue(frameHeight_, OrthancPlugins::DICOM_TAG_ROWS)) | |
149 { | |
150 frameWidth_ = 0; | |
151 frameHeight_ = 0; | |
152 LOG(WARNING) << "Missing tags in a DICOM image: Columns or Rows"; | |
153 } | |
154 | |
155 if (observer2_ != NULL) | |
156 { | |
157 ParallelSlices slices; | |
158 slices.AddSlice(SliceGeometry(*dataset_)); | |
159 observer2_->NotifySlicesAvailable(slices); | |
160 } | |
161 | |
162 NotifyGeometryReady(); | |
112 } | 163 } |
113 else if (operation->GetContent() == Content_Frame) | 164 else if (operation->GetContent() == Content_Frame) |
114 { | 165 { |
115 std::auto_ptr<Orthanc::PngReader> image(new Orthanc::PngReader); | 166 std::auto_ptr<Orthanc::PngReader> image(new Orthanc::PngReader); |
116 image->ReadFromMemory(answer, answerSize); | 167 image->ReadFromMemory(answer, answerSize); |
117 | 168 |
118 if (format_ == Orthanc::PixelFormat_SignedGrayscale16) | 169 bool ok = (image->GetWidth() == frameWidth_ || |
170 image->GetHeight() == frameHeight_); | |
171 | |
172 if (ok && | |
173 format_ == Orthanc::PixelFormat_SignedGrayscale16) | |
119 { | 174 { |
120 if (image->GetFormat() == Orthanc::PixelFormat_Grayscale16) | 175 if (image->GetFormat() == Orthanc::PixelFormat_Grayscale16) |
121 { | 176 { |
122 image->SetFormat(Orthanc::PixelFormat_SignedGrayscale16); | 177 image->SetFormat(Orthanc::PixelFormat_SignedGrayscale16); |
123 } | 178 } |
124 else | 179 else |
125 { | 180 { |
126 NotifyLayerReady(NULL, *this, operation->GetViewportSlice()); | 181 ok = false; |
127 } | 182 } |
128 } | 183 } |
129 | 184 |
130 SliceGeometry frameSlice(*dataset_); | 185 if (ok) |
131 NotifyLayerReady(FrameRenderer::CreateRenderer(image.release(), | 186 { |
132 operation->GetViewportSlice(), | 187 SliceGeometry frameSlice(*dataset_); |
133 frameSlice, *dataset_, 1, 1, true), | 188 NotifyLayerReady(FrameRenderer::CreateRenderer(image.release(), |
134 *this, operation->GetViewportSlice()); | 189 operation->GetViewportSlice(), |
190 frameSlice, *dataset_, | |
191 pixelSpacingX_, pixelSpacingY_, true), | |
192 operation->GetViewportSlice()); | |
193 } | |
194 else | |
195 { | |
196 NotifyLayerError(operation->GetViewportSlice()); | |
197 } | |
135 } | 198 } |
136 else | 199 else |
137 { | 200 { |
138 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 201 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
139 } | 202 } |
144 double& y1, | 207 double& y1, |
145 double& x2, | 208 double& x2, |
146 double& y2, | 209 double& y2, |
147 const SliceGeometry& viewportSlice /* ignored */) | 210 const SliceGeometry& viewportSlice /* ignored */) |
148 { | 211 { |
212 if (!IsStarted() || | |
213 dataset_.get() == NULL) | |
214 { | |
215 return false; | |
216 } | |
217 else | |
218 { | |
219 SliceGeometry frameSlice(*dataset_); | |
220 return FrameRenderer::ComputeFrameExtent(x1, y1, x2, y2, | |
221 viewportSlice, frameSlice, | |
222 frameWidth_, frameHeight_, | |
223 pixelSpacingX_, pixelSpacingY_); | |
224 } | |
225 } | |
226 | |
227 | |
228 void OrthancFrameLayerSource::ScheduleLayerCreation(const SliceGeometry& viewportSlice) | |
229 { | |
230 if (!IsStarted()) | |
231 { | |
232 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
233 } | |
234 | |
149 if (dataset_.get() == NULL) | 235 if (dataset_.get() == NULL) |
150 { | 236 { |
151 return false; | 237 NotifyLayerError(viewportSlice); |
152 } | |
153 else | |
154 { | |
155 // Assume that PixelSpacingX == PixelSpacingY == 1 | |
156 | |
157 OrthancPlugins::DicomDatasetReader reader(*dataset_); | |
158 | |
159 unsigned int width, height; | |
160 | |
161 if (!reader.GetUnsignedIntegerValue(width, OrthancPlugins::DICOM_TAG_COLUMNS) || | |
162 !reader.GetUnsignedIntegerValue(height, OrthancPlugins::DICOM_TAG_ROWS)) | |
163 { | |
164 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | |
165 } | |
166 | |
167 x1 = 0; | |
168 y1 = 0; | |
169 x2 = static_cast<double>(width); | |
170 y2 = static_cast<double>(height); | |
171 | |
172 return true; | |
173 } | |
174 } | |
175 | |
176 | |
177 void OrthancFrameLayerSource::ScheduleLayerCreation(const SliceGeometry& viewportSlice) | |
178 { | |
179 if (dataset_.get() == NULL) | |
180 { | |
181 NotifyLayerReady(NULL, *this, viewportSlice); | |
182 } | 238 } |
183 else | 239 else |
184 { | 240 { |
185 std::string uri = ("/instances/" + instanceId_ + "/frames/" + | 241 std::string uri = ("/instances/" + instanceId_ + "/frames/" + |
186 boost::lexical_cast<std::string>(frame_)); | 242 boost::lexical_cast<std::string>(frame_)); |