Compare commits

..
Author SHA1 Message Date
Dylan M. Taylor 11fec161cc Fonts: ignore variation tags the font has no axis for 2026-11-03 20:32:00 +00:00
4 changed files with 9 additions and 32 deletions
-19
View File
@@ -216,9 +216,6 @@ pub struct Decoder {
out: VecDeque<Output>,
/// pts of the temporal unit being decoded.
pts: i64,
/// Bytes of the repeated-frame (`show_existing_frame`) pictures queued by the current
/// [`Decoder::decode_pts`] call; each is copied out in full when it is returned.
chunk_output_bytes: u64,
}
/// Whether `pictures` frames of `width` x `height`, padded as `FrameBuf::new` pads them, fit in
@@ -301,7 +298,6 @@ impl Decoder {
memory_budget: deckcraft_bitstream::budget::DECODE_MEMORY_BUDGET,
out: VecDeque::new(),
pts: 0,
chunk_output_bytes: 0,
}
}
@@ -334,7 +330,6 @@ impl Decoder {
/// [`Decoder::decode`] with a timestamp that the pictures shown by this chunk carry.
pub fn decode_pts(&mut self, data: &[u8], pts: i64) -> Result<Vec<Picture>> {
self.pts = pts;
self.chunk_output_bytes = 0;
let parsed = self.parse(data);
// Hand out what is finished, then report a parse error.
let mut pics = Vec::new();
@@ -505,20 +500,6 @@ impl Decoder {
let idx = fh.frame_to_show_map_idx;
let slot = self.ref_frames[idx].clone().ok_or(Error::Invalid("show_existing_frame of an empty slot"))?;
let info = self.refs[idx].clone();
// Every repeat is copied out whole, so a compact header must not queue more
// pictures than half the decoder budget allows.
let shape = deckcraft_bitstream::budget::PictureShape {
width: u64::from(info.upscaled_width),
height: u64::from(info.frame_height),
shift_x: u32::from(seq.color.subsampling_x),
shift_y: u32::from(seq.color.subsampling_y),
chroma_planes: if seq.color.mono_chrome { 0 } else { 2 },
bytes_per_sample: 2,
};
self.chunk_output_bytes = self.chunk_output_bytes.saturating_add(shape.bytes().unwrap_or(u64::MAX));
if self.chunk_output_bytes > self.memory_budget / 2 {
return Err(Error::Invalid("repeated frame outputs exceed the decoder memory budget"));
}
let o = Output::Existing {
slot: slot.clone(),
seq: seq.clone(),
+7 -3
View File
@@ -1215,9 +1215,8 @@ impl FontDb {
fn instance(&self, family: &str, style: &str) -> Option<Arc<FontFace>> {
let open = style.find('{')?;
let base = self.find(family, style[..open].trim())?;
if base.skrifa().is_none_or(|f| f.axes().is_empty()) {
return Some(base);
}
let Some(font) = base.skrifa().filter(|f| !f.axes().is_empty()) else { return Some(base) };
let axis_tags: Vec<[u8; 4]> = font.axes().iter().map(|a| a.tag().to_be_bytes()).collect();
let mut coords = base.coords.clone();
for kv in style[open + 1..].trim_end_matches('}').split(',') {
let (k, v) = kv.split_once(':')?;
@@ -1227,6 +1226,11 @@ impl FontDb {
return None;
}
let tag = [k[0], k[1], k[2], k[3]];
// A tag the font has no axis for changes nothing; keeping it would grow the list with
// every distinct tag in the style text.
if !axis_tags.contains(&tag) {
continue;
}
match coords.iter_mut().find(|(t, _)| *t == tag) {
Some(c) => c.1 = v,
None => coords.push((tag, v)),
+1 -3
View File
@@ -404,9 +404,7 @@ impl Decoder {
chroma_planes: if chroma == 0 { 0 } else { 2 },
bytes_per_sample: 2,
};
// Output frames waiting to be returned stay allocated after they leave the DPB.
let queued = self.out_queue.iter().filter(|o| !self.dpb.entries.iter().any(|e| Arc::ptr_eq(&e.frame, &o.frame))).count();
let pictures = u64::from(sps.max_dec_pic_buffering) + 1 + self.max_in_flight as u64 + queued as u64;
let pictures = u64::from(sps.max_dec_pic_buffering) + 1 + self.max_in_flight as u64;
ensure!(
shape.fits(pictures, self.memory_budget),
"{}x{} pictures with {pictures} in the decoder exceed the memory budget",
+1 -7
View File
@@ -166,17 +166,11 @@ impl Decoder {
if frames.len() > 1 {
self.stats.superframes += 1;
}
let queued = self.pending.len();
for f in frames {
if f.is_empty() {
continue;
}
if let Err(e) = self.decode_frame(f, pts) {
// A failed sample outputs nothing: drop what its earlier subframes queued so a
// later drain does not expand each repeat into its own picture.
self.pending.truncate(queued);
return Err(e);
}
self.decode_frame(f, pts)?;
}
Ok(self.drain(false))
}