// 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.
let y0 = rect.origin.1as isize - 2; let y1 = rect.end().1as isize + 2;
let lf_size = src[0].size();
for yy in y0..y1 { let sy = mirror(yy, lf_size.1);
// Fill in input. for c in0..3 { let bufy = (yy + LF_ROW_OFFSET as isize) as usize; let row = lf_rows[c].get_row_mut::<f32>(bufy); let srow = src[c].row(sy); let off = RowBuffer::x0_offset::<f32>();
row[off..off + len].copy_from_slice(&srow[x0..x1]);
row[off - 1] = srow[mirror(x0 as isize - 1, lf_size.0)];
row[off - 2] = srow[mirror(x0 as isize - 2, lf_size.0)];
row[off + len] = srow[mirror(x1 as isize, lf_size.0)];
row[off + len + 1] = srow[mirror(x1 as isize + 1, lf_size.0)];
}
if yy < y0 + 4 { continue;
}
let y = yy as usize - 2;
// Upsample. for c in0..3 { let off = RowBuffer::x0_offset::<f32>() - 2; let input_rows_refs = [
&lf_rows[c].get_row::<f32>(y + LF_ROW_OFFSET - 2)[off..],
&lf_rows[c].get_row::<f32>(y + LF_ROW_OFFSET - 1)[off..],
&lf_rows[c].get_row::<f32>(y + LF_ROW_OFFSET)[off..],
&lf_rows[c].get_row::<f32>(y + LF_ROW_OFFSET + 1)[off..],
&lf_rows[c].get_row::<f32>(y + LF_ROW_OFFSET + 2)[off..],
]
.into_iter()
.collect(); let input_channels = Channels::new(input_rows_refs, 1, 5);
let image_metadata = &self.decoder_state.file_header.image_metadata; if !image_metadata.xyb_encoded || !image_metadata.extra_channel_info.is_empty() { // We only render LF frames for XYB VarDCT images with no extra channels. // TODO(veluca): we might want to relax this to "no alpha". return Ok(false);
} let color_type = pixel_format.color_type; let data_format = pixel_format.color_data_format.unwrap(); if pixel_format.color_data_format.is_none()
|| output_buffers.is_empty()
|| !matches!(
color_type,
JxlColorType::Rgb | JxlColorType::Rgba | JxlColorType::Bgr | JxlColorType::Bgra,
)
{ // We only render color data, and only to 3- or 4- channel output buffers. return Ok(false);
} // We already have a fully-rendered frame and we are not requesting to re-render // specific regions. ifself.decoder_state.lf_frame_was_rendered && changed_regions.is_none() { return Ok(false);
} if changed_regions.is_none() { self.decoder_state.lf_frame_was_rendered = true;
}
let sz = &self.decoder_state.file_header.size; let xsize = sz.xsize() as usize; let ysize = sz.ysize() as usize;
letmut regions_storage;
let regions = iflet Some(regions) = changed_regions {
regions
} else {
regions_storage = vec![]; for i in (0..xsize.div_ceil(8)).step_by(256) { let x0 = i; let x1 = (i + 256).min(xsize.div_ceil(8));
regions_storage.push(Rect {
origin: (x0, 0),
size: (x1 - x0, ysize.div_ceil(8)),
});
}
®ions_storage[..]
};
let orientation = image_metadata.orientation; let info = SaveStageBufferInfo {
downsample: (0, 0),
orientation,
byte_size: data_format.bytes_per_sample() * color_type.samples_per_pixel(),
after_extend: false,
}; let info = [Some(info)]; letmut bufs = [Some(JxlOutputBuffer::reborrow(&mut output_buffers[0]))]; letmut bufs = BufferSplitter::new(&mut bufs); for r in regions { let upsampled_rect = Rect {
size: (r.size.0 * 8, r.size.1 * 8),
origin: (r.origin.0 * 8, r.origin.1 * 8),
}; let upsampled_rect = upsampled_rect.clip((xsize, ysize)); letmut bufs = bufs.get_local_buffers(
&info,
upsampled_rect, false,
(xsize, ysize),
(xsize, ysize),
(0, 0),
); self.render_lf_frame_rect(
color_type,
data_format,
*r,
upsampled_rect,
orientation,
&mut bufs,
(xsize, ysize),
&output_color_info,
&output_tf,
)?;
}
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.