Interpret Footage: the params docs list every key the commands read

execute_checked refuses any key a command's params doc does not list, so
MCP, the CLI and the control channel could not pass preserveRgb,
overrideStart, startTimecode or guessAlpha to file.interpretProxy. The
command reads all four, and the shared Interpret Footage form sends
preserveRgb for every proxy, and overrideStart and startTimecode for a
movie or sequence proxy. file.interpretProxy's doc now lists them. The
docs of file.interpretProxy and file.interpretFootage list premulColor
beside matteColor, which both commands read as the matte color. The
docs of file.interpretFootage, file.applyInterpretation and
file.reloadFootage list `item` beside `items`, which the three commands
already read.
This commit is contained in:
dotCooCoo
2026-10-24 10:01:40 -07:00
parent eb5108786b
commit 557c13b9cd
3 changed files with 36 additions and 4 deletions
+3 -3
View File
@@ -1035,7 +1035,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Main...",
["File", "Interpret Footage"],
Some("Cmd+Alt+G"),
"{items?, frameRate?: fps|\"file\", alpha?: straight|premultiplied|ignore|guess, guessAlpha?, matteColor?, invertAlpha?, loop?, pixelAspect?, fields?: off|upper|lower, colorProfile?: srgb|rec709|rec2020|p3|auto, linearLight?, preserveRgb? (the file's values unconverted), overrideStart?: bool (false: Use Source File Timecode), startTimecode?: timecode|frame (Override Start)}",
"{items?|item?, frameRate?: fps|\"file\", alpha?: straight|premultiplied|ignore|guess, guessAlpha?, matteColor?|premulColor?, invertAlpha?, loop?, pixelAspect?, fields?: off|upper|lower, colorProfile?: srgb|rec709|rec2020|p3|auto, linearLight?, preserveRgb? (the file's values unconverted), overrideStart?: bool (false: Use Source File Timecode), startTimecode?: timecode|frame (Override Start)}",
has_footage_selection,
interpret
),
@@ -1053,7 +1053,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Apply Interpretation",
["File", "Interpret Footage"],
Some("Cmd+Alt+V"),
"{items?}",
"{items?|item?}",
has_interpretation,
apply_interpretation
),
@@ -1084,7 +1084,7 @@ pub fn specs() -> Vec<CommandSpec> {
has_footage_selection,
replace_with_solid
),
cmd!("file.reloadFootage", "Reload Footage", ["File"], Some("Cmd+Alt+L"), "{items?}", has_footage_selection, reload),
cmd!("file.reloadFootage", "Reload Footage", ["File"], Some("Cmd+Alt+L"), "{items?|item?}", has_footage_selection, reload),
cmd!("file.revealInFinder", "Reveal in Finder", ["File"], None, "{item?}", has_footage_selection, reveal_in_finder),
]
}
+1 -1
View File
@@ -229,7 +229,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Proxy...",
["File", "Interpret Footage"],
None,
"{items?|item?, alpha?, matteColor?, invertAlpha?, frameRate?, loop?, pixelAspect?, fields?, colorProfile?, linearLight?}",
"{items?|item?, alpha?, guessAlpha?, matteColor?|premulColor?, invertAlpha?, frameRate?, loop?, pixelAspect?, fields?, colorProfile?, linearLight?, preserveRgb?, overrideStart?, startTimecode? (as file.interpretFootage)}",
has_proxy,
interpret_proxy
),
+32
View File
@@ -187,6 +187,38 @@ fn interpret_proxy_settings_apply_to_the_proxy() {
assert_eq!(f.alpha, AlphaMode::Straight, "the main footage keeps its interpretation");
}
/// Agents and the control channel run commands through `execute_checked`, which refuses keys a
/// params doc does not list. The Interpret Footage commands list every key they read.
#[test]
fn interpret_commands_accept_their_keys_when_checked() {
let mut s = session();
let mov = import(&mut s, "/m/lines.mov");
let b = import(&mut s, "/m/red16.png");
s.execute("file.setProxy", json!({"item": mov.0, "path": "/m/lines.mov"})).unwrap();
s.execute("file.setProxy", json!({"item": b.0, "path": "/m/matte_black.png"})).unwrap();
s.execute_checked("file.interpretProxy", json!({"item": mov.0, "preserveRgb": true, "overrideStart": true, "startTimecode": 25})).unwrap();
let px = s.project.item(mov).unwrap().proxy.clone().unwrap().footage;
assert!(px.preserve_rgb);
assert_eq!(px.start_timecode, Some(25));
s.execute_checked("file.interpretProxy", json!({"item": mov.0, "overrideStart": false})).unwrap();
assert_eq!(s.project.item(mov).unwrap().proxy.as_ref().unwrap().footage.start_timecode, None);
s.execute_checked("file.interpretProxy", json!({"item": b.0, "guessAlpha": true})).unwrap();
assert_eq!(s.project.item(b).unwrap().proxy.as_ref().unwrap().footage.alpha, AlphaMode::Premultiplied);
s.execute_checked("file.interpretProxy", json!({"item": b.0, "premulColor": [1.0, 0.0, 0.0]})).unwrap();
assert_eq!(s.project.item(b).unwrap().proxy.as_ref().unwrap().footage.premul_color, [1.0, 0.0, 0.0]);
// `item` names one footage item, as `items` names several.
s.execute_checked("file.interpretFootage", json!({"item": b.0, "invertAlpha": true, "premulColor": [0.0, 1.0, 0.0]})).unwrap();
s.execute_checked("file.rememberInterpretation", json!({"item": b.0})).unwrap();
s.execute_checked("file.applyInterpretation", json!({"item": mov.0})).unwrap();
let f = match &s.project.item(mov).unwrap().kind {
ItemKind::Footage(f) => f.clone(),
_ => panic!("not footage"),
};
assert!(f.invert_alpha);
assert_eq!(f.premul_color, [0.0, 1.0, 0.0]);
assert_eq!(s.execute_checked("file.reloadFootage", json!({"item": mov.0})).unwrap()["reloaded"], 1);
}
/// Separate Fields: each field becomes a frame at twice the frame rate, the other field's lines
/// interpolated; the dominant field comes first.
#[test]