roxify 1.13.3 → 1.13.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,15 @@ use std::io::{Write, BufWriter};
2
2
  use std::fs::File;
3
3
  use std::path::Path;
4
4
 
5
+ use crate::png_chunk_writer::{ChunkedIdatWriter, write_png_chunk};
6
+
5
7
  const PNG_HEADER: &[u8] = &[137, 80, 78, 71, 13, 10, 26, 10];
6
8
  const PIXEL_MAGIC: &[u8] = b"PXL1";
7
9
  const MARKER_START: [(u8, u8, u8); 3] = [(255, 0, 0), (0, 255, 0), (0, 0, 255)];
8
10
  const MARKER_END: [(u8, u8, u8); 3] = [(0, 0, 255), (0, 255, 0), (255, 0, 0)];
9
11
  const MARKER_ZSTD: (u8, u8, u8) = (0, 255, 0);
10
12
  const MAGIC: &[u8] = b"ROX1";
13
+ const HEADER_VERSION_V2: u8 = 2;
11
14
 
12
15
  pub fn encode_to_png_file(
13
16
  data: &[u8],
@@ -75,10 +78,6 @@ pub fn encode_to_png_file(
75
78
 
76
79
  let adler = crate::core::adler32_bytes(&scanlines);
77
80
 
78
- const MAX_BLOCK: usize = 65535;
79
- let num_blocks = (scanlines_total + MAX_BLOCK - 1) / MAX_BLOCK;
80
- let idat_len = 2 + num_blocks * 5 + scanlines_total + 4;
81
-
82
81
  let f = File::create(output_path)?;
83
82
  let mut w = BufWriter::with_capacity(16 * 1024 * 1024, f);
84
83
 
@@ -89,15 +88,15 @@ pub fn encode_to_png_file(
89
88
  ihdr[4..8].copy_from_slice(&(height as u32).to_be_bytes());
90
89
  ihdr[8] = 8;
91
90
  ihdr[9] = 2;
92
- write_chunk_small(&mut w, b"IHDR", &ihdr)?;
91
+ write_png_chunk(&mut w, b"IHDR", &ihdr)?;
93
92
 
94
- write_idat_direct(&mut w, &scanlines, idat_len, adler)?;
93
+ write_idat_direct(&mut w, &scanlines, adler)?;
95
94
  drop(scanlines);
96
95
 
97
96
  if let Some(fl) = file_list {
98
- write_chunk_small(&mut w, b"rXFL", fl.as_bytes())?;
97
+ write_png_chunk(&mut w, b"rXFL", fl.as_bytes())?;
99
98
  }
100
- write_chunk_small(&mut w, b"IEND", &[])?;
99
+ write_png_chunk(&mut w, b"IEND", &[])?;
101
100
  w.flush()?;
102
101
 
103
102
  Ok(())
@@ -106,20 +105,14 @@ pub fn encode_to_png_file(
106
105
  fn write_idat_direct<W: Write>(
107
106
  w: &mut W,
108
107
  scanlines: &[u8],
109
- idat_len: usize,
110
108
  adler: u32,
111
109
  ) -> anyhow::Result<()> {
112
110
  const MAX_BLOCK: usize = 65535;
113
111
 
114
- w.write_all(&(idat_len as u32).to_be_bytes())?;
115
- w.write_all(b"IDAT")?;
116
-
117
- let mut crc = crc32fast::Hasher::new();
118
- crc.update(b"IDAT");
112
+ let mut idat = ChunkedIdatWriter::new(w);
119
113
 
120
114
  let zlib = [0x78u8, 0x01];
121
- w.write_all(&zlib)?;
122
- crc.update(&zlib);
115
+ idat.write_all(&zlib)?;
123
116
 
124
117
  let mut offset = 0;
125
118
  while offset < scanlines.len() {
@@ -132,20 +125,15 @@ fn write_idat_direct<W: Write>(
132
125
  !chunk_size as u8,
133
126
  (!(chunk_size >> 8)) as u8,
134
127
  ];
135
- w.write_all(&header)?;
136
- crc.update(&header);
128
+ idat.write_all(&header)?;
137
129
  let slice = &scanlines[offset..offset + chunk_size];
138
- w.write_all(slice)?;
139
- crc.update(slice);
130
+ idat.write_all(slice)?;
140
131
  offset += chunk_size;
141
132
  }
142
133
 
143
134
  let adler_bytes = adler.to_be_bytes();
144
- w.write_all(&adler_bytes)?;
145
- crc.update(&adler_bytes);
146
-
147
- w.write_all(&crc.finalize().to_be_bytes())?;
148
- Ok(())
135
+ idat.write_all(&adler_bytes)?;
136
+ idat.finish()
149
137
  }
150
138
 
151
139
  fn build_flat_buffer(
@@ -175,12 +163,12 @@ fn build_flat_buffer(
175
163
  }
176
164
 
177
165
  fn build_meta_pixel(payload: &[u8], name: Option<&str>, file_list: Option<&str>) -> anyhow::Result<Vec<u8>> {
178
- let version = 1u8;
166
+ let version = HEADER_VERSION_V2;
179
167
  let name_bytes = name.map(|n| n.as_bytes()).unwrap_or(&[]);
180
168
  let name_len = name_bytes.len().min(255) as u8;
181
- let payload_len_bytes = (payload.len() as u32).to_be_bytes();
169
+ let payload_len_bytes = (payload.len() as u64).to_be_bytes();
182
170
 
183
- let mut result = Vec::with_capacity(1 + 1 + name_len as usize + 4 + payload.len() + 256);
171
+ let mut result = Vec::with_capacity(1 + 1 + name_len as usize + 8 + payload.len() + 256);
184
172
  result.push(version);
185
173
  result.push(name_len);
186
174
  if name_len > 0 {
@@ -199,14 +187,3 @@ fn build_meta_pixel(payload: &[u8], name: Option<&str>, file_list: Option<&str>)
199
187
  Ok(result)
200
188
  }
201
189
 
202
- fn write_chunk_small<W: Write>(w: &mut W, chunk_type: &[u8; 4], data: &[u8]) -> anyhow::Result<()> {
203
- w.write_all(&(data.len() as u32).to_be_bytes())?;
204
- w.write_all(chunk_type)?;
205
- w.write_all(data)?;
206
-
207
- let mut h = crc32fast::Hasher::new();
208
- h.update(chunk_type);
209
- h.update(data);
210
- w.write_all(&h.finalize().to_be_bytes())?;
211
- Ok(())
212
- }