comparison Framework/Scene2D/Internals/CairoLookupTableTextureRenderer.cpp @ 768:55411e7da2f7

LookupTableTextureSceneLayer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 23 May 2019 20:04:33 +0200
parents
children 6e888cf6a48b
comparison
equal deleted inserted replaced
767:dce5b067d040 768:55411e7da2f7
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 "CairoLookupTableTextureRenderer.h"
23
24 #include "CairoColorTextureRenderer.h"
25 #include "../LookupTableTextureSceneLayer.h"
26
27 #include <Core/OrthancException.h>
28
29 namespace OrthancStone
30 {
31 namespace Internals
32 {
33 void CairoLookupTableTextureRenderer::Update(const ISceneLayer& layer)
34 {
35 const LookupTableTextureSceneLayer& l = dynamic_cast<const LookupTableTextureSceneLayer&>(layer);
36
37 textureTransform_ = l.GetTransform();
38 isLinearInterpolation_ = l.IsLinearInterpolation();
39
40 const float a = l.GetMinValue();
41 float slope;
42
43 if (l.GetMinValue() >= l.GetMaxValue())
44 {
45 slope = 0;
46 }
47 else
48 {
49 slope = 256.0f / (l.GetMaxValue() - l.GetMinValue());
50 }
51
52 const Orthanc::ImageAccessor& source = l.GetTexture();
53 const unsigned int width = source.GetWidth();
54 const unsigned int height = source.GetHeight();
55 texture_.SetSize(width, height, true /* alpha channel is enabled */);
56
57 Orthanc::ImageAccessor target;
58 texture_.GetWriteableAccessor(target);
59
60 const std::vector<uint8_t>& lut = l.GetLookupTable();
61 if (lut.size() != 4 * 256)
62 {
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
64 }
65
66 assert(source.GetFormat() == Orthanc::PixelFormat_Float32 &&
67 target.GetFormat() == Orthanc::PixelFormat_BGRA32 &&
68 sizeof(float) == 4);
69
70 for (unsigned int y = 0; y < height; y++)
71 {
72 const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
73 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
74
75 for (unsigned int x = 0; x < width; x++)
76 {
77 float v = (*p - a) * slope;
78 if (v <= 0)
79 {
80 v = 0;
81 }
82 else if (v >= 255)
83 {
84 v = 255;
85 }
86
87 uint8_t vv = static_cast<uint8_t>(v);
88
89 q[0] = lut[4 * vv + 2]; // B
90 q[1] = lut[4 * vv + 1]; // G
91 q[2] = lut[4 * vv + 0]; // R
92 q[3] = lut[4 * vv + 3]; // A
93
94 p++;
95 q += 4;
96 }
97 }
98
99 cairo_surface_mark_dirty(texture_.GetObject());
100 }
101
102 void CairoLookupTableTextureRenderer::Render(const AffineTransform2D& transform)
103 {
104 CairoColorTextureRenderer::RenderColorTexture(target_, transform, texture_,
105 textureTransform_, isLinearInterpolation_);
106 }
107 }
108 }