Skip to content

Commit

Permalink
🔧(icu_lib): Refactor RLE encoding and update LVGL handling
Browse files Browse the repository at this point in the history
Refactored the RLE encoding logic in `rle.rs` to improve clarity and efficiency. Updated the `lvgl.rs` module to support compression methods, including RLE, and adjusted the `Flags` enum to `HeaderFlag` for better flag management.

Signed-off-by: Benign X <1341398182@qq.com>
  • Loading branch information
W-Mai committed Nov 26, 2024
1 parent 5dd7270 commit 2969fa9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
38 changes: 34 additions & 4 deletions icu_lib/src/endecoder/lvgl/lvgl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::endecoder::lvgl::color_converter::{rgba8888_from, rgba8888_to};
use crate::endecoder::lvgl::{
Flags, ImageCompressedHeader, ImageDescriptor, ImageHeader, LVGLVersion, LVGL,
has_flag, with_flag, Compress, Flags, HeaderFlag, ImageCompressedHeader, ImageDescriptor,
ImageHeader, LVGLVersion, LVGL,
};
use crate::endecoder::{EnDecoder, ImageInfo};
use crate::midata::MiData;
Expand Down Expand Up @@ -36,7 +37,7 @@ impl EnDecoder for LVGL {
imageops::dither(&mut img_data, &cmap);
}

let img_data = rgba8888_to(
let mut img_data = rgba8888_to(
img_data.as_mut(),
color_format,
img.width(),
Expand All @@ -45,13 +46,42 @@ impl EnDecoder for LVGL {
encoder_params.dither,
);

let mut flags = Flags::from(0u16);

match encoder_params.compress {
Compress::NONE => {}
Compress::RLE => {
use super::super::utils::rle::RleCoder;
let blk_size = ((color_format.get_bpp() + 7) >> 3) as usize;
let rle_coder = RleCoder::new(blk_size).unwrap();
let mut data = match rle_coder.encode(&img_data) {
Ok(data) => data,
Err(err) => {
log::error!("RLE encoding failed: {:?}", err);
return vec![];
}
};

let image_compressed_header = ImageCompressedHeader::new()
.with_method(encoder_params.compress)
.with_compressed_size(data.len() as u32)
.with_decompressed_size(img_data.len() as u32);
let mut ich_vec = image_compressed_header.into_bytes().to_vec();
ich_vec.append(&mut data);

img_data = ich_vec;
flags = with_flag(flags, HeaderFlag::COMPRESSED);
}
_ => {}
}

let mut buf = Cursor::new(Vec::new());
buf.write_all(
&ImageDescriptor::new(
ImageHeader::new(
encoder_params.lvgl_version,
color_format,
Flags::NONE,
flags,
img.width() as u16,
img.height() as u16,
stride as u16,
Expand Down Expand Up @@ -129,7 +159,7 @@ impl EnDecoder for LVGL {
}

// Deal Flag has Compressed
if header.flags().has_flag(Flags::COMPRESSED) {
if has_flag(header.flags(), HeaderFlag::COMPRESSED) {
let data = &data[header.header_size()..];
let compressed_header = ImageCompressedHeader::from_bytes([
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8],
Expand Down
29 changes: 18 additions & 11 deletions icu_lib/src/endecoder/lvgl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub struct LVGL {}
#[bits = 16]
#[derive(Copy, Clone, Debug)]
#[repr(u16)]
pub enum Flags {
pub enum HeaderFlag {
NONE = 0,
PREMULTIPLIED = 1 << 0,
MODIFIABLE = 1 << 1,
Expand All @@ -75,6 +75,8 @@ pub enum Flags {
USER8 = 0x0800,
}

type Flags = u16;

#[derive(BitfieldSpecifier)]
#[bits = 4]
#[derive(Copy, Clone, PartialEq, Debug, Default)]
Expand Down Expand Up @@ -137,10 +139,12 @@ pub enum ImageHeader {
V9(ImageHeaderV9),
}

impl Flags {
pub fn has_flag(&self, flag: Flags) -> bool {
*self as u8 & flag as u8 != 0
}
pub fn has_flag(flags: Flags, flag: HeaderFlag) -> bool {
flags & flag as u16 != 0
}

pub fn with_flag(flags: Flags, flag: HeaderFlag) -> Flags {
flags | flag as u16
}

impl ImageHeader {
Expand Down Expand Up @@ -207,8 +211,8 @@ impl ImageHeader {

pub fn flags(&self) -> Flags {
match self {
ImageHeader::Unknown => Flags::NONE,
ImageHeader::V8(_) => Flags::NONE,
ImageHeader::Unknown => 0,
ImageHeader::V8(_) => 0,
ImageHeader::V9(header) => header.flags(),
}
}
Expand Down Expand Up @@ -329,7 +333,7 @@ impl ImageDescriptor {
_ => 0,
};

if header.flags().has_flag(Flags::COMPRESSED) {
if has_flag(header.flags(), HeaderFlag::COMPRESSED) {
log::trace!("Dealing Compressed image");
let compressed_header = ImageCompressedHeader::from_bytes([
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
Expand All @@ -338,11 +342,14 @@ impl ImageDescriptor {
let method = compressed_header.method();
match method {
Compress::RLE => {
let blk_size = ((header.cf().get_bpp() + 7) >> 3) as usize;
use super::utils::rle::RleCoder;
let rle_coder = RleCoder::new(1).unwrap();
if compressed_header.decompressed_size() != data_size {
let rle_coder = RleCoder::new(blk_size).unwrap();
if compressed_header.compressed_size() != data_size - 12 {
log::error!(
"Compressed data size mismatch, but still try to decode"
"Compressed data size mismatch, but still try to decode. current: {} expected {}",
compressed_header.compressed_size(),
data_size
);
}
let decoded = rle_coder
Expand Down
15 changes: 6 additions & 9 deletions icu_lib/src/endecoder/utils/rle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,18 @@ impl RleCoder {
.count()
.min(127);

if repeat_count > 1 {
if repeat_count == 0 {
break;
}

if repeat_count >= 16 {
// Run-length mode
result.push(repeat_count as u8);
result.extend_from_slice(block);
i += repeat_count;
} else {
// Direct copy mode
let literal_end = blocks[i..]
.iter()
.take(127)
.take_while(|&&x| {
let next_pos = i + 1;
next_pos >= blocks.len() || x != blocks[next_pos]
})
.count();
let literal_end = blocks[i..].iter().take(127).count();

result.push(0x80 | (literal_end as u8));
blocks[i..i + literal_end]
Expand Down

0 comments on commit 2969fa9

Please sign in to comment.