diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/DCraw.cs b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/DCraw.cs new file mode 100644 index 0000000..a0e0bab --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/DCraw.cs @@ -0,0 +1,35 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Text; + +namespace QuickLook.Plugin.CameraRawViewer +{ + internal class DCraw + { + private static readonly string DCrawPath = + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Environment.Is64BitProcess ? "dcraw64.exe" : "dcraw32.exe"); + + public static string ConvertToTiff(string input) + { + var output = Path.GetTempFileName(); + + using (var p = new Process()) + { + p.StartInfo.UseShellExecute = false; + p.StartInfo.CreateNoWindow = true; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.FileName = DCrawPath; + p.StartInfo.Arguments = $"-w -W -h -T -O \"{output}\" \"{input}\""; + p.StartInfo.StandardOutputEncoding = Encoding.UTF8; + p.Start(); + + p.WaitForExit(10000); + } + + return new FileInfo(output).Length > 0 ? output : string.Empty; + } + } +} \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Plugin.cs new file mode 100644 index 0000000..8ea30ac --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Plugin.cs @@ -0,0 +1,85 @@ +// Copyright © 2017 Paddy Xu +// +// 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 System; +using System.IO; +using System.Linq; +using QuickLook.Common.Plugin; + +namespace QuickLook.Plugin.CameraRawViewer +{ + public class Plugin : IViewer + { + private static readonly string[] Formats = + { + // camera raw + ".ari", ".arw", ".bay", ".crw", ".cr2", ".cap", ".dcs", ".dcr", ".dng", ".drf", ".eip", ".erf", ".fff", + ".iiq", ".k25", ".kdc", ".mdc", ".mef", ".mos", ".mrw", ".nef", ".nrw", ".obm", ".orf", ".pef", ".ptx", + ".pxn", ".r3d", ".raf", ".raw", ".rwl", ".rw2", ".rwz", ".sr2", ".srf", ".srw", ".x3f" + }; + private string _image = string.Empty; + + private ImageViewer.Plugin _imageViewierPlugin; + + public int Priority => -1;//int.MaxValue; + + public void Init() + { + } + + public bool CanHandle(string path) + { + return false; + return !Directory.Exists(path) && Formats.Any(path.ToLower().EndsWith); + } + + public void Prepare(string path, ContextObject context) + { + _imageViewierPlugin=new ImageViewer.Plugin(); + + _imageViewierPlugin.Prepare(path, context); + } + + public void View(string path, ContextObject context) + { + _image = DCraw.ConvertToTiff(path); + + if (string.IsNullOrEmpty(_image)) + throw new Exception("DCraw failed."); + + _imageViewierPlugin.View(_image, context); + + // correct title + context.Title = Path.GetFileName(path); + } + + public void Cleanup() + { + _imageViewierPlugin.Cleanup(); + _imageViewierPlugin = null; + + try + { + File.Delete(_image); + } + catch (Exception) + { + // ignored + } + } + } +} \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Properties/AssemblyInfo.cs b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d4e401b --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/Properties/AssemblyInfo.cs @@ -0,0 +1,50 @@ +// Copyright © 2017 Paddy Xu +// +// 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 System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("QuickLook.Plugin.ImageViewer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("pooi.moe")] +[assembly: AssemblyProduct("QuickLook.Plugin.ImageViewer")] +[assembly: AssemblyCopyright("Copyright © Paddy Xu 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fe5a5111-9607-4721-a7be-422754002ed8")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/QuickLook.Plugin.CameraRawViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/QuickLook.Plugin.CameraRawViewer.csproj new file mode 100644 index 0000000..2211747 --- /dev/null +++ b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/QuickLook.Plugin.CameraRawViewer.csproj @@ -0,0 +1,98 @@ + + + + + Debug + AnyCPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA} + Library + Properties + QuickLook.Plugin.CameraRawViewer + QuickLook.Plugin.CameraRawViewer + v4.6.2 + 512 + + + + + + true + ..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.CameraRawViewer\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + ..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.CameraRawViewer\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + true + ..\..\Build\Debug\QuickLook.Plugin\QuickLook.Plugin.CameraRawViewer\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + ..\..\Build\Release\QuickLook.Plugin\QuickLook.Plugin.CameraRawViewer\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + false + + + + + + + + + + + + + + + + Properties\GitVersion.cs + + + + + + + + {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95} + QuickLook.Common + False + + + {fe5a5111-9607-4721-a7be-422754002ed8} + QuickLook.Plugin.ImageViewer + False + + + + + PreserveNewest + + + PreserveNewest + + + + \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw32.exe b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw32.exe new file mode 100644 index 0000000..bdca298 Binary files /dev/null and b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw32.exe differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw64.exe b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw64.exe new file mode 100644 index 0000000..060dc48 Binary files /dev/null and b/QuickLook.Plugin/QuickLook.Plugin.CameraRawViewer/dcraw64.exe differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimatedImage.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimatedImage.cs index e014ba8..1a14bdc 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimatedImage.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimatedImage.cs @@ -16,13 +16,11 @@ // along with this program. If not, see . using System; -using System.Diagnostics; using System.IO; -using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Media.Animation; +using System.Windows.Media; using System.Windows.Threading; using QuickLook.Common.Helpers; using QuickLook.Plugin.ImageViewer.Exiv2; @@ -31,15 +29,68 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage { public class AnimatedImage : Image, IDisposable { + private AnimationProvider _animation; + private bool _disposed; + + public void Dispose() + { + BeginAnimation(AnimationFrameIndexProperty, null); + Source = null; + _animation = null; + + _disposed = true; + + Task.Delay(500).ContinueWith(t => ProcessHelper.PerformAggressiveGC()); + } + + private static void LoadFullImage(DependencyObject obj, DependencyPropertyChangedEventArgs ev) + { + if (!(obj is AnimatedImage instance)) + return; + + instance._animation = LoadFullImageCore((Uri) ev.NewValue); + instance.BeginAnimation(AnimationFrameIndexProperty, instance._animation.Animator); + } + + private static AnimationProvider LoadFullImageCore(Uri path) + { + byte[] sign; + using (var reader = + new BinaryReader(new FileStream(path.LocalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) + { + sign = reader.BaseStream.Length < 4 ? new byte[] {0, 0, 0, 0} : reader.ReadBytes(4); + } + + AnimationProvider provider = null; + + if (sign[0] == 'G' && sign[1] == 'I' && sign[2] == 'F' && sign[3] == '8') + provider = new GIFAnimationProvider(path.LocalPath); + //else if (sign[0] == 0x89 && sign[1] == 'P' && sign[2] == 'N' && sign[3] == 'G') + // provider = new APNGAnimationProvider(); + //else + // provider = new ImageMagickProvider(); + + return provider; + } + + #region DependencyProperty + + public static readonly DependencyProperty AnimationFrameIndexProperty = + DependencyProperty.Register("AnimationFrameIndex", typeof(int), typeof(AnimatedImage), + new UIPropertyMetadata(-1, AnimationFrameIndexChanged)); + public static readonly DependencyProperty AnimationUriProperty = DependencyProperty.Register("AnimationUri", typeof(Uri), typeof(AnimatedImage), - new UIPropertyMetadata(null, LoadImage)); + new UIPropertyMetadata(null, AnimationUriChanged)); public static readonly DependencyProperty MetaProperty = DependencyProperty.Register("Meta", typeof(Meta), typeof(AnimatedImage)); - private ObjectAnimationUsingKeyFrames _animator = new ObjectAnimationUsingKeyFrames(); - private bool _disposed; + public int AnimationFrameIndex + { + get => (int) GetValue(AnimationFrameIndexProperty); + set => SetValue(AnimationFrameIndexProperty, value); + } public Uri AnimationUri { @@ -53,90 +104,33 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage set => SetValue(MetaProperty, value); } - public void Dispose() + private static void AnimationUriChanged(DependencyObject obj, DependencyPropertyChangedEventArgs ev) { - BeginAnimation(SourceProperty, null); - Source = null; - _animator.KeyFrames.Clear(); - - _disposed = true; - } - - private static void LoadImage(DependencyObject obj, DependencyPropertyChangedEventArgs ev) - { - var instance = obj as AnimatedImage; - if (instance == null) + if (!(obj is AnimatedImage instance)) return; - var thumbnail = instance.Meta?.GetThumbnail(true); - instance.Source = thumbnail; + //var thumbnail = instance.Meta?.GetThumbnail(true); + //instance.Source = thumbnail; - if (thumbnail != null) - LoadFullImageAsync(obj, ev); - else - LoadFullImage(obj, ev); + LoadFullImage(obj, ev); + + instance.AnimationFrameIndex = 0; } - private static void LoadFullImage(DependencyObject obj, DependencyPropertyChangedEventArgs ev) + private static void AnimationFrameIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs ev) { - var instance = obj as AnimatedImage; - if (instance == null) + if (!(obj is AnimatedImage instance)) return; - instance._animator = LoadFullImageCore((Uri) ev.NewValue); - instance.BeginAnimation(SourceProperty, instance._animator); - } - - private static void LoadFullImageAsync(DependencyObject obj, DependencyPropertyChangedEventArgs ev) - { - Task.Run(() => + new Task(() => { - var instance = obj as AnimatedImage; - if (instance == null) - return; + var image = instance._animation.GetRenderedFrame((int) ev.NewValue); - var animator = LoadFullImageCore((Uri) ev.NewValue); - - instance.Dispatcher.Invoke(DispatcherPriority.Render, - new Action(() => - { - if (instance._disposed) - { - ProcessHelper.PerformAggressiveGC(); - return; - } - - instance._animator = animator; - instance.BeginAnimation(SourceProperty, instance._animator); - - Debug.WriteLine($"LoadFullImageAsync {Thread.CurrentThread.ManagedThreadId}"); - })); - }); + instance.Dispatcher.BeginInvoke( + new Action(() => { instance.Source = image; }), DispatcherPriority.Loaded); + }).Start(); } - private static ObjectAnimationUsingKeyFrames LoadFullImageCore(Uri path) - { - byte[] sign; - using (var reader = - new BinaryReader(new FileStream(path.LocalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) - { - sign = reader.BaseStream.Length < 4 ? new byte[] {0, 0, 0, 0} : reader.ReadBytes(4); - } - - IAnimationProvider provider; - - if (sign[0] == 'G' && sign[1] == 'I' && sign[2] == 'F' && sign[3] == '8') - provider = new GIFAnimationProvider(); - else if (sign[0] == 0x89 && sign[1] == 'P' && sign[2] == 'N' && sign[3] == 'G') - provider = new APNGAnimationProvider(); - else - provider = new ImageMagickProvider(); - - var animator = new ObjectAnimationUsingKeyFrames(); - provider.GetAnimator(animator, path.LocalPath); - animator.Freeze(); - - return animator; - } + #endregion DependencyProperty } } \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/IAnimationProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimationProvider.cs similarity index 69% rename from QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/IAnimationProvider.cs rename to QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimationProvider.cs index a86f1cf..5b7514b 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/IAnimationProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/AnimationProvider.cs @@ -15,12 +15,23 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Windows.Media; using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; namespace QuickLook.Plugin.ImageViewer.AnimatedImage { - internal interface IAnimationProvider + internal abstract class AnimationProvider { - void GetAnimator(ObjectAnimationUsingKeyFrames animator, string path); + public AnimationProvider(string path) + { + Path = path; + } + + public string Path { get; } + + public Int32Animation Animator { get; protected set; } + + public abstract DrawingImage GetRenderedFrame(int index); } } \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/GIFAnimationProvider.cs b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/GIFAnimationProvider.cs index 2dc6651..3b10aa2 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/GIFAnimationProvider.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/AnimatedImage/GIFAnimationProvider.cs @@ -16,86 +16,91 @@ // along with this program. If not, see . using System; +using System.Collections.Generic; +using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; +using QuickLook.Common.ExtensionMethods; namespace QuickLook.Plugin.ImageViewer.AnimatedImage { - internal class GIFAnimationProvider : IAnimationProvider + internal class GIFAnimationProvider : AnimationProvider { - public void GetAnimator(ObjectAnimationUsingKeyFrames animator, string path) + private readonly List _decodedFrames; + private readonly int _lastRenderedFrameIndex; + private readonly DrawingGroup renderedFrame; + + public GIFAnimationProvider(string path) : base(path) { - var decoder = - new GifBitmapDecoder(new Uri(path), BitmapCreateOptions.PreservePixelFormat, - BitmapCacheOption.OnLoad); + var decoder = new GifBitmapDecoder(new Uri(path), BitmapCreateOptions.PreservePixelFormat, + BitmapCacheOption.OnLoad); - var clock = TimeSpan.Zero; - BitmapSource prevFrame = null; - FrameInfo prevInfo = null; - BitmapSource prevprevFrame = null; - foreach (var rawFrame in decoder.Frames) + _decodedFrames = new List(decoder.Frames.Count); + decoder.Frames.ForEach(f => _decodedFrames.Add(GetFrameInfo(f))); + + renderedFrame = new DrawingGroup(); + _lastRenderedFrameIndex = -1; + + var delay = _decodedFrames[0].Delay.TotalMilliseconds; + + Animator = new Int32Animation(0, decoder.Frames.Count - 1, + new Duration(TimeSpan.FromMilliseconds(delay * (decoder.Frames.Count - 1)))) { - var info = GetFrameInfo(rawFrame); - var frame = MakeFrame(decoder.Frames[0], rawFrame, info, prevFrame, prevInfo, prevprevFrame); - prevprevFrame = prevFrame; - prevFrame = frame; - prevInfo = info; + RepeatBehavior = RepeatBehavior.Forever + }; + } - animator.KeyFrames.Add(new DiscreteObjectKeyFrame(frame, clock)); - clock += info.Delay; - } + public override DrawingImage GetRenderedFrame(int index) + { + for (var i = _lastRenderedFrameIndex + 1; i < index; i++) + MakeFrame(renderedFrame, _decodedFrames[i], i > 0 ? _decodedFrames[i - 1] : null); - animator.Duration = clock; - animator.RepeatBehavior = RepeatBehavior.Forever; + MakeFrame( + renderedFrame, + _decodedFrames[index], + index > 0 ? _decodedFrames[index - 1] : null); + + var di=new DrawingImage(renderedFrame); + di.Freeze(); + + return di; } #region private methods - private static BitmapSource MakeFrame( - BitmapSource fullImage, - BitmapSource rawFrame, FrameInfo frameInfo, - BitmapSource previousFrame, FrameInfo previousFrameInfo, - BitmapSource previouspreviousFrame) + private static void MakeFrame( + DrawingGroup renderedFrame, + FrameInfo currentFrame, + FrameInfo previousFrame) { - var visual = new DrawingVisual(); - using (var context = visual.RenderOpen()) - { - if (previousFrameInfo != null && previousFrame != null) + if (previousFrame == null) + renderedFrame.Children.Clear(); + else + switch (previousFrame.DisposalMethod) { - var fullRect = new Rect(0, 0, fullImage.PixelWidth, fullImage.PixelHeight); - - switch (previousFrameInfo.DisposalMethod) - { - case FrameDisposalMethod.Unspecified: - case FrameDisposalMethod.Combine: - context.DrawImage(previousFrame, fullRect); - break; - case FrameDisposalMethod.RestorePrevious: - if (previouspreviousFrame != null) - context.DrawImage(previouspreviousFrame, fullRect); - break; - case FrameDisposalMethod.RestoreBackground: - break; - } + case FrameDisposalMethod.Unspecified: + case FrameDisposalMethod.Combine: + break; + case FrameDisposalMethod.RestorePrevious: + renderedFrame.Children.RemoveAt(renderedFrame.Children.Count - 1); + break; + case FrameDisposalMethod.RestoreBackground: + var bg = renderedFrame.Children.First(); + renderedFrame.Children.Clear(); + renderedFrame.Children.Add(bg); + break; } - context.DrawImage(rawFrame, frameInfo.Rect); - } - - var bitmap = new RenderTargetBitmap( - fullImage.PixelWidth, fullImage.PixelHeight, - Math.Floor(fullImage.DpiX), Math.Floor(fullImage.DpiY), - PixelFormats.Pbgra32); - bitmap.Render(visual); - return bitmap; + renderedFrame.Children.Add(new ImageDrawing(currentFrame.Frame, currentFrame.Rect)); } private static FrameInfo GetFrameInfo(BitmapFrame frame) { var frameInfo = new FrameInfo { + Frame = frame, Delay = TimeSpan.FromMilliseconds(100), DisposalMethod = FrameDisposalMethod.Unspecified, Width = frame.PixelWidth, @@ -153,14 +158,15 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage private class FrameInfo { - public TimeSpan Delay { get; set; } + public BitmapSource Frame { get; set; } public FrameDisposalMethod DisposalMethod { get; set; } + public TimeSpan Delay { get; set; } + public Rect Rect => new Rect(Left, Top, Width, Height); + public double Width { private get; set; } public double Height { private get; set; } public double Left { private get; set; } public double Top { private get; set; } - - public Rect Rect => new Rect(Left, Top, Width, Height); } private enum FrameDisposalMethod diff --git a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj index c15a20f..2f34f70 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj +++ b/QuickLook.Plugin/QuickLook.Plugin.ImageViewer/QuickLook.Plugin.ImageViewer.csproj @@ -78,10 +78,10 @@ Properties\GitVersion.cs - + - - + + diff --git a/QuickLook.sln b/QuickLook.sln index 6b3fd0c..1aad176 100644 --- a/QuickLook.sln +++ b/QuickLook.sln @@ -70,6 +70,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.MailViewer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Common", "QuickLook.Common\QuickLook.Common.csproj", "{85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickLook.Plugin.CameraRawViewer", "QuickLook.Plugin\QuickLook.Plugin.CameraRawViewer\QuickLook.Plugin.CameraRawViewer.csproj", "{BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -200,6 +202,14 @@ Global {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}.Release|Any CPU.Build.0 = Release|Any CPU {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}.Release|x86.ActiveCfg = Release|Any CPU {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95}.Release|x86.Build.0 = Release|Any CPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Debug|x86.ActiveCfg = Debug|x86 + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Debug|x86.Build.0 = Debug|x86 + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Release|Any CPU.Build.0 = Release|Any CPU + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Release|x86.ActiveCfg = Release|x86 + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -218,6 +228,7 @@ Global {2C58F9B2-D8FA-4586-942B-5170CECE5963} = {D18A23FF-76BD-43BD-AC32-786D166EBAC9} {863ECAAC-18D9-4256-A27D-0F308089FB47} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} {45E94893-3076-4A8E-8969-6955B6340739} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} + {BD58F3FC-7601-47BA-AAA1-D8A9D54A33DA} = {06EFDBE0-6408-4B37-BCF2-0CF9EBEA2E93} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D3761C32-8C5F-498A-892B-3B0882994B62}