pub fn load_from_png(
		&mut self,
		png_data: Vec<u8>,
		palette: Option<&VeraPalette>,
		pane_start_x: u32,
		pane_start_y: u32,
		clear_index: u8,
	) -> Result<(), Error> {
		self.tiles = vec![];
		// load as we do for an imageset
		let mut frames = vec![];
		let (frames_per_row, frames_per_col) = png_to_frames(
			&self.id,
			self.tile_width.val_as_u32(),
			self.tile_height.val_as_u32(),
			png_data,
			&mut frames,
		)?;
		if frames_per_row > self.map_width.val_as_u32()
			|| frames_per_col > self.map_height.val_as_u32()
		{
			return Err(ErrorKind::TileMapImageWrongSize(
				self.map_width.val_as_u32() as usize,
				self.map_height.val_as_u32() as usize,
				frames_per_row as usize,
				frames_per_col as usize,
			)
			.into());
		}

		self.pane_width = Some(frames_per_row);
		self.pane_height = Some(frames_per_col);

		if pane_start_x + frames_per_row > self.map_width.val_as_u32()
			|| pane_start_y + frames_per_col > self.map_width.val_as_u32()
		{
			return Err(ErrorKind::TileMapInvalidPanePos(pane_start_x, pane_start_y).into());
		}

		self.pane_start_x = pane_start_x;
		self.pane_start_y = pane_start_y;

		for (i, mut f) in frames.iter_mut().enumerate() {
			if self.mode == VeraTileMapMode::TextBPP1_16
				|| self.mode == VeraTileMapMode::TextBPP1_256
			{
				f.depth = VeraPixelDepth::BPP1;
				for mut p in f.data.iter_mut() {
					// As with imagesets, remove colour data, just use
					// on/off
					p.is_1bpp = true;
					if p.r != 0 && p.g != 0 && p.b != 0 {
						p.is_on = true;
						// store first non-zero pixel as foreground colour
						if f.foreground == 0 {
							let res = palette.unwrap().index_of_rgb(p.r, p.g, p.b);
							let index = match res {
								Some(i) => i as u8,
								None => {
									return Err(ErrorKind::PaletteIndexMissing(
										p.r >> 4,
										p.g >> 4,
										p.b >> 4,
									)
									.into());
								}
							};
							if self.mode == VeraTileMapMode::TextBPP1_16 {
								// in this mode, foreground colour must be in first palette entries
								if index > 15 {
									return Err(ErrorKind::UnexpectedDepthError(format!(
										"Palette index {} in frame {} exceeds mode depth",
										index, f.id
									))
									.into());
								}
							}
							f.foreground = index;
						}
					} else {
						f.background = clear_index;
					}
				}
			} else {
				if palette.is_some() {
					warn!("Palette not required for this map mode, ignoring");
				}
			}
			let hash = f.calc_hash();
			match self.imageset_entries.get(&hash) {
				Some((index, pal_offset)) => {
					self.tiles.push(self.entry_from_image(
						*index as u16,
						*pal_offset,
						f.foreground,
						f.background,
					)?);
				}
				None => {
					let y = i / frames_per_row as usize;
					let x = i - frames_per_row as usize * y;
					return Err(ErrorKind::TileMapNoImageSetEntry(i, x, y).into());
				}
			}
		}
		Ok(())
	}
/// Load from a PNG on which the tilemap has been painted
/// must be same dimensions, contain tiles of same size and
/// palette, etc, etc
/// Palette for 1BPP modes only, to reconcile foreground colours
/// which will be the first non-zero colour in the tile (and must be in
/// the given palette)
/// clear index is the index that 0 (off) will be mapped to
Load from a PNG on which the tilemap has been painted
must be same dimensions, contain tiles of same size and
palette, etc, etc
Palette for 1BPP modes only, to reconcile foreground colours
which will be the first non-zero colour in the tile (and must be in
the given palette)
clear index is the index that 0 (off) will be mapped to
Load from a PNG on which the tilemap has been painted must be same dimensions contain tiles of same size and palette etc etc Palette for 1BPP modes only to reconcile foreground colours which will be the first non - zero colour in the tile ( and must be in the given palette ) clear index is the index that 0 ( off ) will be mapped to
pub fn load_from_png(
		&mut self,
		png_data: Vec<u8>,
		palette: Option<&VeraPalette>,
		pane_start_x: u32,
		pane_start_y: u32,
		clear_index: u8,
	) -> Result<(), Error> {
		self.tiles = vec![];
		// load as we do for an imageset
		let mut frames = vec![];
		let (frames_per_row, frames_per_col) = png_to_frames(
			&self.id,
			self.tile_width.val_as_u32(),
			self.tile_height.val_as_u32(),
			png_data,
			&mut frames,
		)?;
		if frames_per_row > self.map_width.val_as_u32()
			|| frames_per_col > self.map_height.val_as_u32()
		{
			return Err(ErrorKind::TileMapImageWrongSize(
				self.map_width.val_as_u32() as usize,
				self.map_height.val_as_u32() as usize,
				frames_per_row as usize,
				frames_per_col as usize,
			)
			.into());
		}
		self.pane_width = Some(frames_per_row);
		self.pane_height = Some(frames_per_col);
		if pane_start_x + frames_per_row > self.map_width.val_as_u32()
			|| pane_start_y + frames_per_col > self.map_width.val_as_u32()
		{
			return Err(ErrorKind::TileMapInvalidPanePos(pane_start_x, pane_start_y).into());
		}
		self.pane_start_x = pane_start_x;
		self.pane_start_y = pane_start_y;
		for (i, mut f) in frames.iter_mut().enumerate() {
			if self.mode == VeraTileMapMode::TextBPP1_16
				|| self.mode == VeraTileMapMode::TextBPP1_256
			{
				f.depth = VeraPixelDepth::BPP1;
				for mut p in f.data.iter_mut() {
					// As with imagesets, remove colour data, just use
					// on/off
					p.is_1bpp = true;
					if p.r != 0 && p.g != 0 && p.b != 0 {
						p.is_on = true;
						// store first non-zero pixel as foreground colour
						if f.foreground == 0 {
							let res = palette.unwrap().index_of_rgb(p.r, p.g, p.b);
							let index = match res {
								Some(i) => i as u8,
								None => {
									return Err(ErrorKind::PaletteIndexMissing(
										p.r >> 4,
										p.g >> 4,
										p.b >> 4,
									)
									.into());
								}
							};
							if self.mode == VeraTileMapMode::TextBPP1_16 {
								// in this mode, foreground colour must be in first palette entries
								if index > 15 {
									return Err(ErrorKind::UnexpectedDepthError(format!(
										"Palette index {} in frame {} exceeds mode depth",
										index, f.id
									))
									.into());
								}
							}
							f.foreground = index;
						}
					} else {
						f.background = clear_index;
					}
				}
			} else {
				if palette.is_some() {
					warn!("Palette not required for this map mode, ignoring");
				}
			}
			let hash = f.calc_hash();
			match self.imageset_entries.get(&hash) {
				Some((index, pal_offset)) => {
					self.tiles.push(self.entry_from_image(
						*index as u16,
						*pal_offset,
						f.foreground,
						f.background,
					)?);
				}
				None => {
					let y = i / frames_per_row as usize;
					let x = i - frames_per_row as usize * y;
					return Err(ErrorKind::TileMapNoImageSetEntry(i, x, y).into());
				}
			}
		}
		Ok(())
	}
