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)