curves: add per-channel tab support using avfilter.curves
Closes #2187 (closed)
Adds per-channel tab support to the Curves effect by introducing a new avfilter.curves based effect with All/R/G/B tabs.
What changed
- Each channel is a SEPARATE
av_curveparameter in the XML (av.master,av.r,av.g,av.b), each with its own<name>. The firstav_curveparam creates theCurveParamWidget; subsequent ones add a tab to the existing widget viaaddAvCurveTab(). Each tab is bound to its ownQPersistentModelIndex, so per-channel curve state lives in the model, not in a separate in-widget cache. - Added
QTabBar(All, R, G, B) toKisCurveWidget; tabs only appear for avfilter.curves, frei0r.curves is completely untouched - New
AvCurveparam type handles per-parameter serialization; converts KisCubicCurve format to avfilter.curves MLT properties on write, and back on project load - New
avfilter_curves.xmleffect definition - Point coordinates within ~0.00266 x-distance of each other are snapped to a minimum safe distance rather than rejected, avoiding an avfilter/MLT crash on near-duplicate points
- Each channel param supports an optional
colorattribute, used to draw that channel's curve line and distinguish it at a glance - Reset button resets only the currently active channel's curve to identity
- Editable Input/Output spinboxes show the selected point's X/Y, updating live on selection/drag and writing back to the model on edit
- When editing one channel, other channels' curves are drawn faintly (in their own colors) if they've been edited away from identity; similar to GIMP's curve overlay behavior. The active channel stays fully opaque and interactive on top.
Testing
- Apply "Curves (avfilter)" to a clip
- Pull the All tab curve; whole image affected
- Switch to R tab, pull curve up; red tint applied, R tab's curve line colored accordingly
- Switch back to All; curve preserved, R's edited curve appears as a faint ghost while editing All (if All has also been edited); actually ghosts show OTHER edited channels while one is active, so verify by editing R then switching to G: R should appear as a red ghost line
- Use the reset button on the active tab; only that channel resets, its ghost disappears if it was showing
- Select a point; confirm Input/Output spinboxes update and are editable
- Save and reopen project; all curves restore correctly, including edited-vs-default state
- Undo/redo curve edits; no crash, model and UI stay in sync
Notes
- frei0r.bezier_curves and frei0r.curves behavior is unchanged
- Backward compatibility with existing projects preserved
- Unit tests added (
tests/avcurvetest.cpp), 48 assertions covering parameter loading, format conversion, point snapping, per-channel independence, and default state; all passing
Edited by Yash Bavadiya