]> git.seodisparate.com - mpd_info_screen/commitdiff
Try second albumart fetching method on decode fail
authorStephen Seo <seo.disparate@gmail.com>
Wed, 12 Jan 2022 11:25:26 +0000 (20:25 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 12 Jan 2022 11:25:26 +0000 (20:25 +0900)
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.

src/display.rs
src/mpd_handler.rs

index c611017ff3d4ba500c5b650fb03cb40457e5a2ed..9e503d4268efe8b8692ec3a0613942fc3b6e89cf 100644 (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 {
index f35588a0fd21594617bc0d221d02b224c79cd0f0..57f19d7b9745287731fbe66567a9ff55f6c31f29 100644 (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
     }