mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
G5: a still decoded larger than its nominal size is resampled like the renderer does (#1812)
Review: still_at_size returned a smart object's pixels unresampled when they differed from the footage's nominal size. It now follows footage_buf: pixels larger than nominal are resampled to the requested size, smaller ones are left for the renderer to scale up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -774,13 +774,16 @@ impl Inner {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn prefetch(self: &Arc<Self>, _footage: &Footage, _t: Tick, _size: Option<(u32, u32)>, _float: FloatCurve) {}
|
||||
|
||||
/// A still (image file or sequence frame) of the footage's own size, at `loc.key.size` when
|
||||
/// one is set: resampled as the renderer would ([`FootageSource::frame_at_size`]), so the
|
||||
/// pool keeps the reduced frame and a reduced-resolution render neither decodes nor resamples
|
||||
/// a large still again for every frame (#1812: 21120-px plates at Quarter).
|
||||
/// A still (image file or sequence frame) at `loc.key.size` when one is set: resampled as the
|
||||
/// renderer would ([`FootageSource::frame_at_size`]), so the pool keeps the reduced frame and a
|
||||
/// reduced-resolution render neither decodes nor resamples a large still again for every frame
|
||||
/// (#1812: 21120-px plates at Quarter). Like the renderer's `footage_buf`, an image decoded
|
||||
/// larger than the footage's nominal size (a smart object's pixels) is resampled too, and one
|
||||
/// decoded smaller is not (the renderer scales the layer instead).
|
||||
fn still_at_size(img: Image, loc: &Loc, footage: &Footage) -> Image {
|
||||
let (w, h) = loc.key.size;
|
||||
if w == 0 || h == 0 || (img.width, img.height) != (footage.width, footage.height) || (w, h) == (img.width, img.height) {
|
||||
let smaller = img.width == 0 || footage.width as f64 / img.width as f64 > 1.0 + 1e-9;
|
||||
if w == 0 || h == 0 || smaller || (w, h) == (img.width, img.height) {
|
||||
return img;
|
||||
}
|
||||
effectcraft_raster::resample(&img, w, h)
|
||||
|
||||
@@ -608,6 +608,14 @@ fn stills_at_reduced_sizes_are_resampled_once() {
|
||||
assert!(Arc::ptr_eq(&sized, &again), "{w}×{h}: kept at that size");
|
||||
assert_eq!(pool.stats().misses, misses, "{w}×{h}: not decoded again");
|
||||
}
|
||||
// Pixels larger than the nominal size (a smart object's) are resampled as the renderer does;
|
||||
// smaller ones are left as they are (the renderer scales the layer up instead).
|
||||
let larger = Footage { width: 306, height: 48, ..f.clone() };
|
||||
let sized = MediaPool::new().frame_at_size(ItemId(1), &larger, Tick::ZERO, 153, 24).expect("frame");
|
||||
assert_eq!(*sized, effectcraft_raster::resample(&full, 153, 24));
|
||||
let smaller = Footage { width: 1226, height: 194, ..f.clone() };
|
||||
let kept = MediaPool::new().frame_at_size(ItemId(1), &smaller, Tick::ZERO, 306, 48).expect("frame");
|
||||
assert_eq!(*kept, *full);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user