pub struct Scans {
pub metadata_end: Option<usize>,
pub frame_render_start: Option<usize>,
pub first_scan_end: Option<usize>,
pub good_scan_end: Option<usize>,
pub file_size: usize,
}Expand description
Key positions in a progressive image file
cloudflare_soos::Scans::from_file(&input_file)?.cf_priority_change_headers()?;Fields§
§metadata_end: Option<usize>Byte position where metadata ends. This many bytes are preceeding start of pixel data. It’s usually <200 bytes, unless the image has color profiles or other bloat.
frame_render_start: Option<usize>All metadata + minimum amount of data to make browsers render anything (in case they don’t reserve space based on metadata)
first_scan_end: Option<usize>Byte position where the first (lowest-quality) progressive scan ends. This many bytes are needed to display anything on screen. It’s usually 12-15% of the file size.
good_scan_end: Option<usize>Byte position where most of ok-quality pixel data ends. This many bytes are needed to display a good-enough image. It’s usually about 50% of the file size.
file_size: usizeSize of the whole image file, in bytes. The size is only used for heuristics, so the value may be approximate, but it must be greater than all other positions set in this struct.
Implementations§
Source§impl Scans
impl Scans
Sourcepub fn from_file(input_file: &[u8]) -> Result<Self>
pub fn from_file(input_file: &[u8]) -> Result<Self>
Analyze an image file to find byte ranges of its metadata and progressive scans
Examples found in repository?
More examples
11fn main() {
12 let mut args = env::args().skip(1);
13 let input_path = args.next().unwrap_or_else(|| usage());
14 let input_file = fs::read(input_path).expect("The specified input file could not be opened");
15
16 let scans = soos::Scans::from_file(&input_file).expect("Scan failed");
17
18 println!("{scans:#?}");
19 let (pri, pri_change) = scans.cf_priority_change_headers().unwrap();
20 println!("cf-priority: {pri}");
21 println!("cf-priority-change: {pri_change}");
22}13fn main() {
14 let mut args = env::args_os().skip(1);
15 let input_path = PathBuf::from(args.next().unwrap_or_else(|| usage()));
16 let input_file = fs::read(&input_path).expect("The specified input file could not be opened");
17
18 let scans = soos::Scans::from_file(&input_file).expect("Scan failed");
19
20 println!("{scans:#?}");
21
22 write_up_to(&input_path, &input_file, "0-meta", scans.metadata_end);
23 write_up_to(
24 &input_path,
25 &input_file,
26 "1-render",
27 scans.frame_render_start,
28 );
29 write_up_to(
30 &input_path,
31 &input_file,
32 "2-first_scan",
33 scans.first_scan_end,
34 );
35 write_up_to(&input_path, &input_file, "3-good_scan", scans.good_scan_end);
36}Sourcepub fn cf_priority_change_headers(&self) -> Result<(String, String)>
pub fn cf_priority_change_headers(&self) -> Result<(String, String)>
Assumes the HTTP2 priorities are:
- 50 = critical js/css, fonts + image metadata
- 30 = regular js/css, followed by other images + JPEG DC
- 20 = low-priority image bodies
- 10 = idle
Returns cf-priority and cf-priority-change header values, respectively.
Examples found in repository?
11fn main() {
12 let mut args = env::args().skip(1);
13 let input_path = args.next().unwrap_or_else(|| usage());
14 let input_file = fs::read(input_path).expect("The specified input file could not be opened");
15
16 let scans = soos::Scans::from_file(&input_file).expect("Scan failed");
17
18 println!("{scans:#?}");
19 let (pri, pri_change) = scans.cf_priority_change_headers().unwrap();
20 println!("cf-priority: {pri}");
21 println!("cf-priority-change: {pri_change}");
22}