// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// Information for splitting the output buffers. #[derive(Debug)] pubstruct SaveStageBufferInfo { pub downsample: (u8, u8), pub orientation: Orientation, pub byte_size: usize, pub after_extend: bool,
}
/// Data structure responsible for handing out access to portions of the output buffers. pubstruct BufferSplitter<'a, 'b> {
buffers: &'a mut [Option<JxlOutputBuffer<'b>>],
requested_rects: Vec<Rect>,
}
pub(crate) fn get_local_buffers(
&mutself,
save_buffer_info: &[Option<SaveStageBufferInfo>],
rect: Rect,
outside_current_frame: bool,
frame_size: (usize, usize),
full_image_size: (usize, usize),
frame_origin: (isize, isize),
) -> Vec<Option<JxlOutputBuffer<'_>>> { self.requested_rects.push(rect); letmut local_buffers = vec![]; let buffers = &mut *self.buffers;
local_buffers.reserve(buffers.len()); for _ in0..buffers.len() {
local_buffers.push(None::<JxlOutputBuffer>);
} let rect = if !outside_current_frame {
rect.clip(frame_size)
} else {
rect
}; for (i, (info, buf)) in save_buffer_info.iter().zip(buffers.iter_mut()).enumerate() { let Some(bi) = info else { // We never write to this buffer. continue;
}; let Some(buf) = buf.as_mut() else { // The buffer to write into was not provided. continue;
}; if outside_current_frame && !bi.after_extend { // Before-extend stages do not write to rects outside the current frame. continue;
} letmut channel_rect = rect.downsample(bi.downsample); if !outside_current_frame { let frame_size = (
frame_size.0.shrc(bi.downsample.0),
frame_size.1.shrc(bi.downsample.1),
);
channel_rect = channel_rect.clip(frame_size); if bi.after_extend { // clip this rect to its visible area in the full image (in full image coordinates). let origin = (
rect.origin.0as isize + frame_origin.0,
rect.origin.1as isize + frame_origin.1,
); let end = (
origin.0 + rect.size.0as isize,
origin.1 + rect.size.1as isize,
); let origin = (origin.0.max(0) as usize, origin.1.max(0) as usize); let end = (
end.0.min(full_image_size.0as isize).max(0) as usize,
end.1.min(full_image_size.1as isize).max(0) as usize,
);
channel_rect = Rect {
origin,
size: (
end.0.saturating_sub(origin.0),
end.1.saturating_sub(origin.1),
),
};
}
} if channel_rect.size.0 == 0 || channel_rect.size.1 == 0 { // Buffer would be empty anyway. continue;
} let channel_rect = bi.orientation.display_rect(channel_rect, full_image_size); let channel_rect = channel_rect.to_byte_rect_sz(bi.byte_size);
local_buffers[i] = Some(buf.rect(channel_rect));
}
local_buffers
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.