Skip to content

Commit b0d3b3c

Browse files
committed
image v2 support
1 parent 63288e4 commit b0d3b3c

1 file changed

Lines changed: 59 additions & 4 deletions

File tree

src/host/graphics.rs

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,14 @@ fn set_canvas_v1(state: &mut Box<State<'_>>, ptr: u32, len: u32, image_bytes: &[
499499
}
500500

501501
fn set_canvas_v2(state: &mut Box<State<'_>>, ptr: u32, len: u32, image_bytes: &[u8]) {
502+
const HEADER: u32 = 4;
502503
let width = u16::from_le_bytes([image_bytes[1], image_bytes[2]]) as u32;
503-
let image_bytes = &image_bytes[3..];
504+
let image_bytes = &image_bytes[HEADER as usize..];
504505
if !(image_bytes.len() * 2).is_multiple_of(width as usize) {
505506
state.log_error(HostError::InvalidWidth);
506507
return;
507508
}
508-
let canvas = Canvas::new(ptr + 3, len - 3, width);
509+
let canvas = Canvas::new(ptr + HEADER, len - HEADER, width);
509510
state.canvas = Some(canvas)
510511
}
511512

@@ -555,7 +556,7 @@ fn draw_image_inner(mut caller: C, ptr: u32, len: u32, x: i32, y: i32, sub: Opti
555556
state.log_error(HostError::OomPointer);
556557
return;
557558
};
558-
if image_bytes.len() < 7 {
559+
if image_bytes.len() < 4 {
559560
let msg = if ptr == 0 {
560561
"image is a nil pointer: make sure you've loaded it"
561562
} else if image_bytes.is_empty() {
@@ -566,7 +567,24 @@ fn draw_image_inner(mut caller: C, ptr: u32, len: u32, x: i32, y: i32, sub: Opti
566567
state.log_error(msg);
567568
return;
568569
}
570+
match image_bytes[0] {
571+
0x21 => draw_image_v1(state, image_bytes, x, y, sub),
572+
0x22 => draw_image_v2(state, image_bytes, x, y, sub),
573+
_ => state.log_error("invalid magic number"),
574+
}
575+
}
569576

577+
fn draw_image_v1(
578+
state: &mut Box<State<'_>>,
579+
image_bytes: &[u8],
580+
x: i32,
581+
y: i32,
582+
sub: Option<Rectangle>,
583+
) {
584+
if image_bytes.len() < 7 {
585+
state.log_error("image file is too small");
586+
return;
587+
}
570588
// Read image header.
571589
// Bits per color pixel. Can be 1, 2, or 4.
572590
let bpp = u8::from_le_bytes([image_bytes[1]]);
@@ -601,7 +619,7 @@ fn draw_image_inner(mut caller: C, ptr: u32, len: u32, x: i32, y: i32, sub: Opti
601619
2 => 4,
602620
_ => 2,
603621
};
604-
if image_bytes.len() * ppb % width as usize != 0 {
622+
if !(image_bytes.len() * ppb).is_multiple_of(width as usize) {
605623
state.log_error(HostError::InvalidWidth);
606624
return;
607625
}
@@ -624,6 +642,43 @@ fn draw_image_inner(mut caller: C, ptr: u32, len: u32, x: i32, y: i32, sub: Opti
624642
image.render(point, &mut state.frame);
625643
}
626644

645+
fn draw_image_v2(
646+
state: &mut Box<State<'_>>,
647+
image_bytes: &[u8],
648+
x: i32,
649+
y: i32,
650+
sub: Option<Rectangle>,
651+
) {
652+
let width = u16::from_le_bytes([image_bytes[1], image_bytes[2]]) as u32;
653+
if width == 0 {
654+
state.log_error("image has zero width");
655+
return;
656+
}
657+
let transp = u8::from_le_bytes([image_bytes[3]]);
658+
let image_bytes = &image_bytes[4..];
659+
if !(image_bytes.len() * 2).is_multiple_of(width as usize) {
660+
state.log_error(HostError::InvalidWidth);
661+
return;
662+
}
663+
664+
// TODO: support canvas
665+
if state.canvas.is_some() {
666+
state.log_error("images cannot be drawn on canvas yet");
667+
return;
668+
}
669+
670+
let point = Point::new(x, y);
671+
let image = ParsedImage {
672+
bpp: 4,
673+
bytes: image_bytes,
674+
width,
675+
swaps: &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef],
676+
transp,
677+
sub,
678+
};
679+
image.render(point, &mut state.frame);
680+
}
681+
627682
fn get_shape_style(fill_color: u32, stroke_color: u32, stroke_width: u32) -> PrimitiveStyle<Gray4> {
628683
let mut style = PrimitiveStyle::new();
629684
if fill_color != 0 {

0 commit comments

Comments
 (0)