diff --git a/src/Commands/QueryFileContent.cs b/src/Commands/QueryFileContent.cs
index f887859c..83d0a575 100644
--- a/src/Commands/QueryFileContent.cs
+++ b/src/Commands/QueryFileContent.cs
@@ -35,5 +35,39 @@ namespace SourceGit.Commands
return stream;
}
+
+ public static Stream FromLFS(string repo, string oid, long size)
+ {
+ var starter = new ProcessStartInfo();
+ starter.WorkingDirectory = repo;
+ starter.FileName = Native.OS.GitExecutable;
+ starter.Arguments = $"lfs smudge";
+ starter.UseShellExecute = false;
+ starter.CreateNoWindow = true;
+ starter.WindowStyle = ProcessWindowStyle.Hidden;
+ starter.RedirectStandardInput = true;
+ starter.RedirectStandardOutput = true;
+
+ var stream = new MemoryStream();
+ try
+ {
+ var proc = new Process() { StartInfo = starter };
+ proc.Start();
+ proc.StandardInput.WriteLine("version https://git-lfs.github.com/spec/v1");
+ proc.StandardInput.WriteLine($"oid sha256:{oid}");
+ proc.StandardInput.WriteLine($"size {size}");
+ proc.StandardOutput.BaseStream.CopyTo(stream);
+ proc.WaitForExit();
+ proc.Close();
+
+ stream.Position = 0;
+ }
+ catch (Exception e)
+ {
+ App.RaiseException(repo, $"Failed to query file content: {e}");
+ }
+
+ return stream;
+ }
}
}
diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs
index ce13e655..af089635 100644
--- a/src/ViewModels/DiffContext.cs
+++ b/src/ViewModels/DiffContext.cs
@@ -207,7 +207,10 @@ namespace SourceGit.ViewModels
}
else if (latest.IsLFS)
{
- rs = latest.LFSDiff;
+ if (IMG_EXTS.Contains(Path.GetExtension(_option.Path) ?? ".invalid"))
+ rs = new LFSImageDiff(_repo, latest.LFSDiff);
+ else
+ rs = latest.LFSDiff;
}
else
{
diff --git a/src/ViewModels/LFSImageDiff.cs b/src/ViewModels/LFSImageDiff.cs
new file mode 100644
index 00000000..655004a6
--- /dev/null
+++ b/src/ViewModels/LFSImageDiff.cs
@@ -0,0 +1,49 @@
+using System.Threading.Tasks;
+
+using Avalonia.Media.Imaging;
+using Avalonia.Threading;
+
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace SourceGit.ViewModels
+{
+ public class LFSImageDiff : ObservableObject
+ {
+ public Models.LFSDiff LFS
+ {
+ get;
+ }
+
+ public Models.ImageDiff Image
+ {
+ get => _image;
+ private set => SetProperty(ref _image, value);
+ }
+
+ public LFSImageDiff(string repo, Models.LFSDiff lfs)
+ {
+ LFS = lfs;
+
+ Task.Run(() =>
+ {
+ var img = new Models.ImageDiff();
+ (img.Old, img.OldFileSize) = BitmapFromLFSObject(repo, lfs.Old);
+ (img.New, img.NewFileSize) = BitmapFromLFSObject(repo, lfs.New);
+
+ Dispatcher.UIThread.Invoke(() => Image = img);
+ });
+ }
+
+ private (Bitmap, long) BitmapFromLFSObject(string repo, Models.LFSObject lfs)
+ {
+ if (string.IsNullOrEmpty(lfs.Oid) || lfs.Size == 0)
+ return (null, 0);
+
+ var stream = Commands.QueryFileContent.FromLFS(repo, lfs.Oid, lfs.Size);
+ var size = stream.Length;
+ return size > 0 ? (new Bitmap(stream), size) : (null, size);
+ }
+
+ private Models.ImageDiff _image;
+ }
+}
diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml
index 559ad14d..50a3de62 100644
--- a/src/Views/DiffView.axaml
+++ b/src/Views/DiffView.axaml
@@ -224,29 +224,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -302,6 +280,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/LFSDiffView.axaml.cs b/src/Views/LFSDiffView.axaml.cs
new file mode 100644
index 00000000..a16a6fd3
--- /dev/null
+++ b/src/Views/LFSDiffView.axaml.cs
@@ -0,0 +1,12 @@
+using Avalonia.Controls;
+
+namespace SourceGit.Views
+{
+ public partial class LFSDiffView : UserControl
+ {
+ public LFSDiffView()
+ {
+ InitializeComponent();
+ }
+ }
+}