Repository navigation
color picker: locate the pixels holding a module picker's min and max - #1640
Merged
Merged
Conversation
A module picker hands its module the mean, minimum and maximum of each channel over the area, each channel on its own, so a module reading the minimum or the maximum gets three values from three different pixels in general, and nothing showed which. A picker can now declare which extremes its module reads with dt_color_picker_set_extremes(). For such a picker, the helper scans the same blurred input the statistics come from for the first pixel in raster order holding each channel's extreme, which holds exactly the value the module received, and records its position and all its channels. The proxy maps each position back to raw-norm with the inverse of the picker box's own chain and keeps it in dev->color_picker until the next input sample, a reset, a deactivation or the widget's destruction. The darkroom draws a cross in each channel's colour on those pixels; a module names the channel it kept with dt_iop_color_picker_set_deciding_channel(), and that channel's mark becomes a +. dt_iop_color_picker_get_extreme_pixel() gives a module all the channels of one of those pixels, for a module that needs the pixel rather than one channel of it. The marks are drawn while "Display min/max pixel" is checked in the color picker section of the scopes (ui_last/colorpicker_display_extremes, off by default). Locating does not depend on it, since a module may read the pixel. doc/color-picker.md records how the extremes are taken and why the strict per-channel extreme stays: measured on negadoctor's pickers, one pixel chosen by luminance agrees closely on most areas but no longer bounds the area on others, and trimming the extremes, which removes a speck of dust from D max, moves the paper black away from the blacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The locating pass walks the box with one index, row by row, so that its comparisons nest less, and copies the whole pixel with memcpy(). It takes a NULL `extremes` itself, so the helper no longer tests it at each call; the helper's branch for a buffer already in the picker space and its fallback were the same code and are now one. The darkroom marks compute once what depends on whether the module named a channel. Raster order is kept: the old and the new pass gave the same positions and pixels on 201 random boxes, ties and empty boxes included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



A module color picker hands its module the mean, minimum and maximum of each channel over the area, each channel on its own. A module that reads the minimum or the maximum therefore gets three values from three different pixels in general, and nothing showed which pixels they were.
What changes
dt_color_picker_set_extremes(). For such a picker, and only for the input sample,dt_color_picker_helper()scans the same blurred buffer the statistics come from. For each channel it finds the first pixel in raster order holding the minimum and the maximum, so that pixel holds exactly the value the module received.dev->color_pickeruntil the next input sample, a reset, a deactivation or the widget's destruction.dt_iop_color_picker_set_deciding_channel(), and that channel's mark becomes a + while the others stay ×.dt_iop_color_picker_get_extreme_pixel()gives a module all the channels of one of those pixels, for a module that needs the whole pixel rather than one channel of it.ui_last/colorpicker_display_extremesand off by default. Locating runs either way, since a module may read the pixel.No module declares extremes in this PR. negadoctor's pickers are the first users, on a branch that will be rebased onto this one once it is merged.
Why strict per-channel extremes
doc/color-picker.mdrecords the measurements, made on negadoctor's pickers over 20250921_0007:Testing
🤖 Generated with Claude Code