Milestone 4 of 8
Implement brightness and masks safely
Use wider signed arithmetic and clipping for brightness, validate boolean mask and fill shapes, and preserve every unmasked pixel exactly.
Unsigned pixel values have a trap: adding to uint8 can wrap around instead
of reaching the next valid value. Make the arithmetic and mask contract
explicit.
Goal
Implement overflow-safe brightness adjustment and boolean masks while
preserving unmasked pixels, channel shape, and uint8 output.
Operations
Implement:
adjust_brightness(image, delta)
apply_mask(image, mask, fill_values)
Require an integer delta from -255 through 255. Calculate brightness in
a wider signed dtype, clip to [0, 255], and convert back to uint8.
Require a boolean mask of shape (height, width) and one fill value from 0
through 255 per channel. Replace masked pixels only; preserve every unmasked
pixel.
Deliverables
Extend src/operations.py with both operations. Save exact pixel checks for
zero, positive, and negative deltas, clipping boundaries, an all-false and an
all-true mask, and one mask with different fill values per RGB channel.
Checks
Use pixels at 0, 1, 254, and 255. Check positive and negative clipping and prove that no value wraps around. Reject non-integer and out-of-range deltas. Reject masks with the wrong shape or dtype and invalid fill length or values. Check that masked pixels receive the configured values, unmasked pixels are identical, and source arrays remain unchanged.
Run each operation twice and compare exact arrays. Check grayscale and RGB arrays, including a length-one channel axis. Do not treat a nonzero integer mask as a boolean mask by coercion.
Workspace
Keep arithmetic, validation, and mask checks in src/operations.py. The local
mean filter belongs to the next milestone.
Hints
HintWiden before adding
delta=1, calculate
255 + 1 in a signed type, clip it to 255, then convert.HintThe mask has no channel axis
Review
Which result would an unchecked uint8 addition produce for 255 plus 1? Pick
one masked RGB pixel and explain why all its channels change together.
How to check your work
Checks compare extreme-value tables, clipping, mask shape checks, unmasked equality, and source immutability with the fixtures. The operations do not claim to make an image brighter in a perceptual sense.