Mercurial > hg > orthanc-stone
changeset 2229:8cbf31382b7b
added class BitmapLayout
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 25 Apr 2025 17:39:22 +0200 |
parents | 0191a7693b50 |
children | cbad54feb881 |
files | OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake OrthancStone/Sources/Fonts/GlyphAlphabet.cpp OrthancStone/Sources/Toolbox/BitmapLayout.cpp OrthancStone/Sources/Toolbox/BitmapLayout.h OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp OrthancStone/Sources/Toolbox/DicomStructuredReport.h OrthancStone/UnitTestsSources/ImageToolboxTests.cpp |
diffstat | 7 files changed, 252 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 25 14:22:20 2025 +0200 +++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 25 17:39:22 2025 +0200 @@ -320,6 +320,7 @@ ${ORTHANC_STONE_ROOT}/StoneInitialization.cpp ${ORTHANC_STONE_ROOT}/Toolbox/AffineTransform2D.cpp + ${ORTHANC_STONE_ROOT}/Toolbox/BitmapLayout.cpp ${ORTHANC_STONE_ROOT}/Toolbox/BucketAccumulator1D.cpp ${ORTHANC_STONE_ROOT}/Toolbox/BucketAccumulator2D.cpp ${ORTHANC_STONE_ROOT}/Toolbox/CoordinateSystem3D.cpp
--- a/OrthancStone/Sources/Fonts/GlyphAlphabet.cpp Fri Apr 25 14:22:20 2025 +0200 +++ b/OrthancStone/Sources/Fonts/GlyphAlphabet.cpp Fri Apr 25 17:39:22 2025 +0200 @@ -267,8 +267,7 @@ size_t pos = 0; while (pos < source.size()) { - if (source[pos] == ' ' || - (ignoreDeviceControl && IsDeviceControlCharacter(source[pos]))) + if (source[pos] == ' ') { pos++; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Toolbox/BitmapLayout.cpp Fri Apr 25 17:39:22 2025 +0200 @@ -0,0 +1,149 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + **/ + + +#include "BitmapLayout.h" + +#include <Images/Image.h> +#include <Images/ImageProcessing.h> +#include <OrthancException.h> + +#include <cassert> + +namespace OrthancStone +{ + class BitmapLayout::Block : public boost::noncopyable + { + private: + int x_; + int y_; + std::unique_ptr<Orthanc::ImageAccessor> bitmap_; + + public: + Block(int x, + int y, + Orthanc::ImageAccessor* bitmap) : + x_(x), + y_(y), + bitmap_(bitmap) + { + if (bitmap == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + } + + int GetX() const + { + return x_; + } + + int GetY() const + { + return y_; + } + + const Orthanc::ImageAccessor& GetBitmap() const + { + return *bitmap_; + } + }; + + + BitmapLayout::BitmapLayout() : + left_(0), + top_(0), + right_(0), + bottom_(0) + { + } + + + BitmapLayout::~BitmapLayout() + { + for (Blocks::iterator it = blocks_.begin(); it != blocks_.end(); ++it) + { + assert(*it != NULL); + delete *it; + } + } + + + unsigned int BitmapLayout::GetWidth() const + { + assert(left_ <= right_); + return static_cast<unsigned int>(right_ - left_ + 1); + } + + + unsigned int BitmapLayout::GetHeight() const + { + assert(top_ <= bottom_); + return static_cast<unsigned int>(bottom_ - top_ + 1); + } + + + const Orthanc::ImageAccessor& BitmapLayout::AddBlock(int x, + int y, + Orthanc::ImageAccessor* bitmap) + { + if (bitmap == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + + blocks_.push_back(new Block(x, y, bitmap)); + + left_ = std::min(left_, x); + top_ = std::min(top_, x); + right_ = std::max(right_, x + static_cast<int>(bitmap->GetWidth()) - 1); + bottom_ = std::max(bottom_, y + static_cast<int>(bitmap->GetHeight()) - 1); + + return *bitmap; + } + + + Orthanc::ImageAccessor* BitmapLayout::Render(Orthanc::PixelFormat format) const + { + std::unique_ptr<Orthanc::ImageAccessor> layout( + new Orthanc::Image(format, GetWidth(), GetHeight(), true /* to be used as OpenGL texture */)); + + Orthanc::ImageProcessing::Set(*layout, 0); + + for (Blocks::const_iterator it = blocks_.begin(); it != blocks_.end(); ++it) + { + assert(*it != NULL); + + Orthanc::ImageAccessor region; + assert((*it)->GetX() >= GetLeft()); + assert((*it)->GetY() >= GetTop()); + + layout->GetRegion(region, static_cast<unsigned int>((*it)->GetX() + GetLeft()), + static_cast<unsigned int>((*it)->GetY() + GetTop()), + (*it)->GetBitmap().GetWidth(), (*it)->GetBitmap().GetHeight()); + + Orthanc::ImageProcessing::Convert(region, (*it)->GetBitmap()); + } + + return layout.release(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OrthancStone/Sources/Toolbox/BitmapLayout.h Fri Apr 25 17:39:22 2025 +0200 @@ -0,0 +1,80 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <Images/ImageAccessor.h> + +#include <list> + +namespace OrthancStone +{ + class BitmapLayout : public boost::noncopyable + { + private: + class Block; + + typedef std::list<Block*> Blocks; + + Blocks blocks_; + int left_; + int top_; + int right_; + int bottom_; + + public: + BitmapLayout(); + + ~BitmapLayout(); + + int GetLeft() const + { + return left_; + } + + int GetTop() const + { + return top_; + } + + int GetRight() const + { + return right_; + } + + int GetBottom() const + { + return bottom_; + } + + unsigned int GetWidth() const; + + unsigned int GetHeight() const; + + const Orthanc::ImageAccessor& AddBlock(int x, + int y, + Orthanc::ImageAccessor* bitmap /* takes ownership */); + + Orthanc::ImageAccessor* Render(Orthanc::PixelFormat format) const; + }; +}
--- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Fri Apr 25 14:22:20 2025 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Fri Apr 25 17:39:22 2025 +0200 @@ -654,6 +654,19 @@ CheckStringValue(dataset, DCM_Modality, "SR"); + title_ = mainDicomTags_.GetStringValue(Orthanc::DICOM_TAG_SERIES_DESCRIPTION, "?", false); + + if (dataset.tagExists(DCM_ConceptNameCodeSequence)) + { + DcmSequenceOfItems& concepts = GetSequenceValue(dataset, DCM_ConceptNameCodeSequence); + if (concepts.card() == 1 && + concepts.getItem(0) != NULL && + concepts.getItem(0)->tagExists(DCM_CodeMeaning)) + { + title_ = GetStringValue(*concepts.getItem(0), DCM_CodeMeaning); + } + } + ReadTextualReport(textualReport_, dataset); if (IsDicomConcept(dataset, "126000") /* Imaging measurement report */ &&
--- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.h Fri Apr 25 14:22:20 2025 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.h Fri Apr 25 17:39:22 2025 +0200 @@ -210,6 +210,7 @@ std::string studyInstanceUid_; std::string seriesInstanceUid_; std::string sopInstanceUid_; + std::string title_; Orthanc::DicomMap mainDicomTags_; Json::Value textualReport_; @@ -289,6 +290,11 @@ return sopInstanceUid_; } + const std::string& GetTitle() const + { + return title_; + } + const Orthanc::DicomMap& GetMainDicomTags() const { return mainDicomTags_;
--- a/OrthancStone/UnitTestsSources/ImageToolboxTests.cpp Fri Apr 25 14:22:20 2025 +0200 +++ b/OrthancStone/UnitTestsSources/ImageToolboxTests.cpp Fri Apr 25 17:39:22 2025 +0200 @@ -292,4 +292,6 @@ OrthancStone::GlyphAlphabet::IndentUtf8(s, "X A\021B\022C\r\023D\024E Y", 11, false); ASSERT_EQ("X A\021B\022C\023D\024E\nY", s); OrthancStone::GlyphAlphabet::IndentUtf8(s, "X A\021B\022C\r\023D\024E Y", 12, false); ASSERT_EQ("X A\021B\022C\023D\024E\nY", s); OrthancStone::GlyphAlphabet::IndentUtf8(s, "X A\021B\022C\r\023D\024E Y", 13, false); ASSERT_EQ("X A\021B\022C\023D\024E Y", s); + + OrthancStone::GlyphAlphabet::IndentUtf8(s, "\021Type:\022 Value", 20, false); ASSERT_EQ("\021Type:\022 Value", s); }