@@ -499,13 +499,14 @@ fn set_canvas_v1(state: &mut Box<State<'_>>, ptr: u32, len: u32, image_bytes: &[
499499}
500500
501501fn 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+
627682fn 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