implement image preview
This commit is contained in:
		@ -1,19 +1,23 @@
 | 
			
		||||
// TODO: remove on implementation
 | 
			
		||||
#![allow(unused_imports)]
 | 
			
		||||
#![allow(unused_variables)]
 | 
			
		||||
#![allow(dead_code)]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
use crate::model::*;
 | 
			
		||||
use ::image::*;
 | 
			
		||||
 | 
			
		||||
pub struct ConvertConfig {
 | 
			
		||||
    pub desired_size: (usize, usize),
 | 
			
		||||
}
 | 
			
		||||
// TODO: Deside on ::image::FilterType;
 | 
			
		||||
// TODO: Think about size; Hard Code??
 | 
			
		||||
 | 
			
		||||
pub fn generate_preview(
 | 
			
		||||
    input: &[u8],
 | 
			
		||||
    format: TextureFormat,
 | 
			
		||||
    config: &ConvertConfig,
 | 
			
		||||
) -> ::image::ImageResult<Vec<u8>> {
 | 
			
		||||
    unimplemented!()
 | 
			
		||||
const RESIZE: u32 = 256;
 | 
			
		||||
 | 
			
		||||
pub fn generate_preview(input: &[u8], format: TextureFormat) -> ImageResult<Vec<u8>> {
 | 
			
		||||
    // Yes, this guesses the format :D
 | 
			
		||||
    // Also the resize function takes a maximum size and preservs the ratio.
 | 
			
		||||
    let img =
 | 
			
		||||
        ::image::load_from_memory(input)?.resize(RESIZE, RESIZE, ::image::FilterType::Lanczos3);
 | 
			
		||||
 | 
			
		||||
    let mut out: Vec<u8> = Vec::new();
 | 
			
		||||
 | 
			
		||||
    match format {
 | 
			
		||||
        TextureFormat::JPEG => img.write_to(&mut out, ImageOutputFormat::JPEG(95))?,
 | 
			
		||||
        TextureFormat::PNG => img.write_to(&mut out, ImageOutputFormat::PNG)?,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(out)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ use std::path::{Path, PathBuf};
 | 
			
		||||
mod image_convert;
 | 
			
		||||
mod metadata_file;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
pub type TextureFileResult = Result<Vec<u8>, TextureFileError>;
 | 
			
		||||
pub enum TextureFileError {
 | 
			
		||||
    NotFound,
 | 
			
		||||
@ -25,6 +26,7 @@ impl From<::image::ImageError> for TextureFileError {
 | 
			
		||||
        TextureFileError::ImageError(err)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
pub struct DataStore {
 | 
			
		||||
    //data_path: PathBuf,
 | 
			
		||||
@ -35,7 +37,7 @@ pub struct DataStore {
 | 
			
		||||
    id_index: HashMap<String, Texture>,
 | 
			
		||||
    name_index: HashMap<String, Texture>,
 | 
			
		||||
 | 
			
		||||
    _preview_cache: HashMap<(TextureFormat, Sha256), Vec<u8>>,
 | 
			
		||||
    preview_cache: HashMap<(TextureFormat, Sha256), Vec<u8>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl DataStore {
 | 
			
		||||
@ -65,7 +67,7 @@ impl DataStore {
 | 
			
		||||
            id_index: Default::default(),
 | 
			
		||||
            name_index: Default::default(),
 | 
			
		||||
 | 
			
		||||
            _preview_cache: Default::default(),
 | 
			
		||||
            preview_cache: Default::default(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let metadata_file = metadata_file::MetadataFile::load(&store.index_file_path())?;
 | 
			
		||||
@ -172,10 +174,25 @@ impl DataStore {
 | 
			
		||||
 | 
			
		||||
    pub fn get_texture_preview(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        _hash: &Sha256,
 | 
			
		||||
        _desired_format: TextureFormat,
 | 
			
		||||
    ) -> TextureFileResult {
 | 
			
		||||
        unimplemented!();
 | 
			
		||||
        hash: &Sha256,
 | 
			
		||||
        desired_format: TextureFormat,
 | 
			
		||||
    ) -> io::Result<Vec<u8>> {
 | 
			
		||||
        let key = (desired_format.clone(), hash.clone());
 | 
			
		||||
 | 
			
		||||
        if let Some(preview) = self.preview_cache.get(&key) {
 | 
			
		||||
            return Ok(preview.clone());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let original = self.read_texture_file_by_hash(&hash)?;
 | 
			
		||||
 | 
			
		||||
        let preview =
 | 
			
		||||
            image_convert::generate_preview(&original[..], desired_format).map_err(|_e| {
 | 
			
		||||
                io::Error::new(io::ErrorKind::InvalidData, "Invalid Texture Image on Disk.")
 | 
			
		||||
            })?;
 | 
			
		||||
 | 
			
		||||
        self.preview_cache.insert(key, preview.clone());
 | 
			
		||||
 | 
			
		||||
        Ok(preview)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn borrow_textures(&self) -> impl Iterator<Item = &Texture> {
 | 
			
		||||
 | 
			
		||||
@ -56,16 +56,9 @@ impl ProtocolHandler for ServerState {
 | 
			
		||||
    ) -> ProtocolResult<Vec<u8>> {
 | 
			
		||||
        let mut data_store = self.data_store.write().unwrap();
 | 
			
		||||
 | 
			
		||||
        match data_store.get_texture_preview(&hash, format) {
 | 
			
		||||
            Ok(data) => Ok(data),
 | 
			
		||||
            Err(TextureFileError::NotFound) => Err(ProtocolError::FileNotFound(
 | 
			
		||||
                "Texture not found!".to_string(),
 | 
			
		||||
            )),
 | 
			
		||||
            Err(TextureFileError::ImageError(_)) => Err(ProtocolError::FileNotFound(
 | 
			
		||||
                "Didn't Find valid Texture File".to_string(),
 | 
			
		||||
            )),
 | 
			
		||||
            Err(TextureFileError::IoError(err)) => Err(ProtocolError::InternalServerError(err)),
 | 
			
		||||
        }
 | 
			
		||||
        let preview = data_store.get_texture_preview(&hash, format)?;
 | 
			
		||||
 | 
			
		||||
        Ok(preview)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn replace_texture(
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user