# HG changeset patch # User Benjamin Golinvaux # Date 1559061104 -7200 # Node ID bc7ee59420a1aba29c21f44f995eb80d13303235 # Parent abc08ac721d37ee70b8292b30efa96b714b3150b# Parent ffec76a5f7eb0f2e37c347bfd5707248da4ab29a merge diff -r abc08ac721d3 -r bc7ee59420a1 Applications/Sdl/SdlCairoSurface.h --- a/Applications/Sdl/SdlCairoSurface.h Tue May 28 18:31:17 2019 +0200 +++ b/Applications/Sdl/SdlCairoSurface.h Tue May 28 18:31:44 2019 +0200 @@ -24,7 +24,7 @@ #if ORTHANC_ENABLE_SDL == 1 #include "SdlWindow.h" -#include "../../Framework/Viewport/CairoSurface.h" +#include "../../Framework/Wrappers/CairoSurface.h" #include "../../Framework/Deprecated/Viewport/IViewport.h" #include diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Layers/ILayerRenderer.h --- a/Framework/Deprecated/Layers/ILayerRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Deprecated/Layers/ILayerRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoContext.h" +#include "../../Wrappers/CairoContext.h" #include "../../Toolbox/CoordinateSystem3D.h" #include "../Toolbox/ViewportGeometry.h" #include "RenderStyle.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ISeriesLoader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Toolbox/ISeriesLoader.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,59 @@ +/** + * 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 . + **/ + + +#pragma once + +#include "ParallelSlices.h" + +#include +#include + +namespace Deprecated +{ + class ISeriesLoader : public boost::noncopyable + { + public: + virtual ~ISeriesLoader() + { + } + + virtual ParallelSlices& GetGeometry() = 0; + + virtual Orthanc::PixelFormat GetPixelFormat() = 0; + + virtual unsigned int GetWidth() = 0; + + virtual unsigned int GetHeight() = 0; + + virtual OrthancPlugins::IDicomDataset* DownloadDicom(size_t index) = 0; + + // This downloads the frame from Orthanc. The resulting pixel + // format must be Grayscale8, Grayscale16, SignedGrayscale16 or + // RGB24. Orthanc Stone assumes the conversion of the photometric + // interpretation is done by Orthanc. + virtual Orthanc::ImageAccessor* DownloadFrame(size_t index) = 0; + + virtual Orthanc::ImageAccessor* DownloadJpegFrame(size_t index, + unsigned int quality) = 0; + + virtual bool IsJpegAvailable() = 0; + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ParallelSlices.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Toolbox/ParallelSlices.cpp Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,215 @@ +/** + * 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 . + **/ + + +#include "ParallelSlices.h" + +#include "../../Toolbox/GeometryToolbox.h" +#include "../../Volumes/ImageBuffer3D.h" + +#include +#include + +namespace Deprecated +{ + ParallelSlices::ParallelSlices() + { + Clear(); + } + + + ParallelSlices::ParallelSlices(const ParallelSlices& other) + { + normal_ = other.normal_; + + slices_.resize(other.slices_.size()); + + for (size_t i = 0; i < slices_.size(); i++) + { + assert(other.slices_[i] != NULL); + slices_[i] = new OrthancStone::CoordinateSystem3D(*other.slices_[i]); + } + } + + + void ParallelSlices::Clear() + { + for (size_t i = 0; i < slices_.size(); i++) + { + if (slices_[i] != NULL) + { + delete slices_[i]; + slices_[i] = NULL; + } + } + + slices_.clear(); + OrthancStone::LinearAlgebra::AssignVector(normal_, 0, 0, 1); + } + + + ParallelSlices::~ParallelSlices() + { + Clear(); + } + + + void ParallelSlices::AddSlice(const OrthancStone::CoordinateSystem3D& slice) + { + if (slices_.empty()) + { + normal_ = slice.GetNormal(); + slices_.push_back(new OrthancStone::CoordinateSystem3D(slice)); + } + else if (OrthancStone::GeometryToolbox::IsParallel(slice.GetNormal(), normal_)) + { + slices_.push_back(new OrthancStone::CoordinateSystem3D(slice)); + } + else + { + LOG(ERROR) << "Trying to add a slice that is not parallel to the previous ones"; + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } + + + void ParallelSlices::AddSlice(const OrthancStone::Vector& origin, + const OrthancStone::Vector& axisX, + const OrthancStone::Vector& axisY) + { + OrthancStone::CoordinateSystem3D slice(origin, axisX, axisY); + AddSlice(slice); + } + + + const OrthancStone::CoordinateSystem3D& ParallelSlices::GetSlice(size_t index) const + { + if (index >= slices_.size()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + return *slices_[index]; + } + } + + + bool ParallelSlices::ComputeClosestSlice(size_t& closestSlice, + double& closestDistance, + const OrthancStone::Vector& origin) const + { + if (slices_.empty()) + { + return false; + } + + double reference = boost::numeric::ublas::inner_prod(origin, normal_); + + closestSlice = 0; + closestDistance = std::numeric_limits::infinity(); + + for (size_t i = 0; i < slices_.size(); i++) + { + double distance = fabs(boost::numeric::ublas::inner_prod(slices_[i]->GetOrigin(), normal_) - reference); + + if (distance < closestDistance) + { + closestSlice = i; + closestDistance = distance; + } + } + + return true; + } + + + ParallelSlices* ParallelSlices::Reverse() const + { + std::auto_ptr reversed(new ParallelSlices); + + for (size_t i = slices_.size(); i > 0; i--) + { + const OrthancStone::CoordinateSystem3D& slice = *slices_[i - 1]; + + reversed->AddSlice(slice.GetOrigin(), + -slice.GetAxisX(), + slice.GetAxisY()); + } + + return reversed.release(); + } + + + ParallelSlices* ParallelSlices::FromVolumeImage(const OrthancStone::VolumeImageGeometry& geometry, + OrthancStone::VolumeProjection projection) + { + const OrthancStone::Vector dimensions = geometry.GetVoxelDimensions(OrthancStone::VolumeProjection_Axial); + const OrthancStone::CoordinateSystem3D& axial = geometry.GetAxialGeometry(); + + std::auto_ptr result(new ParallelSlices); + + switch (projection) + { + case OrthancStone::VolumeProjection_Axial: + for (unsigned int z = 0; z < geometry.GetDepth(); z++) + { + OrthancStone::Vector origin = axial.GetOrigin(); + origin += static_cast(z) * dimensions[2] * axial.GetNormal(); + + result->AddSlice(origin, + axial.GetAxisX(), + axial.GetAxisY()); + } + break; + + case OrthancStone::VolumeProjection_Coronal: + for (unsigned int y = 0; y < geometry.GetHeight(); y++) + { + OrthancStone::Vector origin = axial.GetOrigin(); + origin += static_cast(y) * dimensions[1] * axial.GetAxisY(); + origin += static_cast(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal(); + + result->AddSlice(origin, + axial.GetAxisX(), + -axial.GetNormal()); + } + break; + + case OrthancStone::VolumeProjection_Sagittal: + for (unsigned int x = 0; x < geometry.GetWidth(); x++) + { + OrthancStone::Vector origin = axial.GetOrigin(); + origin += static_cast(x) * dimensions[0] * axial.GetAxisX(); + origin += static_cast(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal(); + + result->AddSlice(origin, + axial.GetAxisY(), + -axial.GetNormal()); + } + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + return result.release(); + } +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ParallelSlices.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Toolbox/ParallelSlices.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,73 @@ +/** + * 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 . + **/ + + +#pragma once + +#include "../../Toolbox/CoordinateSystem3D.h" +#include "../../Volumes/VolumeImageGeometry.h" + +namespace Deprecated +{ + class ParallelSlices : public boost::noncopyable + { + private: + OrthancStone::Vector normal_; + std::vector slices_; + + ParallelSlices& operator= (const ParallelSlices& other); // Forbidden + + void Clear(); + + public: + ParallelSlices(); + + ParallelSlices(const ParallelSlices& other); + + ~ParallelSlices(); + + const OrthancStone::Vector& GetNormal() const + { + return normal_; + } + + void AddSlice(const OrthancStone::CoordinateSystem3D& slice); + + void AddSlice(const OrthancStone::Vector& origin, + const OrthancStone::Vector& axisX, + const OrthancStone::Vector& axisY); + + size_t GetSliceCount() const + { + return slices_.size(); + } + + const OrthancStone::CoordinateSystem3D& GetSlice(size_t index) const; + + bool ComputeClosestSlice(size_t& closestSlice, + double& closestDistance, + const OrthancStone::Vector& origin) const; + + ParallelSlices* Reverse() const; + + static ParallelSlices* FromVolumeImage(const OrthancStone::VolumeImageGeometry& geometry, + OrthancStone::VolumeProjection projection); + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ParallelSlicesCursor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Toolbox/ParallelSlicesCursor.cpp Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,221 @@ +/** + * 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 . + **/ + + +#include "ParallelSlicesCursor.h" + +#include + +namespace Deprecated +{ + size_t ParallelSlicesCursor::GetDefaultSlice() + { + if (slices_.get() == NULL) + { + return 0; + } + else + { + return slices_->GetSliceCount() / 2; + } + } + + + size_t ParallelSlicesCursor::GetSliceCount() + { + if (slices_.get() == NULL) + { + return 0; + } + else + { + return slices_->GetSliceCount(); + } + } + + + OrthancStone::CoordinateSystem3D ParallelSlicesCursor::GetSlice(size_t slice) + { + if (slices_.get() == NULL) + { + return OrthancStone::CoordinateSystem3D(); + } + else + { + return slices_->GetSlice(slice); + } + } + + + void ParallelSlicesCursor::SetGeometry(const ParallelSlices& slices) + { + slices_.reset(new ParallelSlices(slices)); + + currentSlice_ = GetDefaultSlice(); + } + + + OrthancStone::CoordinateSystem3D ParallelSlicesCursor::GetCurrentSlice() + { + if (slices_.get() != NULL && + currentSlice_ < slices_->GetSliceCount()) + { + return slices_->GetSlice(currentSlice_); + } + else + { + return OrthancStone::CoordinateSystem3D(); // No slice is available, return the canonical geometry + } + } + + + bool ParallelSlicesCursor::SetDefaultSlice() + { + size_t slice = GetDefaultSlice(); + + if (currentSlice_ != slice) + { + currentSlice_ = slice; + return true; + } + else + { + return false; + } + } + + + bool ParallelSlicesCursor::ApplyOffset(OrthancStone::SliceOffsetMode mode, + int offset) + { + if (slices_.get() == NULL) + { + return false; + } + + int count = static_cast(slices_->GetSliceCount()); + if (count == 0) + { + return false; + } + + int slice; + if (static_cast(currentSlice_) >= count) + { + slice = count - 1; + } + else + { + slice = static_cast(currentSlice_); + } + + switch (mode) + { + case OrthancStone::SliceOffsetMode_Absolute: + { + slice = offset; + break; + } + + case OrthancStone::SliceOffsetMode_Relative: + { + slice += offset; + break; + } + + case OrthancStone::SliceOffsetMode_Loop: + { + slice += offset; + while (slice < 0) + { + slice += count; + } + + while (slice >= count) + { + slice -= count; + } + + break; + } + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + if (slice < 0) + { + slice = 0; + } + + if (slice >= count) + { + slice = count - 1; + } + + if (slice != static_cast(currentSlice_)) + { + currentSlice_ = static_cast(slice); + return true; + } + else + { + return false; + } + } + + + bool ParallelSlicesCursor::ApplyWheelEvent(OrthancStone::MouseWheelDirection direction, + OrthancStone::KeyboardModifiers modifiers) + { + int offset = (modifiers & OrthancStone::KeyboardModifiers_Control ? 10 : 1); + + switch (direction) + { + case OrthancStone::MouseWheelDirection_Down: + return ApplyOffset(OrthancStone::SliceOffsetMode_Relative, -offset); + + case OrthancStone::MouseWheelDirection_Up: + return ApplyOffset(OrthancStone::SliceOffsetMode_Relative, offset); + + default: + return false; + } + } + + + bool ParallelSlicesCursor::LookupSliceContainingPoint(const OrthancStone::Vector& p) + { + size_t slice; + double distance; + + if (slices_.get() != NULL && + slices_->ComputeClosestSlice(slice, distance, p)) + { + if (currentSlice_ != slice) + { + currentSlice_ = slice; + return true; + } + } + + return false; + } +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ParallelSlicesCursor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Toolbox/ParallelSlicesCursor.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,65 @@ +/** + * 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 . + **/ + + +#pragma once + +#include "ParallelSlices.h" +#include "../../StoneEnumerations.h" + +namespace Deprecated +{ + class ParallelSlicesCursor : public boost::noncopyable + { + private: + std::auto_ptr slices_; + size_t currentSlice_; + + size_t GetDefaultSlice(); + + public: + ParallelSlicesCursor() : + currentSlice_(0) + { + } + + void SetGeometry(const ParallelSlices& slices); + + size_t GetSliceCount(); + + OrthancStone::CoordinateSystem3D GetSlice(size_t slice); + + OrthancStone::CoordinateSystem3D GetCurrentSlice(); + + // Returns "true" iff. the slice has actually changed + bool SetDefaultSlice(); + + // Returns "true" iff. the slice has actually changed + bool ApplyOffset(OrthancStone::SliceOffsetMode mode, + int offset); + + // Returns "true" iff. the slice has actually changed + bool ApplyWheelEvent(OrthancStone::MouseWheelDirection direction, + OrthancStone::KeyboardModifiers modifiers); + + // Returns "true" iff. the slice has actually changed + bool LookupSliceContainingPoint(const OrthancStone::Vector& p); + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Toolbox/ViewportGeometry.h --- a/Framework/Deprecated/Toolbox/ViewportGeometry.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Deprecated/Toolbox/ViewportGeometry.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoContext.h" +#include "../../Wrappers/CairoContext.h" #include "../../Toolbox/Extent2D.h" #include "../../Toolbox/LinearAlgebra.h" #include "../Viewport/IMouseTracker.h" // to include "Touch" definition diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Viewport/CairoFont.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Viewport/CairoFont.cpp Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,65 @@ +/** + * 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 . + **/ + + +#include "CairoFont.h" + +#include +#include + +namespace Deprecated +{ + CairoFont::CairoFont(const char* family, + cairo_font_slant_t slant, + cairo_font_weight_t weight) + { + font_ = cairo_toy_font_face_create(family, slant, weight); + if (font_ == NULL) + { + LOG(ERROR) << "Unknown font: " << family; + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + } + + + CairoFont::~CairoFont() + { + if (font_ != NULL) + { + cairo_font_face_destroy(font_); + } + } + + + void CairoFont::Draw(OrthancStone::CairoContext& context, + const std::string& text, + double size) + { + if (size <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + cairo_t* cr = context.GetObject(); + cairo_set_font_face(cr, font_); + cairo_set_font_size(cr, size); + cairo_show_text(cr, text.c_str()); + } +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Viewport/CairoFont.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Deprecated/Viewport/CairoFont.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,52 @@ +/** + * 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 . + **/ + + +#pragma once + +#if !defined(ORTHANC_SANDBOXED) +# error The macro ORTHANC_SANDBOXED must be defined +#endif + +#if ORTHANC_SANDBOXED == 1 +# error The class CairoFont cannot be used in sandboxed environments +#endif + +#include "../../Wrappers/CairoContext.h" + +namespace Deprecated +{ + class CairoFont : public boost::noncopyable + { + private: + cairo_font_face_t* font_; + + public: + CairoFont(const char* family, + cairo_font_slant_t slant, + cairo_font_weight_t weight); + + ~CairoFont(); + + void Draw(OrthancStone::CairoContext& context, + const std::string& text, + double size); + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Viewport/IMouseTracker.h --- a/Framework/Deprecated/Viewport/IMouseTracker.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Deprecated/Viewport/IMouseTracker.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include namespace Deprecated diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Widgets/IWorldSceneMouseTracker.h --- a/Framework/Deprecated/Widgets/IWorldSceneMouseTracker.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Deprecated/Widgets/IWorldSceneMouseTracker.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoContext.h" +#include "../../Wrappers/CairoContext.h" #include "../Viewport/IMouseTracker.h" // only to get the "Touch" definition namespace Deprecated diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Deprecated/Widgets/WidgetBase.h --- a/Framework/Deprecated/Widgets/WidgetBase.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Deprecated/Widgets/WidgetBase.h Tue May 28 18:31:44 2019 +0200 @@ -23,7 +23,7 @@ #include "IWidget.h" -#include "../../Viewport/CairoContext.h" +#include "../../Wrappers/CairoContext.h" #include "../Viewport/WidgetViewport.h" namespace Deprecated diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Radiography/RadiographyLayer.h --- a/Framework/Radiography/RadiographyLayer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Radiography/RadiographyLayer.h Tue May 28 18:31:44 2019 +0200 @@ -23,7 +23,7 @@ #include "../Toolbox/AffineTransform2D.h" #include "../Toolbox/Extent2D.h" -#include "../Viewport/CairoContext.h" +#include "../Wrappers/CairoContext.h" #include "../Messages/IMessage.h" #include "../Messages/IObservable.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/CairoCompositor.h --- a/Framework/Scene2D/CairoCompositor.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/CairoCompositor.h Tue May 28 18:31:44 2019 +0200 @@ -22,7 +22,7 @@ #pragma once #include "../Fonts/GlyphBitmapAlphabet.h" -#include "../Viewport/CairoContext.h" +#include "../Wrappers/CairoContext.h" #include "Internals/CompositorHelper.h" #include "Internals/ICairoContextProvider.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/Internals/CairoColorTextureRenderer.h --- a/Framework/Scene2D/Internals/CairoColorTextureRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoColorTextureRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include "CompositorHelper.h" #include "ICairoContextProvider.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/Internals/CairoFloatTextureRenderer.h --- a/Framework/Scene2D/Internals/CairoFloatTextureRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoFloatTextureRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include "CompositorHelper.h" #include "ICairoContextProvider.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/Internals/CairoInfoPanelRenderer.h --- a/Framework/Scene2D/Internals/CairoInfoPanelRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoInfoPanelRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include "CompositorHelper.h" #include "ICairoContextProvider.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/Internals/CairoLookupTableTextureRenderer.h --- a/Framework/Scene2D/Internals/CairoLookupTableTextureRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoLookupTableTextureRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -21,7 +21,7 @@ #pragma once -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include "CompositorHelper.h" #include "ICairoContextProvider.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Scene2D/Internals/CairoTextRenderer.h --- a/Framework/Scene2D/Internals/CairoTextRenderer.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Scene2D/Internals/CairoTextRenderer.h Tue May 28 18:31:44 2019 +0200 @@ -22,7 +22,7 @@ #pragma once #include "../../Fonts/GlyphBitmapAlphabet.h" -#include "../../Viewport/CairoSurface.h" +#include "../../Wrappers/CairoSurface.h" #include "../TextSceneLayer.h" #include "CairoBaseRenderer.h" diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/FiniteProjectiveCamera.cpp --- a/Framework/Toolbox/FiniteProjectiveCamera.cpp Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Toolbox/FiniteProjectiveCamera.cpp Tue May 28 18:31:44 2019 +0200 @@ -23,7 +23,6 @@ #include "GeometryToolbox.h" #include "SubpixelReader.h" -#include "ParallelSlices.h" #include #include @@ -317,7 +316,7 @@ LOG(WARNING) << "Output image size: " << target.GetWidth() << "x" << target.GetHeight(); LOG(WARNING) << "Output pixel format: " << Orthanc::EnumerationToString(target.GetFormat()); - std::auto_ptr slices(OrthancStone::ParallelSlices::FromVolumeImage(geometry, projection)); + const unsigned int slicesCount = geometry.GetProjectionDepth(projection); const OrthancStone::Vector pixelSpacing = geometry.GetVoxelDimensions(projection); const unsigned int targetWidth = target.GetWidth(); const unsigned int targetHeight = target.GetHeight(); @@ -329,11 +328,11 @@ typedef SubpixelReader SourceReader; - for (size_t z = 0; z < slices->GetSliceCount(); z++) + for (unsigned int z = 0; z < slicesCount; z++) { - LOG(INFO) << "Applying raytracer on slice: " << z << "/" << slices->GetSliceCount(); - - const OrthancStone::CoordinateSystem3D& slice = slices->GetSlice(z); + LOG(INFO) << "Applying raytracer on slice: " << z << "/" << slicesCount; + + OrthancStone::CoordinateSystem3D slice = geometry.GetProjectionSlice(projection, z); OrthancStone::ImageBuffer3D::SliceReader sliceReader(source, projection, static_cast(z)); SourceReader pixelReader(sliceReader.GetAccessor()); diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/ISeriesLoader.h --- a/Framework/Toolbox/ISeriesLoader.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include "ParallelSlices.h" - -#include -#include - -namespace OrthancStone -{ - class ISeriesLoader : public boost::noncopyable - { - public: - virtual ~ISeriesLoader() - { - } - - virtual ParallelSlices& GetGeometry() = 0; - - virtual Orthanc::PixelFormat GetPixelFormat() = 0; - - virtual unsigned int GetWidth() = 0; - - virtual unsigned int GetHeight() = 0; - - virtual OrthancPlugins::IDicomDataset* DownloadDicom(size_t index) = 0; - - // This downloads the frame from Orthanc. The resulting pixel - // format must be Grayscale8, Grayscale16, SignedGrayscale16 or - // RGB24. Orthanc Stone assumes the conversion of the photometric - // interpretation is done by Orthanc. - virtual Orthanc::ImageAccessor* DownloadFrame(size_t index) = 0; - - virtual Orthanc::ImageAccessor* DownloadJpegFrame(size_t index, - unsigned int quality) = 0; - - virtual bool IsJpegAvailable() = 0; - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/ParallelSlices.cpp --- a/Framework/Toolbox/ParallelSlices.cpp Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/** - * 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 . - **/ - - -#include "ParallelSlices.h" - -#include "GeometryToolbox.h" -#include "../Volumes/ImageBuffer3D.h" - -#include -#include - -namespace OrthancStone -{ - ParallelSlices::ParallelSlices() - { - Clear(); - } - - - ParallelSlices::ParallelSlices(const ParallelSlices& other) - { - normal_ = other.normal_; - - slices_.resize(other.slices_.size()); - - for (size_t i = 0; i < slices_.size(); i++) - { - assert(other.slices_[i] != NULL); - slices_[i] = new CoordinateSystem3D(*other.slices_[i]); - } - } - - - void ParallelSlices::Clear() - { - for (size_t i = 0; i < slices_.size(); i++) - { - if (slices_[i] != NULL) - { - delete slices_[i]; - slices_[i] = NULL; - } - } - - slices_.clear(); - LinearAlgebra::AssignVector(normal_, 0, 0, 1); - } - - - ParallelSlices::~ParallelSlices() - { - Clear(); - } - - - void ParallelSlices::AddSlice(const CoordinateSystem3D& slice) - { - if (slices_.empty()) - { - normal_ = slice.GetNormal(); - slices_.push_back(new CoordinateSystem3D(slice)); - } - else if (GeometryToolbox::IsParallel(slice.GetNormal(), normal_)) - { - slices_.push_back(new CoordinateSystem3D(slice)); - } - else - { - LOG(ERROR) << "Trying to add a slice that is not parallel to the previous ones"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - } - - - void ParallelSlices::AddSlice(const Vector& origin, - const Vector& axisX, - const Vector& axisY) - { - CoordinateSystem3D slice(origin, axisX, axisY); - AddSlice(slice); - } - - - const CoordinateSystem3D& ParallelSlices::GetSlice(size_t index) const - { - if (index >= slices_.size()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - else - { - return *slices_[index]; - } - } - - - bool ParallelSlices::ComputeClosestSlice(size_t& closestSlice, - double& closestDistance, - const Vector& origin) const - { - if (slices_.empty()) - { - return false; - } - - double reference = boost::numeric::ublas::inner_prod(origin, normal_); - - closestSlice = 0; - closestDistance = std::numeric_limits::infinity(); - - for (size_t i = 0; i < slices_.size(); i++) - { - double distance = fabs(boost::numeric::ublas::inner_prod(slices_[i]->GetOrigin(), normal_) - reference); - - if (distance < closestDistance) - { - closestSlice = i; - closestDistance = distance; - } - } - - return true; - } - - - ParallelSlices* ParallelSlices::Reverse() const - { - std::auto_ptr reversed(new ParallelSlices); - - for (size_t i = slices_.size(); i > 0; i--) - { - const CoordinateSystem3D& slice = *slices_[i - 1]; - - reversed->AddSlice(slice.GetOrigin(), - -slice.GetAxisX(), - slice.GetAxisY()); - } - - return reversed.release(); - } - - - ParallelSlices* ParallelSlices::FromVolumeImage(const VolumeImageGeometry& geometry, - VolumeProjection projection) - { - const Vector dimensions = geometry.GetVoxelDimensions(VolumeProjection_Axial); - const CoordinateSystem3D& axial = geometry.GetAxialGeometry(); - - std::auto_ptr result(new ParallelSlices); - - switch (projection) - { - case VolumeProjection_Axial: - for (unsigned int z = 0; z < geometry.GetDepth(); z++) - { - Vector origin = axial.GetOrigin(); - origin += static_cast(z) * dimensions[2] * axial.GetNormal(); - - result->AddSlice(origin, - axial.GetAxisX(), - axial.GetAxisY()); - } - break; - - case VolumeProjection_Coronal: - for (unsigned int y = 0; y < geometry.GetHeight(); y++) - { - Vector origin = axial.GetOrigin(); - origin += static_cast(y) * dimensions[1] * axial.GetAxisY(); - origin += static_cast(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal(); - - result->AddSlice(origin, - axial.GetAxisX(), - -axial.GetNormal()); - } - break; - - case VolumeProjection_Sagittal: - for (unsigned int x = 0; x < geometry.GetWidth(); x++) - { - Vector origin = axial.GetOrigin(); - origin += static_cast(x) * dimensions[0] * axial.GetAxisX(); - origin += static_cast(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal(); - - result->AddSlice(origin, - axial.GetAxisY(), - -axial.GetNormal()); - } - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - return result.release(); - } -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/ParallelSlices.h --- a/Framework/Toolbox/ParallelSlices.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include "CoordinateSystem3D.h" -#include "../Volumes/VolumeImageGeometry.h" - -namespace OrthancStone -{ - class ParallelSlices : public boost::noncopyable - { - private: - Vector normal_; - std::vector slices_; - - ParallelSlices& operator= (const ParallelSlices& other); // Forbidden - - void Clear(); - - public: - ParallelSlices(); - - ParallelSlices(const ParallelSlices& other); - - ~ParallelSlices(); - - const Vector& GetNormal() const - { - return normal_; - } - - void AddSlice(const CoordinateSystem3D& slice); - - void AddSlice(const Vector& origin, - const Vector& axisX, - const Vector& axisY); - - size_t GetSliceCount() const - { - return slices_.size(); - } - - const CoordinateSystem3D& GetSlice(size_t index) const; - - bool ComputeClosestSlice(size_t& closestSlice, - double& closestDistance, - const Vector& origin) const; - - ParallelSlices* Reverse() const; - - static ParallelSlices* FromVolumeImage(const VolumeImageGeometry& geometry, - VolumeProjection projection); - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/ParallelSlicesCursor.cpp --- a/Framework/Toolbox/ParallelSlicesCursor.cpp Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -/** - * 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 . - **/ - - -#include "ParallelSlicesCursor.h" - -#include - -namespace OrthancStone -{ - size_t ParallelSlicesCursor::GetDefaultSlice() - { - if (slices_.get() == NULL) - { - return 0; - } - else - { - return slices_->GetSliceCount() / 2; - } - } - - - size_t ParallelSlicesCursor::GetSliceCount() - { - if (slices_.get() == NULL) - { - return 0; - } - else - { - return slices_->GetSliceCount(); - } - } - - - CoordinateSystem3D ParallelSlicesCursor::GetSlice(size_t slice) - { - if (slices_.get() == NULL) - { - return CoordinateSystem3D(); - } - else - { - return slices_->GetSlice(slice); - } - } - - - void ParallelSlicesCursor::SetGeometry(const ParallelSlices& slices) - { - slices_.reset(new ParallelSlices(slices)); - - currentSlice_ = GetDefaultSlice(); - } - - - CoordinateSystem3D ParallelSlicesCursor::GetCurrentSlice() - { - if (slices_.get() != NULL && - currentSlice_ < slices_->GetSliceCount()) - { - return slices_->GetSlice(currentSlice_); - } - else - { - return CoordinateSystem3D(); // No slice is available, return the canonical geometry - } - } - - - bool ParallelSlicesCursor::SetDefaultSlice() - { - size_t slice = GetDefaultSlice(); - - if (currentSlice_ != slice) - { - currentSlice_ = slice; - return true; - } - else - { - return false; - } - } - - - bool ParallelSlicesCursor::ApplyOffset(SliceOffsetMode mode, - int offset) - { - if (slices_.get() == NULL) - { - return false; - } - - int count = static_cast(slices_->GetSliceCount()); - if (count == 0) - { - return false; - } - - int slice; - if (static_cast(currentSlice_) >= count) - { - slice = count - 1; - } - else - { - slice = static_cast(currentSlice_); - } - - switch (mode) - { - case SliceOffsetMode_Absolute: - { - slice = offset; - break; - } - - case SliceOffsetMode_Relative: - { - slice += offset; - break; - } - - case SliceOffsetMode_Loop: - { - slice += offset; - while (slice < 0) - { - slice += count; - } - - while (slice >= count) - { - slice -= count; - } - - break; - } - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - if (slice < 0) - { - slice = 0; - } - - if (slice >= count) - { - slice = count - 1; - } - - if (slice != static_cast(currentSlice_)) - { - currentSlice_ = static_cast(slice); - return true; - } - else - { - return false; - } - } - - - bool ParallelSlicesCursor::ApplyWheelEvent(MouseWheelDirection direction, - KeyboardModifiers modifiers) - { - int offset = (modifiers & KeyboardModifiers_Control ? 10 : 1); - - switch (direction) - { - case MouseWheelDirection_Down: - return ApplyOffset(SliceOffsetMode_Relative, -offset); - - case MouseWheelDirection_Up: - return ApplyOffset(SliceOffsetMode_Relative, offset); - - default: - return false; - } - } - - - bool ParallelSlicesCursor::LookupSliceContainingPoint(const Vector& p) - { - size_t slice; - double distance; - - if (slices_.get() != NULL && - slices_->ComputeClosestSlice(slice, distance, p)) - { - if (currentSlice_ != slice) - { - currentSlice_ = slice; - return true; - } - } - - return false; - } -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Toolbox/ParallelSlicesCursor.h --- a/Framework/Toolbox/ParallelSlicesCursor.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include "ParallelSlices.h" -#include "../StoneEnumerations.h" - -namespace OrthancStone -{ - class ParallelSlicesCursor : public boost::noncopyable - { - private: - std::auto_ptr slices_; - size_t currentSlice_; - - size_t GetDefaultSlice(); - - public: - ParallelSlicesCursor() : - currentSlice_(0) - { - } - - void SetGeometry(const ParallelSlices& slices); - - size_t GetSliceCount(); - - CoordinateSystem3D GetSlice(size_t slice); - - CoordinateSystem3D GetCurrentSlice(); - - // Returns "true" iff. the slice has actually changed - bool SetDefaultSlice(); - - // Returns "true" iff. the slice has actually changed - bool ApplyOffset(SliceOffsetMode mode, - int offset); - - // Returns "true" iff. the slice has actually changed - bool ApplyWheelEvent(MouseWheelDirection direction, - KeyboardModifiers modifiers); - - // Returns "true" iff. the slice has actually changed - bool LookupSliceContainingPoint(const Vector& p); - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoContext.cpp --- a/Framework/Viewport/CairoContext.cpp Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -/** - * 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 . - **/ - - -#include "CairoContext.h" - -#include -#include - - -namespace OrthancStone -{ - CairoContext::CairoContext(CairoSurface& surface) : - width_(surface.GetWidth()), - height_(surface.GetHeight()) - { - context_ = cairo_create(surface.GetObject()); - if (!context_) - { - LOG(ERROR) << "Cannot create Cairo drawing context"; - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - - CairoContext::~CairoContext() - { - if (context_ != NULL) - { - cairo_destroy(context_); - context_ = NULL; - } - } - - - void CairoContext::SetSourceColor(uint8_t red, - uint8_t green, - uint8_t blue) - { - cairo_set_source_rgb(context_, - static_cast(red) / 255.0f, - static_cast(green) / 255.0f, - static_cast(blue) / 255.0f); - } - - - class CairoContext::AlphaSurface : public boost::noncopyable - { - private: - cairo_surface_t *surface_; - - public: - AlphaSurface(unsigned int width, - unsigned int height) - { - surface_ = cairo_image_surface_create(CAIRO_FORMAT_A8, width, height); - - if (!surface_) - { - // Should never occur - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) - { - LOG(ERROR) << "Cannot create a Cairo surface"; - cairo_surface_destroy(surface_); - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - ~AlphaSurface() - { - cairo_surface_destroy(surface_); - } - - void GetAccessor(Orthanc::ImageAccessor& target) - { - target.AssignWritable(Orthanc::PixelFormat_Grayscale8, - cairo_image_surface_get_width(surface_), - cairo_image_surface_get_height(surface_), - cairo_image_surface_get_stride(surface_), - cairo_image_surface_get_data(surface_)); - } - - void Blit(cairo_t* cr, - double x, - double y) - { - cairo_surface_mark_dirty(surface_); - cairo_mask_surface(cr, surface_, x, y); - cairo_fill(cr); - } - }; - - - void CairoContext::DrawText(const Orthanc::Font& font, - const std::string& text, - double x, - double y, - BitmapAnchor anchor) - { - // Render a bitmap containing the text - unsigned int width, height; - font.ComputeTextExtent(width, height, text); - - AlphaSurface surface(width, height); - - Orthanc::ImageAccessor accessor; - surface.GetAccessor(accessor); - font.Draw(accessor, text, 0, 0, 255); - - // Correct the text location given the anchor location - double deltaX, deltaY; - ComputeAnchorTranslation(deltaX, deltaY, anchor, width, height); - - // Cancel zoom/rotation before blitting the text onto the surface - double pixelX = x; - double pixelY = y; - cairo_user_to_device(context_, &pixelX, &pixelY); - - cairo_save(context_); - cairo_identity_matrix(context_); - - // Blit the text bitmap - surface.Blit(context_, pixelX + deltaX, pixelY + deltaY); - cairo_restore(context_); - } -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoContext.h --- a/Framework/Viewport/CairoContext.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include "CairoSurface.h" -#include "../StoneEnumerations.h" - -#include - -namespace OrthancStone -{ - // This is a RAII wrapper around the Cairo drawing context - class CairoContext : public boost::noncopyable - { - private: - class AlphaSurface; - - cairo_t* context_; - unsigned int width_; - unsigned int height_; - - public: - CairoContext(CairoSurface& surface); - - ~CairoContext(); - - cairo_t* GetObject() - { - return context_; - } - - unsigned int GetWidth() const - { - return width_; - } - - unsigned int GetHeight() const - { - return height_; - } - - void SetSourceColor(uint8_t red, - uint8_t green, - uint8_t blue); - - void SetSourceColor(const uint8_t color[3]) - { - SetSourceColor(color[0], color[1], color[2]); - } - - void DrawText(const Orthanc::Font& font, - const std::string& text, - double x, - double y, - BitmapAnchor anchor); - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoFont.cpp --- a/Framework/Viewport/CairoFont.cpp Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/** - * 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 . - **/ - - -#include "CairoFont.h" - -#include -#include - -namespace OrthancStone -{ - CairoFont::CairoFont(const char* family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) - { - font_ = cairo_toy_font_face_create(family, slant, weight); - if (font_ == NULL) - { - LOG(ERROR) << "Unknown font: " << family; - throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); - } - } - - - CairoFont::~CairoFont() - { - if (font_ != NULL) - { - cairo_font_face_destroy(font_); - } - } - - - void CairoFont::Draw(CairoContext& context, - const std::string& text, - double size) - { - if (size <= 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - cairo_t* cr = context.GetObject(); - cairo_set_font_face(cr, font_); - cairo_set_font_size(cr, size); - cairo_show_text(cr, text.c_str()); - } -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoFont.h --- a/Framework/Viewport/CairoFont.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#if !defined(ORTHANC_SANDBOXED) -# error The macro ORTHANC_SANDBOXED must be defined -#endif - -#if ORTHANC_SANDBOXED == 1 -# error The class CairoFont cannot be used in sandboxed environments -#endif - -#include "CairoContext.h" - -namespace OrthancStone -{ - class CairoFont : public boost::noncopyable - { - private: - cairo_font_face_t* font_; - - public: - CairoFont(const char* family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - - ~CairoFont(); - - void Draw(CairoContext& context, - const std::string& text, - double size); - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoSurface.cpp --- a/Framework/Viewport/CairoSurface.cpp Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/** - * 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 . - **/ - - -#include "CairoSurface.h" - -#include -#include -#include - -namespace OrthancStone -{ - void CairoSurface::Release() - { - if (surface_) - { - cairo_surface_destroy(surface_); - surface_ = NULL; - } - } - - - void CairoSurface::Allocate(unsigned int width, - unsigned int height, - bool hasAlpha) - { - Release(); - - hasAlpha_ = hasAlpha; - - surface_ = cairo_image_surface_create - (hasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height); - if (!surface_) - { - // Should never occur - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) - { - LOG(ERROR) << "Cannot create a Cairo surface"; - cairo_surface_destroy(surface_); - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - width_ = width; - height_ = height; - pitch_ = cairo_image_surface_get_stride(surface_); - buffer_ = cairo_image_surface_get_data(surface_); - } - - - CairoSurface::CairoSurface(Orthanc::ImageAccessor& accessor, - bool hasAlpha) : - hasAlpha_(hasAlpha) - { - if (accessor.GetFormat() != Orthanc::PixelFormat_BGRA32) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); - } - - width_ = accessor.GetWidth(); - height_ = accessor.GetHeight(); - pitch_ = accessor.GetPitch(); - buffer_ = accessor.GetBuffer(); - - surface_ = cairo_image_surface_create_for_data - (reinterpret_cast(buffer_), - hasAlpha_ ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, - width_, height_, pitch_); - if (!surface_) - { - // Should never occur - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) - { - LOG(ERROR) << "Bad pitch for a Cairo surface"; - cairo_surface_destroy(surface_); - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - - void CairoSurface::SetSize(unsigned int width, - unsigned int height, - bool hasAlpha) - { - if (hasAlpha_ != hasAlpha || - width_ != width || - height_ != height) - { - Allocate(width, height, hasAlpha); - } - } - - - void CairoSurface::Copy(const CairoSurface& other) - { - SetSize(other.GetWidth(), other.GetHeight(), other.HasAlpha()); - - Orthanc::ImageAccessor source, target; - - other.GetReadOnlyAccessor(source); - GetWriteableAccessor(target); - - Orthanc::ImageProcessing::Copy(target, source); - - cairo_surface_mark_dirty(surface_); - } - - - void CairoSurface::Copy(const Orthanc::ImageAccessor& source, - bool hasAlpha) - { - SetSize(source.GetWidth(), source.GetHeight(), hasAlpha); - - Orthanc::ImageAccessor target; - GetWriteableAccessor(target); - - Orthanc::ImageProcessing::Convert(target, source); - - cairo_surface_mark_dirty(surface_); - } - - - void CairoSurface::GetReadOnlyAccessor(Orthanc::ImageAccessor& target) const - { - target.AssignReadOnly(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_); - } - - - void CairoSurface::GetWriteableAccessor(Orthanc::ImageAccessor& target) - { - target.AssignWritable(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_); - } -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Viewport/CairoSurface.h --- a/Framework/Viewport/CairoSurface.h Tue May 28 18:31:17 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/** - * 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 . - **/ - - -#pragma once - -#include - -#include -#include - -namespace OrthancStone -{ - class CairoSurface : public boost::noncopyable - { - private: - cairo_surface_t* surface_; - unsigned int width_; - unsigned int height_; - unsigned int pitch_; - void* buffer_; - bool hasAlpha_; - - void Release(); - - void Allocate(unsigned int width, - unsigned int height, - bool hasAlpha); - - public: - CairoSurface() : - surface_(NULL) - { - Allocate(0, 0, false); - } - - CairoSurface(unsigned int width, - unsigned int height, - bool hasAlpha) : - surface_(NULL) - { - Allocate(width, height, hasAlpha); - } - - CairoSurface(Orthanc::ImageAccessor& accessor, - bool hasAlpha); - - ~CairoSurface() - { - Release(); - } - - void SetSize(unsigned int width, - unsigned int height, - bool hasAlpha); - - void Copy(const CairoSurface& other); - - void Copy(const Orthanc::ImageAccessor& source, - bool hasAlpha); - - unsigned int GetWidth() const - { - return width_; - } - - unsigned int GetHeight() const - { - return height_; - } - - unsigned int GetPitch() const - { - return pitch_; - } - - const void* GetBuffer() const - { - return buffer_; - } - - void* GetBuffer() - { - return buffer_; - } - - cairo_surface_t* GetObject() - { - return surface_; - } - - bool HasAlpha() const - { - return hasAlpha_; - } - - void GetReadOnlyAccessor(Orthanc::ImageAccessor& target) const; - - void GetWriteableAccessor(Orthanc::ImageAccessor& target); - }; -} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Volumes/VolumeImageGeometry.cpp --- a/Framework/Volumes/VolumeImageGeometry.cpp Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Volumes/VolumeImageGeometry.cpp Tue May 28 18:31:44 2019 +0200 @@ -306,4 +306,21 @@ return true; } } + + + CoordinateSystem3D VolumeImageGeometry::GetProjectionSlice(VolumeProjection projection, + unsigned int z) const + { + if (z >= GetProjectionDepth(projection)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + Vector dim = GetVoxelDimensions(projection); + CoordinateSystem3D plane = GetProjectionGeometry(projection); + + plane.SetOrigin(plane.GetOrigin() + static_cast(z) * plane.GetNormal() * dim[2]); + + return plane; + } } diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Volumes/VolumeImageGeometry.h --- a/Framework/Volumes/VolumeImageGeometry.h Tue May 28 18:31:17 2019 +0200 +++ b/Framework/Volumes/VolumeImageGeometry.h Tue May 28 18:31:44 2019 +0200 @@ -127,5 +127,8 @@ bool DetectSlice(VolumeProjection& projection, unsigned int& slice, const CoordinateSystem3D& plane) const; + + CoordinateSystem3D GetProjectionSlice(VolumeProjection projection, + unsigned int z) const; }; } diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Wrappers/CairoContext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Wrappers/CairoContext.cpp Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,146 @@ +/** + * 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 . + **/ + + +#include "CairoContext.h" + +#include +#include + + +namespace OrthancStone +{ + CairoContext::CairoContext(CairoSurface& surface) : + width_(surface.GetWidth()), + height_(surface.GetHeight()) + { + context_ = cairo_create(surface.GetObject()); + if (!context_) + { + LOG(ERROR) << "Cannot create Cairo drawing context"; + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + + CairoContext::~CairoContext() + { + if (context_ != NULL) + { + cairo_destroy(context_); + context_ = NULL; + } + } + + + void CairoContext::SetSourceColor(uint8_t red, + uint8_t green, + uint8_t blue) + { + cairo_set_source_rgb(context_, + static_cast(red) / 255.0f, + static_cast(green) / 255.0f, + static_cast(blue) / 255.0f); + } + + + class CairoContext::AlphaSurface : public boost::noncopyable + { + private: + cairo_surface_t *surface_; + + public: + AlphaSurface(unsigned int width, + unsigned int height) + { + surface_ = cairo_image_surface_create(CAIRO_FORMAT_A8, width, height); + + if (!surface_) + { + // Should never occur + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) + { + LOG(ERROR) << "Cannot create a Cairo surface"; + cairo_surface_destroy(surface_); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + ~AlphaSurface() + { + cairo_surface_destroy(surface_); + } + + void GetAccessor(Orthanc::ImageAccessor& target) + { + target.AssignWritable(Orthanc::PixelFormat_Grayscale8, + cairo_image_surface_get_width(surface_), + cairo_image_surface_get_height(surface_), + cairo_image_surface_get_stride(surface_), + cairo_image_surface_get_data(surface_)); + } + + void Blit(cairo_t* cr, + double x, + double y) + { + cairo_surface_mark_dirty(surface_); + cairo_mask_surface(cr, surface_, x, y); + cairo_fill(cr); + } + }; + + + void CairoContext::DrawText(const Orthanc::Font& font, + const std::string& text, + double x, + double y, + BitmapAnchor anchor) + { + // Render a bitmap containing the text + unsigned int width, height; + font.ComputeTextExtent(width, height, text); + + AlphaSurface surface(width, height); + + Orthanc::ImageAccessor accessor; + surface.GetAccessor(accessor); + font.Draw(accessor, text, 0, 0, 255); + + // Correct the text location given the anchor location + double deltaX, deltaY; + ComputeAnchorTranslation(deltaX, deltaY, anchor, width, height); + + // Cancel zoom/rotation before blitting the text onto the surface + double pixelX = x; + double pixelY = y; + cairo_user_to_device(context_, &pixelX, &pixelY); + + cairo_save(context_); + cairo_identity_matrix(context_); + + // Blit the text bitmap + surface.Blit(context_, pixelX + deltaX, pixelY + deltaY); + cairo_restore(context_); + } +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Wrappers/CairoContext.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Wrappers/CairoContext.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,76 @@ +/** + * 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 . + **/ + + +#pragma once + +#include "CairoSurface.h" +#include "../StoneEnumerations.h" + +#include + +namespace OrthancStone +{ + // This is a RAII wrapper around the Cairo drawing context + class CairoContext : public boost::noncopyable + { + private: + class AlphaSurface; + + cairo_t* context_; + unsigned int width_; + unsigned int height_; + + public: + CairoContext(CairoSurface& surface); + + ~CairoContext(); + + cairo_t* GetObject() + { + return context_; + } + + unsigned int GetWidth() const + { + return width_; + } + + unsigned int GetHeight() const + { + return height_; + } + + void SetSourceColor(uint8_t red, + uint8_t green, + uint8_t blue); + + void SetSourceColor(const uint8_t color[3]) + { + SetSourceColor(color[0], color[1], color[2]); + } + + void DrawText(const Orthanc::Font& font, + const std::string& text, + double x, + double y, + BitmapAnchor anchor); + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Wrappers/CairoSurface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Wrappers/CairoSurface.cpp Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,155 @@ +/** + * 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 . + **/ + + +#include "CairoSurface.h" + +#include +#include +#include + +namespace OrthancStone +{ + void CairoSurface::Release() + { + if (surface_) + { + cairo_surface_destroy(surface_); + surface_ = NULL; + } + } + + + void CairoSurface::Allocate(unsigned int width, + unsigned int height, + bool hasAlpha) + { + Release(); + + hasAlpha_ = hasAlpha; + + surface_ = cairo_image_surface_create + (hasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height); + if (!surface_) + { + // Should never occur + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) + { + LOG(ERROR) << "Cannot create a Cairo surface"; + cairo_surface_destroy(surface_); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + width_ = width; + height_ = height; + pitch_ = cairo_image_surface_get_stride(surface_); + buffer_ = cairo_image_surface_get_data(surface_); + } + + + CairoSurface::CairoSurface(Orthanc::ImageAccessor& accessor, + bool hasAlpha) : + hasAlpha_(hasAlpha) + { + if (accessor.GetFormat() != Orthanc::PixelFormat_BGRA32) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); + } + + width_ = accessor.GetWidth(); + height_ = accessor.GetHeight(); + pitch_ = accessor.GetPitch(); + buffer_ = accessor.GetBuffer(); + + surface_ = cairo_image_surface_create_for_data + (reinterpret_cast(buffer_), + hasAlpha_ ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, + width_, height_, pitch_); + if (!surface_) + { + // Should never occur + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS) + { + LOG(ERROR) << "Bad pitch for a Cairo surface"; + cairo_surface_destroy(surface_); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + + void CairoSurface::SetSize(unsigned int width, + unsigned int height, + bool hasAlpha) + { + if (hasAlpha_ != hasAlpha || + width_ != width || + height_ != height) + { + Allocate(width, height, hasAlpha); + } + } + + + void CairoSurface::Copy(const CairoSurface& other) + { + SetSize(other.GetWidth(), other.GetHeight(), other.HasAlpha()); + + Orthanc::ImageAccessor source, target; + + other.GetReadOnlyAccessor(source); + GetWriteableAccessor(target); + + Orthanc::ImageProcessing::Copy(target, source); + + cairo_surface_mark_dirty(surface_); + } + + + void CairoSurface::Copy(const Orthanc::ImageAccessor& source, + bool hasAlpha) + { + SetSize(source.GetWidth(), source.GetHeight(), hasAlpha); + + Orthanc::ImageAccessor target; + GetWriteableAccessor(target); + + Orthanc::ImageProcessing::Convert(target, source); + + cairo_surface_mark_dirty(surface_); + } + + + void CairoSurface::GetReadOnlyAccessor(Orthanc::ImageAccessor& target) const + { + target.AssignReadOnly(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_); + } + + + void CairoSurface::GetWriteableAccessor(Orthanc::ImageAccessor& target) + { + target.AssignWritable(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_); + } +} diff -r abc08ac721d3 -r bc7ee59420a1 Framework/Wrappers/CairoSurface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Wrappers/CairoSurface.h Tue May 28 18:31:44 2019 +0200 @@ -0,0 +1,118 @@ +/** + * 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 . + **/ + + +#pragma once + +#include + +#include +#include + +namespace OrthancStone +{ + class CairoSurface : public boost::noncopyable + { + private: + cairo_surface_t* surface_; + unsigned int width_; + unsigned int height_; + unsigned int pitch_; + void* buffer_; + bool hasAlpha_; + + void Release(); + + void Allocate(unsigned int width, + unsigned int height, + bool hasAlpha); + + public: + CairoSurface() : + surface_(NULL) + { + Allocate(0, 0, false); + } + + CairoSurface(unsigned int width, + unsigned int height, + bool hasAlpha) : + surface_(NULL) + { + Allocate(width, height, hasAlpha); + } + + CairoSurface(Orthanc::ImageAccessor& accessor, + bool hasAlpha); + + ~CairoSurface() + { + Release(); + } + + void SetSize(unsigned int width, + unsigned int height, + bool hasAlpha); + + void Copy(const CairoSurface& other); + + void Copy(const Orthanc::ImageAccessor& source, + bool hasAlpha); + + unsigned int GetWidth() const + { + return width_; + } + + unsigned int GetHeight() const + { + return height_; + } + + unsigned int GetPitch() const + { + return pitch_; + } + + const void* GetBuffer() const + { + return buffer_; + } + + void* GetBuffer() + { + return buffer_; + } + + cairo_surface_t* GetObject() + { + return surface_; + } + + bool HasAlpha() const + { + return hasAlpha_; + } + + void GetReadOnlyAccessor(Orthanc::ImageAccessor& target) const; + + void GetWriteableAccessor(Orthanc::ImageAccessor& target); + }; +} diff -r abc08ac721d3 -r bc7ee59420a1 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Tue May 28 18:31:17 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Tue May 28 18:31:44 2019 +0200 @@ -252,7 +252,6 @@ if (NOT ORTHANC_SANDBOXED) set(PLATFORM_SOURCES - ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoFont.cpp ${ORTHANC_STONE_ROOT}/Platforms/Generic/WebServiceCommandBase.cpp ${ORTHANC_STONE_ROOT}/Platforms/Generic/WebServiceGetCommand.cpp ${ORTHANC_STONE_ROOT}/Platforms/Generic/WebServicePostCommand.cpp @@ -263,6 +262,12 @@ ${ORTHANC_STONE_ROOT}/Platforms/Generic/OracleDelayedCallExecutor.h ) + if (ENABLE_STONE_DEPRECATED) + list(APPEND PLATFORM_SOURCES + ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Viewport/CairoFont.cpp + ) + endif() + if (ENABLE_SDL OR ENABLE_QT) list(APPEND APPLICATIONS_SOURCES ${ORTHANC_STONE_ROOT}/Applications/Generic/NativeStoneApplicationRunner.cpp @@ -333,6 +338,8 @@ ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/MessagingToolbox.cpp ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/OrthancApiClient.cpp ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/OrthancSlicesLoader.cpp + ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/ParallelSlices.cpp + ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/ParallelSlicesCursor.cpp ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/Slice.cpp ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Toolbox/ViewportGeometry.cpp ${ORTHANC_STONE_ROOT}/Framework/Deprecated/Viewport/IMouseTracker.h @@ -479,13 +486,11 @@ ${ORTHANC_STONE_ROOT}/Framework/Toolbox/GeometryToolbox.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ImageGeometry.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/LinearAlgebra.cpp - ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlices.cpp - ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ParallelSlicesCursor.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/ShearWarpProjectiveTransform.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/SlicesSorter.cpp ${ORTHANC_STONE_ROOT}/Framework/Toolbox/UndoRedoStack.cpp - ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoContext.cpp - ${ORTHANC_STONE_ROOT}/Framework/Viewport/CairoSurface.cpp + ${ORTHANC_STONE_ROOT}/Framework/Wrappers/CairoContext.cpp + ${ORTHANC_STONE_ROOT}/Framework/Wrappers/CairoSurface.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/ImageBuffer3D.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/OrientedVolumeBoundingBox.cpp ${ORTHANC_STONE_ROOT}/Framework/Volumes/VolumeImageGeometry.cpp diff -r abc08ac721d3 -r bc7ee59420a1 UnitTestsSources/UnitTestsMain.cpp --- a/UnitTestsSources/UnitTestsMain.cpp Tue May 28 18:31:17 2019 +0200 +++ b/UnitTestsSources/UnitTestsMain.cpp Tue May 28 18:31:44 2019 +0200 @@ -699,18 +699,22 @@ OrthancStone::VolumeProjection projection = (OrthancStone::VolumeProjection) p; const OrthancStone::CoordinateSystem3D& s = g.GetProjectionGeometry(projection); + ASSERT_THROW(g.GetProjectionSlice(projection, g.GetProjectionDepth(projection)), Orthanc::OrthancException); + for (unsigned int i = 0; i < g.GetProjectionDepth(projection); i++) { - OrthancStone::CoordinateSystem3D plane( - s.GetOrigin() + static_cast(i) * s.GetNormal() * g.GetVoxelDimensions(projection)[2], - s.GetAxisX(), - s.GetAxisY()); + OrthancStone::CoordinateSystem3D plane = g.GetProjectionSlice(projection, i); + + ASSERT_TRUE(IsEqualVector(plane.GetOrigin(), s.GetOrigin() + static_cast(i) * + s.GetNormal() * g.GetVoxelDimensions(projection)[2])); + ASSERT_TRUE(IsEqualVector(plane.GetAxisX(), s.GetAxisX())); + ASSERT_TRUE(IsEqualVector(plane.GetAxisY(), s.GetAxisY())); unsigned int slice; OrthancStone::VolumeProjection q; ASSERT_TRUE(g.DetectSlice(q, slice, plane)); ASSERT_EQ(projection, q); - ASSERT_EQ(i, slice); + ASSERT_EQ(i, slice); } } }