Try second albumart fetching method on decode fail

If the "image" crate fails to decode the album art from the first album-art
fetching method, fallback to the second fetching method to try decoding the
other image.
This commit is contained in:
Stephen Seo 2022-01-12 20:25:26 +09:00
parent 0888ec3ff9
commit 2b90aed487
2 changed files with 59 additions and 9 deletions

View file

@ -1,5 +1,5 @@
use crate::debug_log::{self, log};
use crate::mpd_handler::{InfoFromShared, MPDHandler};
use crate::mpd_handler::{InfoFromShared, MPDHandler, MPDHandlerState};
use crate::Opt;
use ggez::event::{self, EventHandler};
use ggez::graphics::{
@ -10,7 +10,7 @@ use ggez::{timer, Context, GameError, GameResult};
use image::io::Reader as ImageReader;
use std::io::Cursor;
use std::sync::atomic::AtomicBool;
use std::sync::{atomic::Ordering, Arc};
use std::sync::{atomic::Ordering, Arc, RwLockReadGuard};
use std::thread;
use std::time::{Duration, Instant};
@ -76,6 +76,7 @@ pub struct MPDDisplay {
length: f64,
text_bg_mesh: Option<Mesh>,
hide_text: bool,
tried_album_art_in_dir: bool,
}
impl MPDDisplay {
@ -107,6 +108,7 @@ impl MPDDisplay {
length: 0.0,
text_bg_mesh: None,
hide_text: false,
tried_album_art_in_dir: false,
}
}
@ -191,24 +193,53 @@ impl MPDDisplay {
}
fn get_image_from_data(&mut self, ctx: &mut Context) -> Result<(), String> {
let read_guard = self
let mut read_guard_opt: Option<RwLockReadGuard<'_, MPDHandlerState>> = self
.mpd_handler
.as_ref()
.unwrap()
.get_state_read_guard()
.map_err(|_| String::from("Failed to get read_guard of MPDHandlerState"))?;
if !read_guard.is_art_data_ready() {
.ok();
if read_guard_opt.is_none() {
return Err(String::from("Failed to get read_guard of MPDHandlerState"));
} else if !read_guard_opt.as_ref().unwrap().is_art_data_ready() {
return Err(String::from("MPDHandlerState does not have album art data"));
}
let image_ref = read_guard.get_art_data();
let image_ref = read_guard_opt.as_ref().unwrap().get_art_data();
let mut image_format: image::ImageFormat = image::ImageFormat::Png;
match read_guard.get_art_type().as_str() {
log(
format!(
"Got image_format type {}",
read_guard_opt.as_ref().unwrap().get_art_type()
),
debug_log::LogState::DEBUG,
self.opts.log_level,
);
let mut is_unknown_format: bool = false;
match read_guard_opt.as_ref().unwrap().get_art_type().as_str() {
"image/png" => image_format = image::ImageFormat::Png,
"image/jpg" | "image/jpeg" => image_format = image::ImageFormat::Jpeg,
"image/gif" => image_format = image::ImageFormat::Gif,
_ => (),
_ => is_unknown_format = true,
}
#[allow(unused_assignments)]
if is_unknown_format && !self.tried_album_art_in_dir {
self.tried_album_art_in_dir = true;
self.album_art = None;
// Drop the "read_guard" so that the "force_try_other_album_art()"
// can get a "write_guard"
read_guard_opt = None;
self.mpd_handler
.as_ref()
.unwrap()
.force_try_other_album_art()
.map_err(|_| String::from("Failed to force try other album art fetching method"))?;
return Err("Got unknown format album art image".into());
}
let img = ImageReader::with_format(Cursor::new(&image_ref), image_format)
.decode()
.map_err(|e| format!("ERROR: Failed to decode album art image: {}", e))?;
@ -544,6 +575,7 @@ impl EventHandler for MPDDisplay {
if !shared.filename.is_empty() {
if self.filename_text.contents() != shared.filename {
self.album_art = None;
self.tried_album_art_in_dir = false;
}
self.filename_text = Text::new(shared.filename.clone());
} else {
@ -565,7 +597,7 @@ impl EventHandler for MPDDisplay {
if self.album_art.is_none() {
let result = self.get_image_from_data(ctx);
if let Err(e) = result {
log(e, debug_log::LogState::DEBUG, self.opts.log_level);
log(e, debug_log::LogState::WARNING, self.opts.log_level);
self.album_art = None;
self.album_art_draw_transform = None;
} else {

View file

@ -353,6 +353,15 @@ impl MPDHandler {
Ok(())
}
pub fn force_try_other_album_art(&self) -> Result<(), ()> {
let mut write_handle = self.state.try_write().map_err(|_| ())?;
write_handle.art_data.clear();
write_handle.art_data_size = 0;
write_handle.can_get_album_art = false;
write_handle.can_get_album_art_in_dir = true;
Ok(())
}
fn handler_loop(self) -> Result<(), String> {
let log_level = self
.state
@ -808,6 +817,15 @@ impl MPDHandlerState {
}
pub fn is_art_data_ready(&self) -> bool {
log(
format!(
"is_art_data_ready(): art_data_size == {}, art_data.len() == {}",
self.art_data_size,
self.art_data.len()
),
LogState::DEBUG,
self.log_level,
);
self.art_data_size != 0 && self.art_data.len() == self.art_data_size
}