pub fn load_from_png ( & mut self , png_data : Vec < u8 > , palette : Option < & VeraPalette > , pane_start_x : u32 , pane_start_y : u32 , clear_index : u8 , ) -> Result < ( ) , Error > { self . tiles = vec ! [ ] ; // load as we do for an imageset let mut frames = vec ! [ ] ; let ( frames_per_row , frames_per_col ) = png_to_frames ( & self . id , self . tile_width . val_as_u32 ( ) , self . tile_height . val_as_u32 ( ) , png_data , & mut frames , ) ? ; if frames_per_row > self . map_width . val_as_u32 ( ) || frames_per_col > self . map_height . val_as_u32 ( ) { return Err ( ErrorKind :: TileMapImageWrongSize ( self . map_width . val_as_u32 ( ) as usize , self . map_height . val_as_u32 ( ) as usize , frames_per_row as usize , frames_per_col as usize , ) . into ( ) ) ; } self . pane_width = Some ( frames_per_row ) ; self . pane_height = Some ( frames_per_col ) ; if pane_start_x + frames_per_row > self . map_width . val_as_u32 ( ) || pane_start_y + frames_per_col > self . map_width . val_as_u32 ( ) { return Err ( ErrorKind :: TileMapInvalidPanePos ( pane_start_x , pane_start_y ) . into ( ) ) ; } self . pane_start_x = pane_start_x ; self . pane_start_y = pane_start_y ; for ( i , mut f ) in frames . iter_mut ( ) . enumerate ( ) { if self . mode == VeraTileMapMode :: TextBPP1_16 || self . mode == VeraTileMapMode :: TextBPP1_256 { f . depth = VeraPixelDepth :: BPP1 ; for mut p in f . data . iter_mut ( ) { // As with imagesets, remove colour data, just use // on/off p . is_1bpp = true ; if p . r != 0 && p . g != 0 && p . b != 0 { p . is_on = true ; // store first non-zero pixel as foreground colour if f . foreground == 0 { let res = palette . unwrap ( ) . index_of_rgb ( p . r , p . g , p . b ) ; let index = match res { Some ( i ) => i as u8 , None => { return Err ( ErrorKind :: PaletteIndexMissing ( p . r >> 4 , p . g >> 4 , p . b >> 4 , ) . into ( ) ) ; } } ; if self . mode == VeraTileMapMode :: TextBPP1_16 { // in this mode, foreground colour must be in first palette entries if index > 15 { return Err ( ErrorKind :: UnexpectedDepthError ( format ! ( " " index f id ) ) . into ( ) ) ; } } f . foreground = index ; } } else { f . background = clear_index ; } } } else { if palette . is_some ( ) { warn ! ( " " ) ; } } let hash = f . calc_hash ( ) ; match self . imageset_entries . get ( & hash ) { Some ( ( index , pal_offset ) ) => { self . tiles . push ( self . entry_from_image ( * index as u16 , * pal_offset , f . foreground , f . background , ) ? ) ; } None => { let y = i / frames_per_row as usize ; let x = i - frames_per_row as usize * y ; return Err ( ErrorKind :: TileMapNoImageSetEntry ( i , x , y ) . into ( ) ) ; } } } Ok ( ( ) ) }
Load from a PNG on which the tilemap has been painted
must be same dimensions, contain tiles of same size and
palette, etc, etc
Palette for 1BPP modes only, to reconcile foreground colours
which will be the first non-zero colour in the tile (and must be in
the given palette)
clear index is the index that 0 (off) will be mapped to
Load from a PNG on which the tilemap has been painted must be same dimensions contain tiles of same size and palette etc etc Palette for 1BPP modes only to reconcile foreground colours which will be the first non - zero colour in the tile ( and must be in the given palette ) clear index is the index that 0 ( off ) will be mapped to
&mut self
png_data
Vec<u8>
palette
Option<&VeraPalette>
pane_start_x
u32
pane_start_y
u32
clear_index
u8