Skip to content

Commit 5018bbc

Browse files
committed
Add run-length encoding for image parser
1 parent d22de31 commit 5018bbc

1 file changed

Lines changed: 55 additions & 3 deletions

File tree

src/main.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,14 @@ impl DesignerApp {
197197

198198
// Set format to 8-bit for maximum color support
199199
o.format = PictureGraphicFormat::EightBit;
200-
o.options.data_code_type = DataCodeType::Raw;
201200

202201
// We set transparent color to 1 (arbitrary choice) as we
203202
// only use index 15..255 for actual colors
204203
o.transparency_colour = 1;
205204
o.options.transparent = true;
206205

207-
// Convert RGB pixels to color indices
208-
o.data = img
206+
// Convert RGB pixels to color indices (raw data)
207+
let raw_data: Vec<u8> = img
209208
.to_rgba8()
210209
.pixels()
211210
.map(|pixel| {
@@ -218,6 +217,59 @@ impl DesignerApp {
218217
)
219218
})
220219
.collect();
220+
221+
// Run-length encoding lambda that matches Python implementation
222+
let run_length_encode = |data: &[u8]| -> Vec<u8> {
223+
if data.is_empty() {
224+
return Vec::new();
225+
}
226+
227+
let mut compressed = Vec::new();
228+
let mut count: u8 = 1;
229+
let mut current_value = data[0];
230+
231+
for &value in &data[1..] {
232+
if value == current_value && count < 255 {
233+
count += 1;
234+
} else {
235+
// Append current run
236+
compressed.push(count);
237+
compressed.push(current_value);
238+
239+
// Start new run
240+
current_value = value;
241+
count = 1;
242+
}
243+
}
244+
245+
// Append the final run
246+
compressed.push(count);
247+
compressed.push(current_value);
248+
249+
compressed
250+
};
251+
252+
// Compute run-length encoded version
253+
let run_length_data = run_length_encode(&raw_data);
254+
255+
// Automatically select the encoding that produces smaller output
256+
if run_length_data.len() < raw_data.len() {
257+
o.data = run_length_data;
258+
o.options.data_code_type = DataCodeType::RunLength;
259+
log::info!(
260+
"Selected run-length encoding ({} bytes) over raw ({} bytes)",
261+
o.data.len(),
262+
raw_data.len()
263+
);
264+
} else {
265+
o.data = raw_data;
266+
o.options.data_code_type = DataCodeType::Raw;
267+
log::info!(
268+
"Selected raw encoding ({} bytes) over run-length ({} bytes)",
269+
o.data.len(),
270+
run_length_data.len()
271+
);
272+
}
221273
} else {
222274
log::error!("Failed to decode image");
223275
}

0 commit comments

Comments
 (0)