Implement T.4 MH (Modified Huffman) encoder

- encoder/mh.rs: Full T.4 Group 3 MH encoding implementation
- Uses ITU-T T.4 standard Huffman tables for white/black runs
- Adds EOL codes and RTC (6 EOLs) at document end
- Class2Send now encodes pixels to MH before transmission
- CLI convert command shows MH encoded size

Test result: 467KB raw pixels → 14.6KB MH encoded (~32:1 compression)
This commit is contained in:
Warren
2026-07-01 18:12:57 +08:00
parent 4b6c89bee0
commit b102917644
5 changed files with 212 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
use crate::error::{FaxError, Result};
use crate::fax::class2::commands::{Class2Commands, DccParams, BR_V17_14400};
use crate::fax::encoder::MhEncoder;
use crate::modem::driver::ModemDriver;
use crate::document::convert::Page;
@@ -128,20 +129,13 @@ impl<'a> Class2Send<'a> {
return Err(FaxError::modem("FDT command failed"));
}
// Send T.4 MH encoded data
// For Class 2, we need to:
// 1. Send T.4 page data (with proper MH encoding)
// 2. End with DLE ETX (0x10 0x03)
// 3. Handle any DLE escapes in the data
// Encode pixel data to T.4 MH format
tracing::info!("Encoding {}x{} pixels to T.4 MH...", page.width_pels, page.rows);
let mh_data = MhEncoder::encode_page(page)?;
tracing::info!("Encoded to {} bytes", mh_data.len());
// TODO: The pixel data needs to be T.4 MH encoded first
// For now, send raw pixel data (this won't work properly!)
// We need to implement MH encoding
tracing::warn!("Sending raw pixel data (MH encoding not yet implemented)");
// Escape any DLE (0x10) bytes in the data by doubling them
let escaped_data = self.escape_dle(&page.pixels);
let escaped_data = self.escape_dle(&mh_data);
self.driver.write_raw(&escaped_data)?;
self.driver.write_raw(&DLE_ETX)?;