Mercurial > hg > orthanc-stone
comparison Framework/Radiography/RadiographyWidget.cpp @ 1196:a5f2a6b04a31
RadiographyScene: windowing is now only applied to the Dicom layer
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Wed, 27 Nov 2019 17:51:33 +0100 |
parents | 4663f158c748 |
children | 922d2e61aa5d |
comparison
equal
deleted
inserted
replaced
1191:c6a36ecd641d | 1196:a5f2a6b04a31 |
---|---|
68 | 68 |
69 bool RadiographyWidget::RenderInternal(unsigned int width, | 69 bool RadiographyWidget::RenderInternal(unsigned int width, |
70 unsigned int height, | 70 unsigned int height, |
71 ImageInterpolation interpolation) | 71 ImageInterpolation interpolation) |
72 { | 72 { |
73 float windowCenter, windowWidth; | 73 if (floatBuffer_.get() == NULL || |
74 scene_->GetWindowingWithDefault(windowCenter, windowWidth); | 74 floatBuffer_->GetWidth() != width || |
75 | 75 floatBuffer_->GetHeight() != height) |
76 float x0 = windowCenter - windowWidth / 2.0f; | 76 { |
77 float x1 = windowCenter + windowWidth / 2.0f; | 77 floatBuffer_.reset(new Orthanc::Image( |
78 | 78 Orthanc::PixelFormat_Float32, width, height, false)); |
79 if (windowWidth <= 0.001f) // Avoid division by zero at (*) | 79 } |
80 { | 80 |
81 return false; | 81 if (cairoBuffer_.get() == NULL || |
82 } | 82 cairoBuffer_->GetWidth() != width || |
83 else | 83 cairoBuffer_->GetHeight() != height) |
84 { | 84 { |
85 if (floatBuffer_.get() == NULL || | 85 cairoBuffer_.reset(new CairoSurface(width, height, false /* no alpha */)); |
86 floatBuffer_->GetWidth() != width || | 86 } |
87 floatBuffer_->GetHeight() != height) | 87 |
88 RenderBackground(*floatBuffer_, 0.0, 65535.0); | |
89 | |
90 scene_->Render(*floatBuffer_, GetView().GetMatrix(), interpolation, true); | |
91 | |
92 // Conversion from Float32 to BGRA32 (cairo). Very similar to | |
93 // GrayscaleFrameRenderer => TODO MERGE? | |
94 Orthanc::ImageAccessor target; | |
95 cairoBuffer_->GetWriteableAccessor(target); | |
96 | |
97 bool invert = IsInvertedInternal(); | |
98 | |
99 for (unsigned int y = 0; y < height; y++) | |
100 { | |
101 const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y)); | |
102 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); | |
103 | |
104 for (unsigned int x = 0; x < width; x++, p++, q += 4) | |
88 { | 105 { |
89 floatBuffer_.reset(new Orthanc::Image( | 106 uint8_t v = 0; |
90 Orthanc::PixelFormat_Float32, width, height, false)); | 107 if (*p >= 65535.0) |
108 { | |
109 v = 255; | |
110 } | |
111 else if (*p <= 0.0) | |
112 { | |
113 v = 0; | |
114 } | |
115 else | |
116 { | |
117 v = static_cast<uint8_t>(*p / 256.0); | |
118 } | |
119 | |
120 if (invert) | |
121 { | |
122 v = 255 - v; | |
123 } | |
124 | |
125 q[0] = v; | |
126 q[1] = v; | |
127 q[2] = v; | |
128 q[3] = 255; | |
91 } | 129 } |
92 | 130 } |
93 if (cairoBuffer_.get() == NULL || | 131 |
94 cairoBuffer_->GetWidth() != width || | 132 return true; |
95 cairoBuffer_->GetHeight() != height) | |
96 { | |
97 cairoBuffer_.reset(new CairoSurface(width, height, false /* no alpha */)); | |
98 } | |
99 | |
100 RenderBackground(*floatBuffer_, x0, x1); | |
101 | |
102 scene_->Render(*floatBuffer_, GetView().GetMatrix(), interpolation); | |
103 | |
104 // Conversion from Float32 to BGRA32 (cairo). Very similar to | |
105 // GrayscaleFrameRenderer => TODO MERGE? | |
106 | |
107 Orthanc::ImageAccessor target; | |
108 cairoBuffer_->GetWriteableAccessor(target); | |
109 | |
110 float scaling = 255.0f / (x1 - x0); | |
111 | |
112 bool invert = IsInvertedInternal(); | |
113 | |
114 for (unsigned int y = 0; y < height; y++) | |
115 { | |
116 const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y)); | |
117 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); | |
118 | |
119 for (unsigned int x = 0; x < width; x++, p++, q += 4) | |
120 { | |
121 uint8_t v = 0; | |
122 if (*p >= x1) | |
123 { | |
124 v = 255; | |
125 } | |
126 else if (*p <= x0) | |
127 { | |
128 v = 0; | |
129 } | |
130 else | |
131 { | |
132 // https://en.wikipedia.org/wiki/Linear_interpolation | |
133 v = static_cast<uint8_t>(scaling * (*p - x0)); // (*) | |
134 } | |
135 | |
136 if (invert) | |
137 { | |
138 v = 255 - v; | |
139 } | |
140 | |
141 q[0] = v; | |
142 q[1] = v; | |
143 q[2] = v; | |
144 q[3] = 255; | |
145 } | |
146 } | |
147 | |
148 return true; | |
149 } | |
150 } | 133 } |
151 | 134 |
152 | 135 |
153 bool RadiographyWidget::RenderScene(CairoContext& context, | 136 bool RadiographyWidget::RenderScene(CairoContext& context, |
154 const Deprecated::ViewportGeometry& view) | 137 const Deprecated::ViewportGeometry& view) |