1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
#pragma once
namespace graphics {
/**
* Simple randomized dithering for converting to 1-bit B/W.
*/
class DitherState {
public:
// Create.
DitherState() : state(0xACE1) {}
// Get the next 16-bit number.
Nat next() {
step();
return state;
}
// Get the current pixel value based on a (linear) brightness value.
Bool pixelValue(Float brightness) {
Nat range = 0x7FF;
Nat deadzone = 20;
Nat val = next() & range;
// Scale 'brightness' to slightly above the range. This preserves pictures that were already b/w.
brightness = brightness * Float(range) + Float(deadzone);
return Float(val + deadzone) < brightness;
}
private:
// Current state. We only use 16 bits.
Nat state;
// Step the LFSR.
void step() {
// Using the polynomial from Wikipedia (Linear-feedback shift register)
Nat lsb = state & 1;
state >>= 1;
if (lsb)
state ^= 0xB400;
}
};
}
|