Function tryRgbHistogram256WithValidity
Build an RGB histogram using an explicit validity/NoData mask.
RgbHistogramError tryRgbHistogram256WithValidity(
scope raster .view .RasterView!(ubyte) rgb,
raster .region .Region2D roi,
scope raster .view .RasterView!(ubyte) validity,
ref RgbHistogram256 published
) @safe;
Unlike the selection-mask overload, zero means that the source sample is not valid and must not contribute to statistics; nonzero means valid. The mask does not alter pixels and is not an editing-selection or alpha policy. The caller is responsible for constructing it from source-specific NoData rules.
Example
Count two stored RGB pixels, then include only the first using a binary mask. Allocation here belongs to the consumer, not the histogram.
import core .stdc .stdlib : malloc;
import raster : OwnedByteResource, PlaneByteLayout, RasterLease,
tryAdoptMallocResource, tryImportOwnedRaster;
// The consumer creates a retained, interleaved two-pixel RGB raster.
auto bytes = cast(ubyte*)malloc(6);
assert(bytes !is null);
bytes[0 .. 6] = [cast(ubyte)0, 64, 255, 128, 192, 17];
OwnedByteResource owned;
assert(tryAdoptMallocResource(bytes, 6, owned));
const PlaneByteLayout[3] channels = [
PlaneByteLayout(0, 6, 3), PlaneByteLayout(1, 6, 3),
PlaneByteLayout(2, 6, 3)
];
RasterLease!ubyte image;
assert(tryImportOwnedRaster!ubyte(owned, channels[],
Region2D(0, 0, 2, 1), image) .ok);
RgbHistogram256 result;
const roi = Region2D(0, 0, 2, 1);
assert(tryRgbHistogram256(image .view(), roi, result) ==
RgbHistogramError .none);
assert(result .includedPixels == 2 && result .excludedPixels == 0);
assert(result .bins[0][0] == 1 && result .bins[0][128] == 1);
assert(result .minimum == [0, 64, 17]);
assert(result .maximum == [128, 192, 255]);
assert(result .mean == [64.0, 128.0, 136.0]);
auto maskBytes = cast(ubyte*)malloc(2);
assert(maskBytes !is null);
maskBytes[0 .. 2] = [cast(ubyte)1, 0];
OwnedByteResource maskOwned;
assert(tryAdoptMallocResource(maskBytes, 2, maskOwned));
const PlaneByteLayout[1] maskPlane = [PlaneByteLayout(0, 2, 1)];
RasterLease!ubyte mask;
assert(tryImportOwnedRaster!ubyte(maskOwned, maskPlane[], roi, mask) .ok);
assert(tryRgbHistogram256(image .view(), roi, mask .view(), result) ==
RgbHistogramError .none);
assert(result .includedPixels == 1 && result .excludedPixels == 1);
assert(result .mean == [0.0, 64.0, 255.0]); // mask byte 1 includes once
const previous = result;
assert(tryRgbHistogram256(image .view(), Region2D(2, 0, 1, 1), result)
== RgbHistogramError .invalidRegion);
assert(result == previous); // returned failure preserves publication