3#include "../utils/Altitude.hpp"
4#include "MorphologicalTree.hpp"
5#include "detail/HigraExportLayoutDetail.hpp"
31 template<AltitudeValue T>
34 throw std::runtime_error(
"Altitude buffer size must match the dense internal-node domain.");
41 template<AltitudeValue T>
43 if constexpr (std::is_floating_point_v<T>) {
44 const long double level =
static_cast<long double>(altitude);
45 if (!std::isfinite(level)) {
46 std::ostringstream
oss;
47 oss <<
context <<
" requires finite floating-point altitudes; value at index "
48 << index <<
" is " << level <<
".";
49 throw std::invalid_argument(
oss.str());
57 template<AltitudeValue T>
59 if constexpr (std::is_floating_point_v<T>) {
60 for (std::size_t index = 0; index < altitude.size(); ++index) {
69 template<AltitudeValue T>
71 if constexpr (std::is_floating_point_v<T>) {
73 throw std::invalid_argument(
"Image altitude validation requires a non-null image.");
76 std::span<const T>(
image->rawData(),
static_cast<std::size_t
>(
image->getSize())),
84 template<AltitudeValue T>
86 if (
nodeId < 0 ||
static_cast<std::size_t
>(
nodeId) >= altitude.size()) {
87 throw std::invalid_argument(
"Altitude access requires a valid internal NodeId.");
89 return altitude[
static_cast<std::size_t
>(
nodeId)];
95 template<AltitudeValue T>
99 throw std::invalid_argument(
"Node residue requires a live internal NodeId.");
112 template<AltitudeValue T>
114 const long double level =
static_cast<long double>(altitude);
115 if constexpr (std::is_floating_point_v<T>) {
116 if (!std::isfinite(level)) {
117 std::ostringstream
oss;
118 oss <<
context <<
" requires finite node altitudes in the uint8 domain [0, 255]; node "
119 <<
nodeId <<
" has altitude " << level <<
".";
120 throw std::invalid_argument(
oss.str());
124 std::ostringstream
oss;
125 oss <<
context <<
" requires node altitudes in the uint8 domain [0, 255]; node "
126 <<
nodeId <<
" has altitude " << level <<
".";
127 throw std::invalid_argument(
oss.str());
129 return static_cast<std::uint8_t
>(altitude);
135 template<AltitudeValue T>
150 template<AltitudeValue T>
173 template<AltitudeValue T>
176 const detail::ExportedHigraLayout
layout = detail::computeExportedHigraLayout(tree, altitude);
192 throw std::runtime_error(
"Each proper part must belong to one alive node when exporting a compact Higra hierarchy.");
210 template<AltitudeValue T>
216 case MorphologicalTreeKind::MAX_TREE:
219 case MorphologicalTreeKind::MIN_TREE:
222 case MorphologicalTreeKind::TREE_OF_SHAPES:
223 case MorphologicalTreeKind::SELF_DUAL_RESIDUAL_TREE:
226 throw std::invalid_argument(
"Unsupported tree type for monotone altitude validation.");
236 throw std::runtime_error(
"Monotonic validation requires every alive non-root node to have an alive parent.");
241 throw std::runtime_error(
"Max-tree altitude buffer must be non-decreasing from parent to child.");
244 throw std::runtime_error(
"Min-tree altitude buffer must be non-increasing from parent to child.");
constexpr NodeId InvalidNode
Sentinel value used to denote an invalid node identifier.
static Ptr create(int rows, int cols)
Creates an owned image with uninitialised pixel values.
Mutable morphological tree built directly on proper parts and dense node ids.
int getNumTotalProperParts() const
Returns the size of the proper-part domain.
int getNumInternalNodeSlots() const
Returns the size of the dense internal-node id domain.
bool isAlive(NodeId nodeId) const
Tests whether a node slot currently represents a live node.
bool isRoot(NodeId nodeId) const
Tests whether nodeId is the current root.
NodeId getProperPartOwner(NodeId properPartId) const
Returns the live node that directly owns properPartId.
MorphologicalTreeKind getTreeType() const noexcept
Returns the current tree type.
int getNumColsOfImage() const
Returns the number of image columns in the attached 2D domain.
void requireNotEditing(const char *context) const
Rejects operations that require a committed connected topology.
AliveNodeRange getAliveNodeIds() const
Returns a fail-fast range over all live node ids.
NodeId getNodeParent(NodeId nodeId) const
Returns the direct parent of nodeId.
int getNumRowsOfImage() const
Returns the number of image rows in the attached 2D domain.
Pure operations over a topology and an explicit altitude buffer.
static T getAltitude(std::span< const T > altitude, NodeId nodeId)
Reads one node altitude from an explicit altitude buffer.
static void validateAltitudeBufferShape(const MorphologicalTree &tree, std::span< const T > altitude)
Validates that an altitude buffer covers the dense internal-node domain.
static void validateUInt8AltitudeDomain(const MorphologicalTree &tree, std::span< const T > altitude, const char *context)
Validates all live node altitudes before materialising an ImageUInt8.
static std::uint8_t requireUInt8AltitudeValue(T altitude, NodeId nodeId, const char *context)
Converts one altitude value to uint8_t, rejecting values outside the output domain.
static void validateFiniteImageAltitudes(const ImagePtr< T > &image, const char *context)
Rejects non-finite floating-point pixels before using an image as altitude source.
static void validateMonotoneAltitude(const MorphologicalTree &tree, std::span< const T > altitude)
Validates altitude monotonicity for max-trees and min-trees.
static void validateFiniteAltitudeValue(T altitude, std::size_t index, const char *context)
Rejects non-finite floating-point altitudes while compiling to a no-op for integral types.
static void validateFiniteAltitudeValues(std::span< const T > altitude, const char *context)
Rejects non-finite floating-point altitudes in a contiguous input range.
static std::pair< std::vector< NodeId >, std::vector< T > > exportHigraHierarchy(const MorphologicalTree &tree, std::span< const T > altitude)
Exports a live rooted topology and explicit altitudes to a compact parent/altitude representation.
static AltitudeDiff< T > getNodeResidue(const MorphologicalTree &tree, std::span< const T > altitude, NodeId nodeId)
Computes the altitude difference between one node and its parent.
static ImagePtr< T > reconstructImage(const MorphologicalTree &tree, std::span< const T > altitude, const char *context="TreeAltitudeAlgorithms::reconstructImage")
Reconstructs a typed image from topology ownership and explicit node altitudes.
Owning result for one computed scalar attribute layout and buffer.