comparison Framework/Deprecated/Layers/GrayscaleFrameRenderer.cpp @ 732:c35e98d22764

move Deprecated classes to a separate folder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 21 May 2019 14:27:35 +0200
parents Framework/Layers/GrayscaleFrameRenderer.cpp@4f2416d519b4
children 2d8ab34c8c91
comparison
equal deleted inserted replaced
729:529189f399ec 732:c35e98d22764
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-2019 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 "GrayscaleFrameRenderer.h"
23
24 #include <Core/Images/Image.h>
25 #include <Core/OrthancException.h>
26
27 namespace Deprecated
28 {
29 OrthancStone::CairoSurface* GrayscaleFrameRenderer::GenerateDisplay(const RenderStyle& style)
30 {
31 assert(frame_->GetFormat() == Orthanc::PixelFormat_Float32);
32
33 std::auto_ptr<OrthancStone::CairoSurface> result;
34
35 float windowCenter, windowWidth;
36 style.ComputeWindowing(windowCenter, windowWidth,
37 defaultWindowCenter_, defaultWindowWidth_);
38
39 float x0 = windowCenter - windowWidth / 2.0f;
40 float x1 = windowCenter + windowWidth / 2.0f;
41
42 //LOG(INFO) << "Window: " << x0 << " => " << x1;
43
44 result.reset(new OrthancStone::CairoSurface(frame_->GetWidth(), frame_->GetHeight(), false /* no alpha */));
45
46 const uint8_t* lut = NULL;
47 if (style.applyLut_)
48 {
49 if (Orthanc::EmbeddedResources::GetFileResourceSize(style.lut_) != 3 * 256)
50 {
51 // Invalid colormap
52 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
53 }
54
55 lut = reinterpret_cast<const uint8_t*>(Orthanc::EmbeddedResources::GetFileResourceBuffer(style.lut_));
56 }
57
58 Orthanc::ImageAccessor target;
59 result->GetWriteableAccessor(target);
60
61 const unsigned int width = target.GetWidth();
62 const unsigned int height = target.GetHeight();
63
64 for (unsigned int y = 0; y < height; y++)
65 {
66 const float* p = reinterpret_cast<const float*>(frame_->GetConstRow(y));
67 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
68
69 for (unsigned int x = 0; x < width; x++, p++, q += 4)
70 {
71 uint8_t v = 0;
72 if (windowWidth >= 0.001f) // Avoid division by zero
73 {
74 if (*p >= x1)
75 {
76 v = 255;
77 }
78 else if (*p <= x0)
79 {
80 v = 0;
81 }
82 else
83 {
84 // https://en.wikipedia.org/wiki/Linear_interpolation
85 v = static_cast<uint8_t>(255.0f * (*p - x0) / (x1 - x0));
86 }
87
88 if (style.reverse_ ^ (photometric_ == Orthanc::PhotometricInterpretation_Monochrome1))
89 {
90 v = 255 - v;
91 }
92 }
93
94 if (style.applyLut_)
95 {
96 assert(lut != NULL);
97 q[3] = 255;
98 q[2] = lut[3 * v];
99 q[1] = lut[3 * v + 1];
100 q[0] = lut[3 * v + 2];
101 }
102 else
103 {
104 q[3] = 255;
105 q[2] = v;
106 q[1] = v;
107 q[0] = v;
108 }
109 }
110 }
111
112 return result.release();
113 }
114
115
116 GrayscaleFrameRenderer::GrayscaleFrameRenderer(const Orthanc::ImageAccessor& frame,
117 const Deprecated::DicomFrameConverter& converter,
118 const OrthancStone::CoordinateSystem3D& framePlane,
119 double pixelSpacingX,
120 double pixelSpacingY,
121 bool isFullQuality) :
122 FrameRenderer(framePlane, pixelSpacingX, pixelSpacingY, isFullQuality),
123 frame_(Orthanc::Image::Clone(frame)),
124 defaultWindowCenter_(static_cast<float>(converter.GetDefaultWindowCenter())),
125 defaultWindowWidth_(static_cast<float>(converter.GetDefaultWindowWidth())),
126 photometric_(converter.GetPhotometricInterpretation())
127 {
128 if (frame_.get() == NULL)
129 {
130 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
131 }
132
133 converter.ConvertFrameInplace(frame_);
134 assert(frame_.get() != NULL);
135
136 if (frame_->GetFormat() != Orthanc::PixelFormat_Float32)
137 {
138 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
139 }
140 }
141 }