// Copyright © 2017-2025 QL-Win Contributors
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
using QuickLook.Common.ExtensionMethods;
using QuickLook.Plugin.VideoViewer.Extensions;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
namespace QuickLook.Plugin.VideoViewer.AudioTrack;
internal static class CoverDataExtractor
{
///
/// Extracts cover image data from a Base64 string.
///
/// A Base64-encoded string (may contain multiple covers separated by " / ").
/// Byte array of the cover image, or null if extraction fails.
public static byte[] Extract(string base64strings)
{
try
{
var coverData = base64strings.Trim();
if (!string.IsNullOrEmpty(coverData))
{
// MediaInfo may return multiple covers in one string.
// In that case, only take the first one.
var coverBytes = Convert.FromBase64String
(
coverData.Contains(' ')
? coverData.Split(" / ")[0]
: coverData
);
return coverBytes;
}
}
catch (Exception e)
{
Debug.WriteLine(e);
}
return null;
}
///
/// Extracts a from cover image bytes.
///
/// Cover image as a byte array.
/// if successful; otherwise, null.
public static BitmapSource Extract(byte[] coverBytes)
{
// Supported formats: JPEG, PNG, BMP, GIF (first frame only), TIFF (first page only), ICO.
// Not supported: WebP, HEIC/HEIF, AVIF, JPEG 2000, animated WebP/APNG, and other raw image formats (e.g., CR2, NEF).
using var ms = new MemoryStream(coverBytes);
try
{
// First try decoding with WPF's built-in decoder.
var coverArt = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
return coverArt;
}
catch
{
// Fallback:
// https://github.com/QL-Win/QuickLook/issues/1759
// Use System.Drawing's Bitmap decoder, which is more forgiving with common JPEG files
// and tends not to throw WINCODEC_ERR_STREAMREAD like WPF often does.
try
{
using var bmp = new Bitmap(ms);
var coverArt = bmp.ToBitmapSource();
return coverArt;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
return null;
}
}