Mercurial > hg > orthanc-stone
view Framework/Scene2D/LookupTableTextureSceneLayer.cpp @ 987:d225bccd4d4a
Scaffolding for A/B tests with DicomStructureSet[Loader] (A/B testing)
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 09 Sep 2019 15:18:24 +0200 |
parents | 11fc84650e4b |
children | 391fb6d6905d |
line wrap: on
line source
/** * Stone of Orthanc * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2019 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "LookupTableTextureSceneLayer.h" #include <Core/Images/Image.h> #include <Core/Images/ImageProcessing.h> #include <Core/OrthancException.h> namespace OrthancStone { static void StringToVector(std::vector<uint8_t>& target, const std::string& source) { target.resize(source.size()); for (size_t i = 0; i < source.size(); i++) { target[i] = source[i]; } } LookupTableTextureSceneLayer::LookupTableTextureSceneLayer(const Orthanc::ImageAccessor& texture) { { std::auto_ptr<Orthanc::ImageAccessor> t( new Orthanc::Image(Orthanc::PixelFormat_Float32, texture.GetWidth(), texture.GetHeight(), false)); Orthanc::ImageProcessing::Convert(*t, texture); SetTexture(t.release()); } SetLookupTableGrayscale(); SetRange(0, 1); } void LookupTableTextureSceneLayer::SetLookupTableGrayscale() { std::vector<uint8_t> rgb(3 * 256); for (size_t i = 0; i < 256; i++) { rgb[3 * i] = static_cast<uint8_t>(i); rgb[3 * i + 1] = static_cast<uint8_t>(i); rgb[3 * i + 2] = static_cast<uint8_t>(i); } SetLookupTableRgb(rgb); } void LookupTableTextureSceneLayer::SetLookupTableRgb(const std::vector<uint8_t>& lut) { if (lut.size() != 3 * 256) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } lut_.resize(4 * 256); for (size_t i = 0; i < 256; i++) { // Premultiplied alpha if (i == 0) { // Make zero transparent lut_[4 * i] = 0; // R lut_[4 * i + 1] = 0; // G lut_[4 * i + 2] = 0; // B lut_[4 * i + 3] = 0; // A } else { float a = static_cast<float>(i) / 255.0f; float r = static_cast<float>(lut[3 * i]) * a; float g = static_cast<float>(lut[3 * i + 1]) * a; float b = static_cast<float>(lut[3 * i + 2]) * a; lut_[4 * i] = static_cast<uint8_t>(std::floor(r)); lut_[4 * i + 1] = static_cast<uint8_t>(std::floor(g)); lut_[4 * i + 2] = static_cast<uint8_t>(std::floor(b)); lut_[4 * i + 3] = static_cast<uint8_t>(std::floor(a * 255.0f)); } } IncrementRevision(); } void LookupTableTextureSceneLayer::SetLookupTable(const std::vector<uint8_t>& lut) { if (lut.size() == 4 * 256) { lut_ = lut; IncrementRevision(); } else if (lut.size() == 3 * 256) { SetLookupTableRgb(lut); } else { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } } void LookupTableTextureSceneLayer::SetLookupTable(const std::string& lut) { std::vector<uint8_t> tmp; StringToVector(tmp, lut); SetLookupTable(tmp); } void LookupTableTextureSceneLayer::SetRange(float minValue, float maxValue) { if (minValue > maxValue) { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } else { minValue_ = minValue; maxValue_ = maxValue; IncrementRevision(); } } void LookupTableTextureSceneLayer::FitRange() { Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue_, maxValue_, GetTexture()); assert(minValue_ <= maxValue_); IncrementRevision(); } ISceneLayer* LookupTableTextureSceneLayer::Clone() const { std::auto_ptr<LookupTableTextureSceneLayer> cloned (new LookupTableTextureSceneLayer(GetTexture())); cloned->CopyParameters(*this); cloned->minValue_ = minValue_; cloned->maxValue_ = maxValue_; cloned->lut_ = lut_; return cloned.release(); } }