Function tryRgbEqualizationLut
Build a separate equalization lookup table for each stored RGB8 channel. For a nonconstant channel, the first observed byte maps to 0 and each later byte maps to roundHalfUp(255 * (CDF(byte) - CDF(first)) / (includedPixels - CDF(first))). Bytes before the first observed byte map to 0. A channel with only one observed byte gets an identity table, so a flat channel is not arbitrarily recoloured. Integer arithmetic is exact through the full ulong count domain; no floating-point CDF is formed.
bool tryRgbEqualizationLut(
ref const(RgbHistogram256) histogram,
ref ubyte[256][3] published
) pure nothrow @nogc @safe;
A histogram's optional binary mask only determines which samples estimate the distribution. This table itself does not choose output pixels. Applying it independently to stored RGB channels may change colour relationships; there is no luminance, transfer-function, ICC, alpha or NoData inference. A malformed public histogram or empty selection returns false and preserves published. No raster is read or allocated.
Parameters
| Name | Description |
|---|---|
| histogram | Completed RGB histogram returned by tryRgbHistogram256. |
| published | Mapping indexed as [channel][storedByte], assigned on success. |
Returns
true when all three lookup tables are published.
Example
Work entirely from an already completed histogram. A two-pixel channel has its lower value at the 50th nearest rank and upper value at the 51st.
RgbHistogram256 h;
h .includedPixels = 2;
h .bins[0][10] = 1;
h .bins[0][200] = 1;
h .bins[1][0] = 2;
h .bins[2][255] = 2;
ulong[256][3] cumulative;
assert(tryRgbCumulativeCounts(h, cumulative));
assert(cumulative[0][9] == 0 && cumulative[0][10] == 1 &&
cumulative[0][199] == 1 && cumulative[0][200] == 2);
foreach (channel; 0 .. 3)
assert(cumulative[channel][255] == h .includedPixels);
ubyte[3] values;
assert(tryRgbPercentile(h, 0, values) && values == [10, 0, 255]);
assert(tryRgbPercentile(h, 50, values) && values == [10, 0, 255]);
assert(tryRgbPercentile(h, 51, values) && values == [200, 0, 255]);
assert(tryRgbPercentile(h, 100, values) && values == [200, 0, 255]);
ubyte[256][3] lut;
assert(tryRgbPercentileStretchLut(h, 0, 100, lut));
assert(lut[0][9] == 0 && lut[0][10] == 0 &&
lut[0][105] == 128 && lut[0][200] == 255 &&
lut[0][255] == 255);
// Both constant channels have identity lookup tables.
foreach (value; 0 .. 256)
assert(lut[1][value] == value && lut[2][value] == value);
assert(tryRgbEqualizationLut(h, lut));
assert(lut[0][9] == 0 && lut[0][10] == 0 &&
lut[0][199] == 0 && lut[0][200] == 255);
foreach (value; 0 .. 256)
assert(lut[1][value] == value && lut[2][value] == value);