comparison Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp @ 841:266e2b0b9abc

better error reporting in DicomStructureSetLoader + fixed POST request logic in WebAssemblyOracle + support for LookupTableTextureSceneLayer in OpenGL (NOT using shaders!) (2 new files) + a few small non-functional changes
author Benjamin Golinvaux <bgo@osimis.io>
date Tue, 11 Jun 2019 15:41:21 +0200
parents
children 6e888cf6a48b
comparison
equal deleted inserted replaced
840:47fc7919977d 841:266e2b0b9abc
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 "OpenGLLookupTableTextureRenderer.h"
23
24 namespace OrthancStone
25 {
26 namespace Internals
27 {
28 void OpenGLLookupTableTextureRenderer::LoadTexture(
29 const LookupTableTextureSceneLayer& layer)
30 {
31 const Orthanc::ImageAccessor& source = layer.GetTexture();
32 const unsigned int width = source.GetWidth();
33 const unsigned int height = source.GetHeight();
34
35 if ((texture_.get() == NULL) ||
36 (texture_->GetWidth() != width) ||
37 (texture_->GetHeight() != height))
38 {
39
40 texture_.reset(new Orthanc::Image(
41 Orthanc::PixelFormat_RGBA32,
42 width,
43 height,
44 false));
45 }
46
47 {
48
49 const float a = layer.GetMinValue();
50 float slope = 0;
51
52 if (layer.GetMinValue() >= layer.GetMaxValue())
53 {
54 slope = 0;
55 }
56 else
57 {
58 slope = 256.0f / (layer.GetMaxValue() - layer.GetMinValue());
59 }
60
61 Orthanc::ImageAccessor target;
62 texture_->GetWriteableAccessor(target);
63
64 const std::vector<uint8_t>& lut = layer.GetLookupTable();
65 if (lut.size() != 4 * 256)
66 {
67 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
68 }
69
70 assert(source.GetFormat() == Orthanc::PixelFormat_Float32 &&
71 target.GetFormat() == Orthanc::PixelFormat_RGBA32 &&
72 sizeof(float) == 4);
73
74 for (unsigned int y = 0; y < height; y++)
75 {
76 const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
77 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
78
79 for (unsigned int x = 0; x < width; x++)
80 {
81 float v = (*p - a) * slope;
82 if (v <= 0)
83 {
84 v = 0;
85 }
86 else if (v >= 255)
87 {
88 v = 255;
89 }
90
91 uint8_t vv = static_cast<uint8_t>(v);
92
93 q[0] = lut[4 * vv + 0]; // R
94 q[1] = lut[4 * vv + 1]; // G
95 q[2] = lut[4 * vv + 2]; // B
96 q[3] = lut[4 * vv + 3]; // A
97
98 p++;
99 q += 4;
100 }
101 }
102 }
103
104 context_.MakeCurrent();
105 glTexture_.reset(new OpenGL::OpenGLTexture);
106 glTexture_->Load(*texture_, layer.IsLinearInterpolation());
107 layerTransform_ = layer.GetTransform();
108 }
109
110
111 OpenGLLookupTableTextureRenderer::OpenGLLookupTableTextureRenderer(
112 OpenGL::IOpenGLContext& context,
113 OpenGLColorTextureProgram& program,
114 const LookupTableTextureSceneLayer& layer)
115 : context_(context)
116 , program_(program)
117 {
118 LoadTexture(layer);
119 }
120
121
122 void OpenGLLookupTableTextureRenderer::Render(const AffineTransform2D& transform)
123 {
124 if (glTexture_.get() != NULL)
125 {
126 program_.Apply(
127 *glTexture_,
128 AffineTransform2D::Combine(transform, layerTransform_),
129 true);
130 }
131 }
132
133
134 void OpenGLLookupTableTextureRenderer::Update(const ISceneLayer& layer)
135 {
136 // Should never happen (no revisions in color textures)
137 LoadTexture(dynamic_cast<const LookupTableTextureSceneLayer&>(layer));
138 }
139 }
140 }