wip
This commit is contained in:
parent
3cd16ac714
commit
e06aede5cd
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
8
src/CamBooth/CamBooth.App/App.xaml
Normal file
8
src/CamBooth/CamBooth.App/App.xaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<Application x:Class="CamBooth.App.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="clr-namespace:CamBooth.App">
|
||||||
|
<Application.Resources>
|
||||||
|
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
||||||
39
src/CamBooth/CamBooth.App/App.xaml.cs
Normal file
39
src/CamBooth/CamBooth.App/App.xaml.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System.Configuration;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
using CamBooth.App.Core.Logging;
|
||||||
|
using CamBooth.App.LiveView;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace CamBooth.App;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
private IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnStartup(e);
|
||||||
|
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
ConfigureServices(services);
|
||||||
|
|
||||||
|
_serviceProvider = services.BuildServiceProvider();
|
||||||
|
|
||||||
|
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
|
||||||
|
mainWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
// Register your services and view models here
|
||||||
|
services.AddTransient<MainWindow>();
|
||||||
|
services.AddTransient<LiveViewPage>();
|
||||||
|
services.AddSingleton<Logger>();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/CamBooth/CamBooth.App/AssemblyInfo.cs
Normal file
10
src/CamBooth/CamBooth.App/AssemblyInfo.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
[assembly: ThemeInfo(
|
||||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// or application resource dictionaries)
|
||||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// app, or any theme specific resource dictionaries)
|
||||||
|
)]
|
||||||
32
src/CamBooth/CamBooth.App/CamBooth.App.csproj
Normal file
32
src/CamBooth/CamBooth.App/CamBooth.App.csproj
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\EDSDKLib\EDSDKLib.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Core\Models\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
9
src/CamBooth/CamBooth.App/Core/Logging/Logger.cs
Normal file
9
src/CamBooth/CamBooth.App/Core/Logging/Logger.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace CamBooth.App.Core.Logging;
|
||||||
|
|
||||||
|
public class Logger
|
||||||
|
{
|
||||||
|
public void LogInfo(string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/CamBooth/CamBooth.App/DebugConsole/DebugConsolePage.xaml
Normal file
12
src/CamBooth/CamBooth.App/DebugConsole/DebugConsolePage.xaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<Page x:Class="CamBooth.App.DebugConsole.DebugConsolePage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:CamBooth.App.DebugConsole"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="DebugConsolePage" Height="100" Width="800">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock>Debug Console</TextBlock>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace CamBooth.App.DebugConsole;
|
||||||
|
|
||||||
|
public partial class DebugConsolePage : Page
|
||||||
|
{
|
||||||
|
public DebugConsolePage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml
Normal file
14
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Page x:Class="CamBooth.App.LiveView.LiveViewPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:CamBooth.App.LiveView"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="LiveViewPage" Height="550" Width="780"
|
||||||
|
Background="PaleVioletRed">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock>LiveView CamBooth</TextBlock>
|
||||||
|
<Canvas x:Name="LVCanvas" Background="LightGray" />
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
231
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml.cs
Normal file
231
src/CamBooth/CamBooth.App/LiveView/LiveViewPage.xaml.cs
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
using EOSDigital.API;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
|
||||||
|
namespace CamBooth.App.LiveView;
|
||||||
|
|
||||||
|
public partial class LiveViewPage : Page
|
||||||
|
{
|
||||||
|
CanonAPI APIHandler;
|
||||||
|
|
||||||
|
Camera MainCamera;
|
||||||
|
|
||||||
|
CameraValue[] AvList;
|
||||||
|
|
||||||
|
CameraValue[] TvList;
|
||||||
|
|
||||||
|
CameraValue[] ISOList;
|
||||||
|
|
||||||
|
List<Camera> CamList;
|
||||||
|
|
||||||
|
bool IsInit = false;
|
||||||
|
|
||||||
|
int BulbTime = 30;
|
||||||
|
|
||||||
|
ImageBrush bgbrush = new ImageBrush();
|
||||||
|
|
||||||
|
Action<BitmapImage> SetImageAction;
|
||||||
|
|
||||||
|
int ErrCount;
|
||||||
|
|
||||||
|
object ErrLock = new object();
|
||||||
|
|
||||||
|
|
||||||
|
public LiveViewPage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
APIHandler = new CanonAPI();
|
||||||
|
APIHandler.CameraAdded += APIHandler_CameraAdded;
|
||||||
|
ErrorHandler.SevereErrorHappened += ErrorHandler_SevereErrorHappened;
|
||||||
|
ErrorHandler.NonSevereErrorHappened += ErrorHandler_NonSevereErrorHappened;
|
||||||
|
//SavePathTextBox.Text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "RemotePhoto");
|
||||||
|
SetImageAction = (BitmapImage img) => { bgbrush.ImageSource = img; };
|
||||||
|
RefreshCamera();
|
||||||
|
IsInit = true;
|
||||||
|
}
|
||||||
|
catch (DllNotFoundException)
|
||||||
|
{
|
||||||
|
ReportError("Canon DLLs not found!", true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void CloseSession()
|
||||||
|
{
|
||||||
|
MainCamera.CloseSession();
|
||||||
|
// AvCoBox.Items.Clear();
|
||||||
|
// TvCoBox.Items.Clear();
|
||||||
|
// ISOCoBox.Items.Clear();
|
||||||
|
// SettingsGroupBox.IsEnabled = false;
|
||||||
|
// LiveViewGroupBox.IsEnabled = false;
|
||||||
|
// SessionButton.Content = "Open Session";
|
||||||
|
// SessionLabel.Content = "No open session";
|
||||||
|
// StarLVButton.Content = "Start LV";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshCamera()
|
||||||
|
{
|
||||||
|
// CameraListBox.Items.Clear();
|
||||||
|
CamList = APIHandler.GetCameraList();
|
||||||
|
// foreach (Camera cam in CamList) CameraListBox.Items.Add(cam.DeviceName);
|
||||||
|
// if (MainCamera?.SessionOpen == true) CameraListBox.SelectedIndex = CamList.FindIndex(t => t.ID == MainCamera.ID);
|
||||||
|
// else if (CamList.Count > 0) CameraListBox.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenSession()
|
||||||
|
{
|
||||||
|
|
||||||
|
MainCamera = CamList[0];
|
||||||
|
MainCamera.OpenSession();
|
||||||
|
MainCamera.LiveViewUpdated += MainCamera_LiveViewUpdated;
|
||||||
|
MainCamera.ProgressChanged += MainCamera_ProgressChanged;
|
||||||
|
MainCamera.StateChanged += MainCamera_StateChanged;
|
||||||
|
MainCamera.DownloadReady += MainCamera_DownloadReady;
|
||||||
|
|
||||||
|
|
||||||
|
//SessionLabel.Content = MainCamera.DeviceName;
|
||||||
|
AvList = MainCamera.GetSettingsList(PropertyID.Av);
|
||||||
|
TvList = MainCamera.GetSettingsList(PropertyID.Tv);
|
||||||
|
ISOList = MainCamera.GetSettingsList(PropertyID.ISO);
|
||||||
|
// foreach (var Av in AvList) AvCoBox.Items.Add(Av.StringValue);
|
||||||
|
// foreach (var Tv in TvList) TvCoBox.Items.Add(Tv.StringValue);
|
||||||
|
// foreach (var ISO in ISOList) ISOCoBox.Items.Add(ISO.StringValue);
|
||||||
|
// AvCoBox.SelectedIndex = AvCoBox.Items.IndexOf(AvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Av)).StringValue);
|
||||||
|
// TvCoBox.SelectedIndex = TvCoBox.Items.IndexOf(TvValues.GetValue(MainCamera.GetInt32Setting(PropertyID.Tv)).StringValue);
|
||||||
|
// ISOCoBox.SelectedIndex = ISOCoBox.Items.IndexOf(ISOValues.GetValue(MainCamera.GetInt32Setting(PropertyID.ISO)).StringValue);
|
||||||
|
// SettingsGroupBox.IsEnabled = true;
|
||||||
|
// LiveViewGroupBox.IsEnabled = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReportError(string message, bool lockdown)
|
||||||
|
{
|
||||||
|
int errc;
|
||||||
|
lock (ErrLock) { errc = ++ErrCount; }
|
||||||
|
|
||||||
|
if (lockdown) EnableUI(false);
|
||||||
|
|
||||||
|
if (errc < 4) MessageBox.Show(message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
else if (errc == 4) MessageBox.Show("Many errors happened!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
|
||||||
|
lock (ErrLock) { ErrCount--; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableUI(bool enable)
|
||||||
|
{
|
||||||
|
if (!Dispatcher.CheckAccess()) Dispatcher.Invoke((Action)delegate { EnableUI(enable); });
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// SettingsGroupBox.IsEnabled = enable;
|
||||||
|
// InitGroupBox.IsEnabled = enable;
|
||||||
|
// LiveViewGroupBox.IsEnabled = enable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region API Events
|
||||||
|
|
||||||
|
private void APIHandler_CameraAdded(CanonAPI sender)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MainCamera_StateChanged(Camera sender, StateEventID eventID, int parameter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (eventID == StateEventID.Shutdown && IsInit)
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke((Action)delegate { CloseSession(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MainCamera_ProgressChanged(object sender, int progress)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//MainProgressBar.Dispatcher.Invoke((Action)delegate { MainProgressBar.Value = progress; });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MainCamera_LiveViewUpdated(Camera sender, Stream img)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (WrapStream s = new WrapStream(img))
|
||||||
|
{
|
||||||
|
img.Position = 0;
|
||||||
|
BitmapImage EvfImage = new BitmapImage();
|
||||||
|
EvfImage.BeginInit();
|
||||||
|
EvfImage.StreamSource = s;
|
||||||
|
EvfImage.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
EvfImage.EndInit();
|
||||||
|
EvfImage.Freeze();
|
||||||
|
Application.Current.Dispatcher.BeginInvoke(SetImageAction, EvfImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MainCamera_DownloadReady(Camera sender, DownloadInfo Info)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string dir = null;
|
||||||
|
//SavePathTextBox.Dispatcher.Invoke((Action)delegate { dir = SavePathTextBox.Text; });
|
||||||
|
sender.DownloadFile(Info, dir);
|
||||||
|
//MainProgressBar.Dispatcher.Invoke((Action)delegate { MainProgressBar.Value = 0; });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ErrorHandler_NonSevereErrorHappened(object sender, ErrorCode ex)
|
||||||
|
{
|
||||||
|
ReportError($"SDK Error code: {ex} ({((int)ex).ToString("X")})", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ErrorHandler_SevereErrorHappened(object sender, Exception ex)
|
||||||
|
{
|
||||||
|
ReportError(ex.Message, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
120
src/CamBooth/CamBooth.App/LiveView/WrappingStream.cs
Normal file
120
src/CamBooth/CamBooth.App/LiveView/WrappingStream.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CamBooth.App.LiveView
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A stream that does nothing more but wrap another stream (needed for a WPF memory leak)
|
||||||
|
/// </summary>
|
||||||
|
public sealed class WrapStream : Stream
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports reading.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return this.Base.CanRead; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports seeking.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanSeek
|
||||||
|
{
|
||||||
|
get { return this.Base.CanSeek; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports writing.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return this.Base.CanWrite; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the length in bytes of the stream.
|
||||||
|
/// </summary>
|
||||||
|
public override long Length
|
||||||
|
{
|
||||||
|
get { return this.Base.Length; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the position within the current stream.
|
||||||
|
/// </summary>
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get { return this.Base.Position; }
|
||||||
|
set { this.Base.Position = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream Base;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="WrapStream"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inStream">The stream that gets wrapped</param>
|
||||||
|
public WrapStream(Stream inStream)
|
||||||
|
{
|
||||||
|
this.Base = inStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// reads a sequence of bytes from the current stream and advances
|
||||||
|
/// the position within the stream by the number of bytes read.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||||
|
/// byte array with the values between offset and (offset + count - 1) replaced
|
||||||
|
/// by the bytes read from the current source.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||||
|
/// from the current stream.</param>
|
||||||
|
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer. This can be less than the
|
||||||
|
/// number of bytes requested if that many bytes are not currently available,
|
||||||
|
/// or zero (0) if the end of the stream has been reached.</returns>
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
return this.Base.Read(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When overridden in a derived class, writes a sequence of bytes to the current
|
||||||
|
/// stream and advances the current position within this stream by the number
|
||||||
|
/// of bytes written.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the
|
||||||
|
/// current stream.</param>
|
||||||
|
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
this.Base.Write(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// sets the position within the current stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||||
|
/// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used
|
||||||
|
/// to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current stream.</returns>
|
||||||
|
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
||||||
|
{
|
||||||
|
return this.Base.Seek(offset, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all buffers for this stream and causes any buffered data to be written to the underlying device.
|
||||||
|
/// </summary>
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
this.Base.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the length of the current stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
this.Base.SetLength(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/CamBooth/CamBooth.App/MainWindow.xaml
Normal file
43
src/CamBooth/CamBooth.App/MainWindow.xaml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<Window x:Class="CamBooth.App.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:CamBooth.App"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="MainWindow" Height="650" Width="800">
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/> <!-- Erste Zeile (Auto-Höhe) -->
|
||||||
|
<RowDefinition Height="*"/> <!-- Zweite Zeile (flexibler Platz) -->
|
||||||
|
<RowDefinition Height="Auto"/> <!-- Dritte Zeile (Auto-Höhe) -->
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- Inhalt der ersten Zeile -->
|
||||||
|
<Frame Grid.Row="0"
|
||||||
|
x:Name="MainFrame"
|
||||||
|
NavigationUIVisibility="Hidden"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Background="LightBlue"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Panel.ZIndex="0" />
|
||||||
|
|
||||||
|
<!-- Inhalt der zweiten Zeile (nimmt den verbleibenden Platz ein) -->
|
||||||
|
<Frame Grid.Row="1"
|
||||||
|
x:Name="DebugFrame"
|
||||||
|
NavigationUIVisibility="Hidden"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Height="100"
|
||||||
|
Background="LightGreen"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Panel.ZIndex="1" />
|
||||||
|
|
||||||
|
<!-- Inhalt der dritten Zeile -->
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<Button Content="Start" Click="NavToLiveView" Width="200" Background="LightCoral" Height="50" VerticalAlignment="Bottom"/>
|
||||||
|
<Button Content="Hide Debug" Click="ToggleDebugConsole" Width="200" Background="LightCoral" Height="50" VerticalAlignment="Bottom"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
51
src/CamBooth/CamBooth.App/MainWindow.xaml.cs
Normal file
51
src/CamBooth/CamBooth.App/MainWindow.xaml.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
using CamBooth.App.Core.Logging;
|
||||||
|
using CamBooth.App.DebugConsole;
|
||||||
|
using CamBooth.App.LiveView;
|
||||||
|
|
||||||
|
namespace CamBooth.App;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MainWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
private bool _isDebugConsoleVisible;
|
||||||
|
|
||||||
|
public MainWindow(Logger logger)
|
||||||
|
{
|
||||||
|
this._logger = logger;
|
||||||
|
InitializeComponent();
|
||||||
|
logger.LogInfo("MainWindow initialized");
|
||||||
|
ToggleDebugConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavToLiveView(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
MainFrame.Navigate(new LiveViewPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleDebugConsole(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.ToggleDebugConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleDebugConsole()
|
||||||
|
{
|
||||||
|
if (_isDebugConsoleVisible)
|
||||||
|
{
|
||||||
|
this.DebugFrame.ClearValue(Frame.ContentProperty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.DebugFrame.Navigate(new DebugConsolePage());
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isDebugConsoleVisible = !this._isDebugConsoleVisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,22 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamBooth.App", "CamBooth.App\CamBooth.App.csproj", "{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EDSDKLib", "EDSDKLib\EDSDKLib.csproj", "{15E99248-6161-46A4-9183-609CA62406A6}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C0EEB2D6-5C1D-4245-AFDC-A7640E386573}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{15E99248-6161-46A4-9183-609CA62406A6}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
|
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{15E99248-6161-46A4-9183-609CA62406A6}.Release|Any CPU.Build.0 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
12
src/CamBooth/CamBooth.sln.DotSettings.user
Normal file
12
src/CamBooth/CamBooth.sln.DotSettings.user
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPDLL_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPLibCom_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CDPPRSC_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CEDSDK_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CEdsImage_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CMlib_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CDev_005CRepos_005CPrivat_005CCamBooth_005Cmisc_005CCanonBinaries_005CUcs32P_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AApplication_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6665f2e3e843578225e3796b83c5342a58c3f72bfef19eeee7aa90d157d4949_003FApplication_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fbd1d5c50194fea68ff3559c160230b0ab50f5acf4ce3061bffd6d62958e2182_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0713c794b56e4feca091d5981a6f5967f60930_003Fc8_003F61b7e802_003FWindow_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWindow_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003Ftobia_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd0db11e55b76dc7f234163f6cee32b297b8ddb591fb0b5cbad1b46ed17343e18_003FWindow_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||||
1569
src/CamBooth/EDSDKLib/API/Base/Camera.cs
Normal file
1569
src/CamBooth/EDSDKLib/API/Base/Camera.cs
Normal file
File diff suppressed because it is too large
Load Diff
337
src/CamBooth/EDSDKLib/API/Base/CanonAPI.cs
Normal file
337
src/CamBooth/EDSDKLib/API/Base/CanonAPI.cs
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
using Size = EOSDigital.SDK.Size;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles camera connections
|
||||||
|
/// </summary>
|
||||||
|
public class CanonAPI : IDisposable
|
||||||
|
{
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fires if a new camera is added
|
||||||
|
/// </summary>
|
||||||
|
public event CameraAddedHandler CameraAdded;
|
||||||
|
/// <summary>
|
||||||
|
/// The SDK camera added delegate
|
||||||
|
/// </summary>
|
||||||
|
protected static SDKCameraAddedHandler CameraAddedEvent;
|
||||||
|
|
||||||
|
private ErrorCode CanonAPI_CameraAddedEvent(IntPtr inContext)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem((state) => CameraAdded?.Invoke(this));
|
||||||
|
return ErrorCode.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Variables
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States if the SDK is initialized or not
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsSDKInitialized
|
||||||
|
{
|
||||||
|
get { return _IsSDKInitialized; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The main SDK thread where the event loop runs
|
||||||
|
/// </summary>
|
||||||
|
protected static STAThread MainThread;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Field for the public <see cref="IsSDKInitialized"/> property
|
||||||
|
/// </summary>
|
||||||
|
private static bool _IsSDKInitialized;
|
||||||
|
/// <summary>
|
||||||
|
/// States if the instance is disposed or not
|
||||||
|
/// </summary>
|
||||||
|
private bool IsDisposed;
|
||||||
|
/// <summary>
|
||||||
|
/// Number of instances of this class
|
||||||
|
/// </summary>
|
||||||
|
private static int RefCount = 0;
|
||||||
|
/// <summary>
|
||||||
|
/// Object to lock on to safely de- and increment the <see cref="RefCount"/> value
|
||||||
|
/// </summary>
|
||||||
|
private static readonly object InitLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// List of currently connected cameras (since the last time GetCameraList got called)
|
||||||
|
/// </summary>
|
||||||
|
private static List<Camera> CurrentCameras = new List<Camera>();
|
||||||
|
/// <summary>
|
||||||
|
/// Object to lock on to safely add/remove cameras from the <see cref="CurrentCameras"/> list
|
||||||
|
/// </summary>
|
||||||
|
private static readonly object CameraLock = new object();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Init/Dispose
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the SDK
|
||||||
|
/// </summary>
|
||||||
|
public CanonAPI()
|
||||||
|
: this(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the SDK
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="useCallingThread">If true, the calling thread will be used as SDK main thread;
|
||||||
|
/// if false, a separate thread will be created</param>
|
||||||
|
public CanonAPI(bool useCallingThread)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Ensure that only one caller at a time can increase the counter
|
||||||
|
lock (InitLock)
|
||||||
|
{
|
||||||
|
//If no instance exists yet, initialize everything
|
||||||
|
if (RefCount == 0)
|
||||||
|
{
|
||||||
|
if (useCallingThread)
|
||||||
|
{
|
||||||
|
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
|
||||||
|
throw new ThreadStateException("Calling thread must be in STA");
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Trying to trigger DllNotFoundException so it's not thrown
|
||||||
|
//in the event loop on a different thread:
|
||||||
|
CanonSDK.EdsRelease(IntPtr.Zero);
|
||||||
|
|
||||||
|
//Start the main thread where SDK will run on
|
||||||
|
MainThread = new ApiThread();
|
||||||
|
MainThread.Start();
|
||||||
|
//Initialize the SDK on the main thread
|
||||||
|
MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CanonSDK.InitializeVersion();
|
||||||
|
//Subscribe to the CameraAdded event
|
||||||
|
CameraAddedEvent = new SDKCameraAddedHandler(CanonAPI_CameraAddedEvent);
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraAddedHandler(CameraAddedEvent, IntPtr.Zero));
|
||||||
|
_IsSDKInitialized = true;
|
||||||
|
}
|
||||||
|
RefCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
IsDisposed = true;
|
||||||
|
if (MainThread?.IsRunning == true) MainThread.Shutdown();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destructor
|
||||||
|
/// </summary>
|
||||||
|
~CanonAPI()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Terminates the SDK and disposes resources
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Terminates the SDK and disposes resources
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
|
||||||
|
protected virtual void Dispose(bool managed)
|
||||||
|
{
|
||||||
|
//Ensure that only one caller at a time can decrease the counter
|
||||||
|
lock (InitLock)
|
||||||
|
{
|
||||||
|
if (!IsDisposed)
|
||||||
|
{
|
||||||
|
//If it's the last instance, release everything
|
||||||
|
if (RefCount == 1)
|
||||||
|
{
|
||||||
|
_IsSDKInitialized = false;//Set beforehand because if an error happens, the SDK will be in an unstable state anyway
|
||||||
|
|
||||||
|
//Remove event handler for the CameraAdded event
|
||||||
|
ErrorCode err = CanonSDK.EdsSetCameraAddedHandler(null, IntPtr.Zero);
|
||||||
|
if (managed)
|
||||||
|
{
|
||||||
|
ErrorHandler.CheckError(this, err);
|
||||||
|
//Dispose all the connected cameras
|
||||||
|
CurrentCameras.ForEach(t => t.Dispose());
|
||||||
|
}
|
||||||
|
//Terminate the SDK
|
||||||
|
if (MainThread?.IsRunning == true) err = MainThread.Invoke(() => { return CanonSDK.EdsTerminateSDK(); });
|
||||||
|
//Close the main thread
|
||||||
|
if (MainThread?.IsRunning == true) MainThread.Shutdown();
|
||||||
|
if (managed) ErrorHandler.CheckError(this, err);
|
||||||
|
}
|
||||||
|
RefCount--;
|
||||||
|
IsDisposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of all cameras connected to the host.
|
||||||
|
/// <para>If a camera has been connected previously, the same instance of the class is returned.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A list of connected cameras</returns>
|
||||||
|
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
|
||||||
|
/// <exception cref="SDKException">An SDK call failed</exception>
|
||||||
|
public List<Camera> GetCameraList()
|
||||||
|
{
|
||||||
|
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
|
||||||
|
|
||||||
|
//Ensure that only one caller at a time can access the camera list
|
||||||
|
lock (CameraLock)
|
||||||
|
{
|
||||||
|
//Get a list of camera pointers
|
||||||
|
IEnumerable<IntPtr> ptrList = GetCameraPointerList();
|
||||||
|
List<Camera> camList = new List<Camera>();
|
||||||
|
|
||||||
|
//Find cameras that were connected before and add new ones
|
||||||
|
foreach (var ptr in ptrList)
|
||||||
|
{
|
||||||
|
var oldCam = CurrentCameras.FirstOrDefault(t => t.Reference == ptr);
|
||||||
|
if (oldCam != null && !oldCam.IsDisposed) camList.Add(oldCam); //Pointer exists already so we reuse it
|
||||||
|
else camList.Add(new Camera(ptr)); //Pointer does not exists yet, so we add it
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ensure that cameras not connected anymore are disposed properly
|
||||||
|
var oldCameras = CurrentCameras.Where(t => !ptrList.Any(u => u == t.Reference));
|
||||||
|
foreach (var cam in oldCameras) { if (!cam.IsDisposed) cam.Dispose(); }
|
||||||
|
|
||||||
|
CurrentCameras.Clear();
|
||||||
|
CurrentCameras.AddRange(camList);
|
||||||
|
return camList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of all pointer of the cameras connected to the host
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A list of connected cameras as pointer</returns>
|
||||||
|
/// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
|
||||||
|
/// <exception cref="SDKException">An SDK call failed</exception>
|
||||||
|
protected IEnumerable<IntPtr> GetCameraPointerList()
|
||||||
|
{
|
||||||
|
if (IsDisposed) throw new ObjectDisposedException(nameof(CanonAPI));
|
||||||
|
|
||||||
|
IntPtr camlist;
|
||||||
|
//Get camera list
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetCameraList(out camlist));
|
||||||
|
|
||||||
|
//Get number of connected cameras
|
||||||
|
int camCount;
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(camlist, out camCount));
|
||||||
|
List<IntPtr> ptrList = new List<IntPtr>();
|
||||||
|
for (int i = 0; i < camCount; i++)
|
||||||
|
{
|
||||||
|
//Get camera pointer
|
||||||
|
IntPtr cptr;
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(camlist, i, out cptr));
|
||||||
|
ptrList.Add(cptr);
|
||||||
|
}
|
||||||
|
//Release the list
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsRelease(camlist));
|
||||||
|
return ptrList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a thumbnail from a Raw or Jpg image
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filepath">Path to the image file</param>
|
||||||
|
/// <returns>A <see cref="Bitmap"/> thumbnail from the provided image file</returns>
|
||||||
|
public Bitmap GetFileThumb(string filepath)
|
||||||
|
{
|
||||||
|
//create a file stream to given file
|
||||||
|
using (var stream = new SDKStream(filepath, FileCreateDisposition.OpenExisting, FileAccess.Read))
|
||||||
|
{
|
||||||
|
//Create a thumbnail Bitmap from the stream
|
||||||
|
return GetImage(stream.Reference, ImageSource.Thumbnail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="Bitmap"/> from an EDSDK pointer to an image (Jpg or Raw)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="imgStream">Stream pointer to the image</param>
|
||||||
|
/// <param name="imageSource">The result image type</param>
|
||||||
|
/// <returns>A <see cref="Bitmap"/> image from the given stream pointer</returns>
|
||||||
|
protected Bitmap GetImage(IntPtr imgStream, ImageSource imageSource)
|
||||||
|
{
|
||||||
|
IntPtr imgRef = IntPtr.Zero;
|
||||||
|
IntPtr streamPointer = IntPtr.Zero;
|
||||||
|
ImageInfo imageInfo;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//create reference and get image info
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsCreateImageRef(imgStream, out imgRef));
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetImageInfo(imgRef, imageSource, out imageInfo));
|
||||||
|
|
||||||
|
Size outputSize = new Size();
|
||||||
|
outputSize.Width = imageInfo.EffectiveRect.Width;
|
||||||
|
outputSize.Height = imageInfo.EffectiveRect.Height;
|
||||||
|
//calculate amount of data
|
||||||
|
int datalength = outputSize.Height * outputSize.Width * 3;
|
||||||
|
//create buffer that stores the image
|
||||||
|
byte[] buffer = new byte[datalength];
|
||||||
|
//create a stream to the buffer
|
||||||
|
using (var stream = new SDKStream(buffer))
|
||||||
|
{
|
||||||
|
//load image into the buffer
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetImage(imgRef, imageSource, TargetImageType.RGB, imageInfo.EffectiveRect, outputSize, stream.Reference));
|
||||||
|
|
||||||
|
//make BGR from RGB (System.Drawing (i.e. GDI+) uses BGR)
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
byte tmp;
|
||||||
|
fixed (byte* pix = buffer)
|
||||||
|
{
|
||||||
|
for (long i = 0; i < datalength; i += 3)
|
||||||
|
{
|
||||||
|
tmp = pix[i]; //Save B value
|
||||||
|
pix[i] = pix[i + 2]; //Set B value with R value
|
||||||
|
pix[i + 2] = tmp; //Set R value with B value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get pointer to stream data
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.EdsGetPointer(stream.Reference, out streamPointer));
|
||||||
|
//Create bitmap with the data in the buffer
|
||||||
|
return new Bitmap(outputSize.Width, outputSize.Height, datalength, PixelFormat.Format24bppRgb, streamPointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//Release all data
|
||||||
|
if (imgStream != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgStream));
|
||||||
|
if (imgRef != IntPtr.Zero) ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgRef));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/CamBooth/EDSDKLib/API/Helper/ApiThread.cs
Normal file
25
src/CamBooth/EDSDKLib/API/Helper/ApiThread.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using EOSDigital.SDK;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
internal sealed class ApiThread : STAThread
|
||||||
|
{
|
||||||
|
protected override void WaitForNotification()
|
||||||
|
{
|
||||||
|
lock (threadLock1)
|
||||||
|
{
|
||||||
|
while (block1 && IsRunning)
|
||||||
|
{
|
||||||
|
Monitor.Wait(threadLock1, 0);
|
||||||
|
lock (ExecLock)
|
||||||
|
{
|
||||||
|
CanonSDK.EdsGetEvent();
|
||||||
|
Monitor.Wait(ExecLock, 40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
block1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
282
src/CamBooth/EDSDKLib/API/Helper/CameraValue.cs
Normal file
282
src/CamBooth/EDSDKLib/API/Helper/CameraValue.cs
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
using EOSDigital.SDK;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores a camera value
|
||||||
|
/// </summary>
|
||||||
|
public class CameraValue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The value as a string
|
||||||
|
/// </summary>
|
||||||
|
public string StringValue { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The value as an UInt
|
||||||
|
/// </summary>
|
||||||
|
public int IntValue { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The value as a double
|
||||||
|
/// </summary>
|
||||||
|
public double DoubleValue { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The property ID of this value
|
||||||
|
/// </summary>
|
||||||
|
public PropertyID ValueType { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="CameraValue"/> class
|
||||||
|
/// </summary>
|
||||||
|
protected CameraValue()
|
||||||
|
{
|
||||||
|
ValueType = PropertyID.Unknown;
|
||||||
|
StringValue = "N/A";
|
||||||
|
IntValue = unchecked((int)0xFFFFFFFF);
|
||||||
|
DoubleValue = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new camera value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Value">The value as a string</param>
|
||||||
|
/// <param name="ValueType">The property ID of the value</param>
|
||||||
|
public CameraValue(string Value, PropertyID ValueType)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
this.ValueType = ValueType;
|
||||||
|
StringValue = Value;
|
||||||
|
switch (ValueType)
|
||||||
|
{
|
||||||
|
case PropertyID.Av:
|
||||||
|
IntValue = AvValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = AvValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.Tv:
|
||||||
|
IntValue = TvValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = TvValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ISO:
|
||||||
|
IntValue = ISOValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ColorTemperature:
|
||||||
|
int utmp;
|
||||||
|
IntValue = (int.TryParse(Value, out utmp)) ? utmp : 5600;
|
||||||
|
DoubleValue = utmp;
|
||||||
|
break;
|
||||||
|
case PropertyID.AEMode:
|
||||||
|
IntValue = AEModeValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.MeteringMode:
|
||||||
|
IntValue = MeteringModeValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ExposureCompensation:
|
||||||
|
IntValue = ExpCompValues.GetValue(Value).IntValue;
|
||||||
|
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new camera value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Value">The value as an uint</param>
|
||||||
|
/// <param name="ValueType">The property ID of the value</param>
|
||||||
|
public CameraValue(int Value, PropertyID ValueType)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
this.ValueType = ValueType;
|
||||||
|
IntValue = Value;
|
||||||
|
switch (ValueType)
|
||||||
|
{
|
||||||
|
case PropertyID.Av:
|
||||||
|
StringValue = AvValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = AvValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.Tv:
|
||||||
|
StringValue = TvValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = TvValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ISO:
|
||||||
|
StringValue = ISOValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = ISOValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ColorTemperature:
|
||||||
|
StringValue = Value.ToString();
|
||||||
|
DoubleValue = Value;
|
||||||
|
break;
|
||||||
|
case PropertyID.AEMode:
|
||||||
|
StringValue = AEModeValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = AEModeValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.MeteringMode:
|
||||||
|
StringValue = MeteringModeValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = MeteringModeValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ExposureCompensation:
|
||||||
|
StringValue = ExpCompValues.GetValue(Value).StringValue;
|
||||||
|
DoubleValue = ExpCompValues.GetValue(Value).DoubleValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new camera value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Value">The value as a double</param>
|
||||||
|
/// <param name="ValueType">The property ID of the value</param>
|
||||||
|
public CameraValue(double Value, PropertyID ValueType)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
this.ValueType = ValueType;
|
||||||
|
DoubleValue = Value;
|
||||||
|
switch (ValueType)
|
||||||
|
{
|
||||||
|
case PropertyID.Av:
|
||||||
|
StringValue = AvValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = AvValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.Tv:
|
||||||
|
StringValue = TvValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = TvValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ISO:
|
||||||
|
StringValue = ISOValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = ISOValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ColorTemperature:
|
||||||
|
StringValue = Value.ToString("F0");
|
||||||
|
IntValue = (int)Value;
|
||||||
|
break;
|
||||||
|
case PropertyID.AEMode:
|
||||||
|
StringValue = AEModeValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = AEModeValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.MeteringMode:
|
||||||
|
StringValue = MeteringModeValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = MeteringModeValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
case PropertyID.ExposureCompensation:
|
||||||
|
StringValue = ExpCompValues.GetValue(Value).StringValue;
|
||||||
|
IntValue = ExpCompValues.GetValue(Value).IntValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CameraValue(string SValue, int IValue, double DValue)
|
||||||
|
{
|
||||||
|
ValueType = PropertyID.Unknown;
|
||||||
|
StringValue = SValue;
|
||||||
|
IntValue = IValue;
|
||||||
|
DoubleValue = DValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CameraValue(string SValue, int IValue, double DValue, PropertyID ValueType)
|
||||||
|
{
|
||||||
|
this.ValueType = ValueType;
|
||||||
|
StringValue = SValue;
|
||||||
|
IntValue = IValue;
|
||||||
|
DoubleValue = DValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="CameraValue"/>s are equal to each other.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||||
|
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||||
|
/// <returns>True if the <see cref="CameraValue"/>s are equal; otherwise, false</returns>
|
||||||
|
public static bool operator ==(CameraValue x, CameraValue y)
|
||||||
|
{
|
||||||
|
// If both are null, or both are same instance, return true.
|
||||||
|
if (object.ReferenceEquals(x, y)) return true;
|
||||||
|
|
||||||
|
// If one is null, but not both, return false.
|
||||||
|
if ((object)x == null || (object)y == null) return false;
|
||||||
|
|
||||||
|
return x.IntValue == y.IntValue && x.ValueType == y.ValueType;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="CameraValue"/>s are unequal to each other.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||||
|
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||||
|
/// <returns>True if the <see cref="CameraValue"/>s are unequal; otherwise, false</returns>
|
||||||
|
public static bool operator !=(CameraValue x, CameraValue y)
|
||||||
|
{
|
||||||
|
return !(x == y);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraValue"/></param>
|
||||||
|
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraValue"/>; otherwise, false.</returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
// If objects have different types, return false.
|
||||||
|
if (obj.GetType() != GetType()) return false;
|
||||||
|
|
||||||
|
// If both are null, or both are same instance, return true.
|
||||||
|
if (object.ReferenceEquals(this, obj)) return true;
|
||||||
|
|
||||||
|
CameraValue cv = obj as CameraValue;
|
||||||
|
if (cv == null) return false;
|
||||||
|
|
||||||
|
return IntValue == cv.IntValue && ValueType == cv.ValueType;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Serves as a hash function for a <see cref="CameraValue"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
int hash = (int)2166136261;
|
||||||
|
hash *= 16777619 ^ IntValue.GetHashCode();
|
||||||
|
hash *= 16777619 ^ ValueType.GetHashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts the camera value to an int
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The camera value to convert</param>
|
||||||
|
/// <returns>The int representing the camera value</returns>
|
||||||
|
public static implicit operator int(CameraValue x)
|
||||||
|
{
|
||||||
|
return x.IntValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts the camera value to a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The camera value to convert</param>
|
||||||
|
/// <returns>The string representing the camera value</returns>
|
||||||
|
public static implicit operator string(CameraValue x)
|
||||||
|
{
|
||||||
|
return x.StringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Implicitly converts the camera value to a double
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The camera value to convert</param>
|
||||||
|
/// <returns>The double representing the camera value</returns>
|
||||||
|
public static implicit operator double(CameraValue x)
|
||||||
|
{
|
||||||
|
return x.DoubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a string that represents the current <see cref="CameraValue"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A string that represents the current <see cref="CameraValue"/>.</returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return StringValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/CamBooth/EDSDKLib/API/Helper/Delegates.cs
Normal file
69
src/CamBooth/EDSDKLib/API/Helper/Delegates.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for progress
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="progress">The progress. A value between 0 and 100</param>
|
||||||
|
public delegate void ProgressHandler(object sender, int progress);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to pass a stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="img">An image embedded in a stream</param>
|
||||||
|
public delegate void LiveViewUpdate(Camera sender, Stream img);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to report an available download
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="Info">The data for the download</param>
|
||||||
|
public delegate void DownloadHandler(Camera sender, DownloadInfo Info);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for property changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="eventID">The property event ID</param>
|
||||||
|
/// <param name="propID">The property ID</param>
|
||||||
|
/// <param name="parameter">A parameter for additional information</param>
|
||||||
|
public delegate void PropertyChangeHandler(Camera sender, PropertyEventID eventID, PropertyID propID, int parameter);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for camera state changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="eventID">The state event ID</param>
|
||||||
|
/// <param name="parameter">A parameter for additional information</param>
|
||||||
|
public delegate void StateChangeHandler(Camera sender, StateEventID eventID, int parameter);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for property changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="eventID">The object event ID</param>
|
||||||
|
/// <param name="reference">A pointer to the object that has changed</param>
|
||||||
|
public delegate void ObjectChangeHandler(Camera sender, ObjectEventID eventID, IntPtr reference);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to inform of an added camera
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
public delegate void CameraAddedHandler(CanonAPI sender);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to inform of a change of a camera
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
public delegate void CameraUpdateHandler(Camera sender);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to inform of SDK exceptions
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="ex">The SDK exception</param>
|
||||||
|
public delegate void SDKExceptionHandler(object sender, ErrorCode ex);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to inform of exceptions
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender of this event</param>
|
||||||
|
/// <param name="ex">The exception</param>
|
||||||
|
public delegate void GeneralExceptionHandler(object sender, Exception ex);
|
||||||
|
}
|
||||||
421
src/CamBooth/EDSDKLib/API/Helper/ExceptionHandling.cs
Normal file
421
src/CamBooth/EDSDKLib/API/Helper/ExceptionHandling.cs
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Remoting.Messaging;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An Exception that happened while handling the Canon SDK
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class SDKException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The specific SDK error code that happened
|
||||||
|
/// </summary>
|
||||||
|
public ErrorCode Error { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class
|
||||||
|
/// </summary>
|
||||||
|
public SDKException()
|
||||||
|
{
|
||||||
|
Error = ErrorCode.INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error code
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||||
|
public SDKException(ErrorCode Error)
|
||||||
|
: base(Error.ToString())
|
||||||
|
{
|
||||||
|
this.Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
public SDKException(string message)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
Error = ErrorCode.INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
|
||||||
|
/// error message and a reference to the inner exception that is the cause of
|
||||||
|
/// this exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||||
|
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||||
|
public SDKException(string message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{
|
||||||
|
Error = ErrorCode.INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified error message and error code
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
public SDKException(string message, ErrorCode Error)
|
||||||
|
: base(message)
|
||||||
|
{
|
||||||
|
this.Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with a specified
|
||||||
|
/// error message, error code and a reference to the inner exception that is the cause of
|
||||||
|
/// this exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
/// <param name="Error">The SDK error code of the error that happened</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||||
|
/// (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||||
|
public SDKException(string message, ErrorCode Error, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{
|
||||||
|
this.Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKException"/> class with serialized data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||||
|
/// object data about the exception being thrown.</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||||
|
/// information about the source or destination.</param>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
private SDKException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{
|
||||||
|
Error = (ErrorCode)info.GetUInt32("Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||||
|
/// with information about the exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||||
|
/// that holds the serialized object data about the exception being thrown</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/>
|
||||||
|
/// that contains contextual information about the source or destination.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||||
|
info.AddValue("Error", Error);
|
||||||
|
|
||||||
|
base.GetObjectData(info, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An Exception that states a problem with the session state of the camera
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class CameraSessionException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CameraSessionException"/> class
|
||||||
|
/// </summary>
|
||||||
|
public CameraSessionException()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
public CameraSessionException(string message)
|
||||||
|
: base(message)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with a specified
|
||||||
|
/// error message and a reference to the inner exception that is the cause of
|
||||||
|
/// this exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||||
|
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||||
|
public CameraSessionException(string message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CameraSessionException"/> class with serialized data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||||
|
/// object data about the exception being thrown.</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||||
|
/// information about the source or destination.</param>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
private CameraSessionException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||||
|
/// with information about the exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||||
|
/// that holds the serialized object data about the exception being thrown</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/>
|
||||||
|
/// that contains contextual information about the source or destination.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||||
|
base.GetObjectData(info, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An Exception that states a problem with the state of the Canon SDK
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class SDKStateException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKStateException"/> class
|
||||||
|
/// </summary>
|
||||||
|
public SDKStateException()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
public SDKStateException(string message)
|
||||||
|
: base(message)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKStateException"/> class with a specified
|
||||||
|
/// error message and a reference to the inner exception that is the cause of
|
||||||
|
/// this exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||||
|
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||||
|
public SDKStateException(string message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SDKStateException"/> class with serialized data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||||
|
/// object data about the exception being thrown.</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||||
|
/// information about the source or destination.</param>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
private SDKStateException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||||
|
/// with information about the exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||||
|
/// that holds the serialized object data about the exception being thrown</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/>
|
||||||
|
/// that contains contextual information about the source or destination.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||||
|
base.GetObjectData(info, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An Exception that happened while executing on an STA thread
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public sealed class ExecutionException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a specified error message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
public ExecutionException(string message)
|
||||||
|
: base(message)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ExecutionException"/> class with a reference to
|
||||||
|
/// the inner exception that is the cause of this exception
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception</param>
|
||||||
|
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference
|
||||||
|
/// (Nothing in Visual Basic) if no inner exception is specified</param>
|
||||||
|
public ExecutionException(string message, Exception innerException)
|
||||||
|
: base(message, innerException)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ExecutionException"/> class with serialized data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized
|
||||||
|
/// object data about the exception being thrown.</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual
|
||||||
|
/// information about the source or destination.</param>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
private ExecutionException(SerializationInfo info, StreamingContext context)
|
||||||
|
: base(info, context)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When overridden in a derived class, sets the <see cref="SerializationInfo"/>
|
||||||
|
/// with information about the exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="info">The <see cref="SerializationInfo"/>
|
||||||
|
/// that holds the serialized object data about the exception being thrown</param>
|
||||||
|
/// <param name="context">The <see cref="StreamingContext"/>
|
||||||
|
/// that contains contextual information about the source or destination.</param>
|
||||||
|
/// <exception cref="ArgumentNullException">The info parameter is a null reference</exception>
|
||||||
|
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||||
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
|
{
|
||||||
|
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||||
|
base.GetObjectData(info, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles errors and provides events for errors (e.g. focus problems or general exceptions)
|
||||||
|
/// </summary>
|
||||||
|
public static class ErrorHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// If an error happened, that does not break the program, this event is fired (e.g. a focus error)
|
||||||
|
/// </summary>
|
||||||
|
public static event SDKExceptionHandler NonSevereErrorHappened;
|
||||||
|
/// <summary>
|
||||||
|
/// If an error happened on a thread that does not fall into the non-severe category, this event is fired
|
||||||
|
/// </summary>
|
||||||
|
public static event GeneralExceptionHandler SevereErrorHappened;
|
||||||
|
/// <summary>
|
||||||
|
/// List of all non-severe errors. Items can be added or removed.
|
||||||
|
/// </summary>
|
||||||
|
public static List<ErrorCode> NonSevereErrors { get; private set; }
|
||||||
|
|
||||||
|
static ErrorHandler()
|
||||||
|
{
|
||||||
|
NonSevereErrors = new List<ErrorCode>()
|
||||||
|
{
|
||||||
|
ErrorCode.TAKE_PICTURE_AF_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_CARD_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_CARD_PROTECT_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_LV_REL_PROHIBIT_MODE_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_MIRROR_UP_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_MOVIE_CROP_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_NO_CARD_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_NO_LENS_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_SENSOR_CLEANING_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_SILENCE_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_SPECIAL_MOVIE_MODE_NG,
|
||||||
|
ErrorCode.TAKE_PICTURE_STROBO_CHARGE_NG,
|
||||||
|
ErrorCode.LENS_COVER_CLOSE,
|
||||||
|
ErrorCode.DEVICE_BUSY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for an error in SDK calls and checks how to treat it
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender object</param>
|
||||||
|
/// <param name="errorCode">The return code of the SDK call</param>
|
||||||
|
/// <exception cref="SDKException">If a severe error is recognized or the <see cref="NonSevereErrorHappened"/>
|
||||||
|
/// event is null with a non-severe error, it will be thrown as an exception</exception>
|
||||||
|
public static void CheckError(object sender, ErrorCode errorCode)
|
||||||
|
{
|
||||||
|
if (errorCode == ErrorCode.OK) return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool Severe = !NonSevereErrors.Any(t => t == errorCode);
|
||||||
|
|
||||||
|
var NonSevereErrorHappenedEvent = NonSevereErrorHappened;
|
||||||
|
if (!Severe) Severe = NonSevereErrorHappenedEvent == null;
|
||||||
|
|
||||||
|
if (Severe) throw new SDKException(errorCode);
|
||||||
|
else NonSevereErrorHappenedEvent.BeginInvoke(sender, errorCode, (a) =>
|
||||||
|
{
|
||||||
|
var ar = a as AsyncResult;
|
||||||
|
var invokedMethod = ar.AsyncDelegate as SDKExceptionHandler;
|
||||||
|
invokedMethod.EndInvoke(a);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for an error in SDK calls and throws an exception if it's not <see cref="ErrorCode.OK"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="errorCode">The return code of the SDK call</param>
|
||||||
|
/// <exception cref="SDKException">If <paramref name="errorCode"/> is something other than <see cref="ErrorCode.OK"/></exception>
|
||||||
|
public static void CheckError(ErrorCode errorCode)
|
||||||
|
{
|
||||||
|
if (errorCode != ErrorCode.OK) throw new SDKException(errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
|
||||||
|
/// and throws an exception if it's not valid
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="countOrError">The return code of the SDK call</param>
|
||||||
|
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
|
||||||
|
public static int CheckError(int countOrError)
|
||||||
|
{
|
||||||
|
if (countOrError == unchecked((int)0xFFFFFFFF)) throw new SDKException(ErrorCode.INVALID_HANDLE);
|
||||||
|
else return countOrError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for an error in <see cref="CanonSDK.EdsRetain"/> and <see cref="CanonSDK.EdsRelease"/> calls
|
||||||
|
/// and throws an exception if it's not valid
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The calling object instance. This is currently not used and is ignored.</param>
|
||||||
|
/// <param name="countOrError">The return code of the SDK call</param>
|
||||||
|
/// <returns>The number of references for the pointer that was used for the SDK call</returns>
|
||||||
|
public static int CheckError(object sender, int countOrError)
|
||||||
|
{
|
||||||
|
return CheckError(countOrError);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports an error that happened in a threading environment
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The sender object</param>
|
||||||
|
/// <param name="ex">The exception that happened</param>
|
||||||
|
/// <returns>True if the error could be passed on; false otherwise</returns>
|
||||||
|
public static bool ReportError(object sender, Exception ex)
|
||||||
|
{
|
||||||
|
var SevereErrorHappenedEvent = SevereErrorHappened;
|
||||||
|
if (SevereErrorHappenedEvent == null) return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SevereErrorHappenedEvent.BeginInvoke(sender, ex, (a) =>
|
||||||
|
{
|
||||||
|
var ar = a as AsyncResult;
|
||||||
|
var invokedMethod = ar.AsyncDelegate as GeneralExceptionHandler;
|
||||||
|
invokedMethod.EndInvoke(a);
|
||||||
|
}, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
554
src/CamBooth/EDSDKLib/API/Helper/IO.cs
Normal file
554
src/CamBooth/EDSDKLib/API/Helper/IO.cs
Normal file
@ -0,0 +1,554 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
using SeekOrigin = System.IO.SeekOrigin;
|
||||||
|
using FileAccess = EOSDigital.SDK.FileAccess;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores information to download data from the camera
|
||||||
|
/// </summary>
|
||||||
|
public class DownloadInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the downloadable object
|
||||||
|
/// </summary>
|
||||||
|
protected IntPtr inRef;
|
||||||
|
/// <summary>
|
||||||
|
/// Directory item info of the downloadable object
|
||||||
|
/// </summary>
|
||||||
|
protected DirectoryItemInfo dirInfo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the downloadable object
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Reference { get { return inRef; } }
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the file. You can change it before you pass it to the
|
||||||
|
/// <see cref="Camera.DownloadFile(DownloadInfo)"/> or
|
||||||
|
/// <see cref="Camera.DownloadFile(DownloadInfo, string)"/> method.
|
||||||
|
/// </summary>
|
||||||
|
public string FileName
|
||||||
|
{
|
||||||
|
get { return dirInfo.FileName; }
|
||||||
|
set { dirInfo.FileName = value; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// The files size in bytes
|
||||||
|
/// </summary>
|
||||||
|
public int Size { get { return dirInfo.Size; } }
|
||||||
|
/// <summary>
|
||||||
|
/// The files size in bytes (as ulong)
|
||||||
|
/// </summary>
|
||||||
|
public long Size64 { get { return dirInfo.Size64; } }
|
||||||
|
/// <summary>
|
||||||
|
/// States if the file is a RAW file or not
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRAW { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="DownloadInfo"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inRef">Pointer to the downloadable object</param>
|
||||||
|
internal protected DownloadInfo(IntPtr inRef)
|
||||||
|
{
|
||||||
|
if (inRef == IntPtr.Zero) throw new ArgumentNullException(nameof(inRef));
|
||||||
|
|
||||||
|
this.inRef = inRef;
|
||||||
|
ErrorHandler.CheckError(this, CanonSDK.GetDirectoryItemInfo(inRef, out dirInfo));
|
||||||
|
string ext = Path.GetExtension(FileName).ToLower();
|
||||||
|
if (ext == ".crw" || ext == ".cr2") IsRAW = true;
|
||||||
|
else IsRAW = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores information about a file or folder in a camera
|
||||||
|
/// </summary>
|
||||||
|
public partial class CameraFileEntry : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the file entry
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Reference { get { return Ref; } }
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the entry. (volume name, folder name or file name)
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// States if the entry is a folder or not
|
||||||
|
/// </summary>
|
||||||
|
public bool IsFolder { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// States if the entry is a volume or not
|
||||||
|
/// </summary>
|
||||||
|
public bool IsVolume { get; protected set; }
|
||||||
|
/// <summary>
|
||||||
|
/// If the entry is a volume or folder, these are the subentries it contains. It's null if no subentries are present.
|
||||||
|
/// </summary>
|
||||||
|
public CameraFileEntry[] Entries { get; internal protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the file entry
|
||||||
|
/// </summary>
|
||||||
|
protected IntPtr Ref;
|
||||||
|
/// <summary>
|
||||||
|
/// States if the entry is disposed or not
|
||||||
|
/// </summary>
|
||||||
|
internal protected bool IsDisposed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="CameraFileEntry"/> class
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Ref"></param>
|
||||||
|
/// <param name="Name"></param>
|
||||||
|
/// <param name="IsFolder"></param>
|
||||||
|
/// <param name="IsVolume"></param>
|
||||||
|
internal protected CameraFileEntry(IntPtr Ref, string Name, bool IsFolder, bool IsVolume)
|
||||||
|
{
|
||||||
|
this.Ref = Ref;
|
||||||
|
this.Name = Name;
|
||||||
|
this.IsFolder = IsFolder;
|
||||||
|
this.IsVolume = IsVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Destructor
|
||||||
|
/// </summary>
|
||||||
|
~CameraFileEntry()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases this entry but not the subentries
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases this entry and all the subentries
|
||||||
|
/// </summary>
|
||||||
|
public void DisposeAll()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
if (Entries != null) for (int i = 0; i < Entries.Length; i++) Entries[i].DisposeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases this entry but not the subentries
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
|
||||||
|
protected virtual void Dispose(bool managed)
|
||||||
|
{
|
||||||
|
if (!IsDisposed)
|
||||||
|
{
|
||||||
|
if (managed) DisposeThumb();
|
||||||
|
if (Reference != IntPtr.Zero) CanonSDK.EdsRelease(Reference);
|
||||||
|
IsDisposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispose the thumbnail in an extension
|
||||||
|
/// </summary>
|
||||||
|
partial void DisposeThumb();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the thumbnail from a stream. The thumbnail depends on the image class you want to use.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The image stream</param>
|
||||||
|
internal protected virtual void SetThumb(IntPtr stream)
|
||||||
|
{
|
||||||
|
SetThumbSub(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the thumbnail
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The image stream</param>
|
||||||
|
partial void SetThumbSub(IntPtr stream);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="CameraFileEntry"/>s are equal to each other.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
|
||||||
|
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
|
||||||
|
/// <returns>True if the <see cref="CameraFileEntry"/>s are equal; otherwise, false</returns>
|
||||||
|
public static bool operator ==(CameraFileEntry x, CameraFileEntry y)
|
||||||
|
{
|
||||||
|
// If both are null, or both are same instance, return true.
|
||||||
|
if (object.ReferenceEquals(x, y)) return true;
|
||||||
|
|
||||||
|
// If one is null, but not both, return false.
|
||||||
|
if ((object)x == null || (object)y == null) return false;
|
||||||
|
|
||||||
|
return x.Reference == y.Reference;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="CameraFileEntry"/>s are unequal to each other.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The first <see cref="CameraFileEntry"/></param>
|
||||||
|
/// <param name="y">The second <see cref="CameraFileEntry"/></param>
|
||||||
|
/// <returns>True if the <see cref="CameraFileEntry"/>s are unequal; otherwise, false</returns>
|
||||||
|
public static bool operator !=(CameraFileEntry x, CameraFileEntry y)
|
||||||
|
{
|
||||||
|
return !(x == y);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The <see cref="object"/> to compare with the current <see cref="CameraFileEntry"/></param>
|
||||||
|
/// <returns>true if the specified <see cref="object"/> is equal to the current <see cref="CameraFileEntry"/>; otherwise, false.</returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
// If objects have different types, return false.
|
||||||
|
if (obj.GetType() != GetType()) return false;
|
||||||
|
|
||||||
|
// If both are null, or both are same instance, return true.
|
||||||
|
if (object.ReferenceEquals(this, obj)) return true;
|
||||||
|
|
||||||
|
CameraFileEntry cv = obj as CameraFileEntry;
|
||||||
|
if (cv == null) return false;
|
||||||
|
|
||||||
|
return Reference == cv.Reference;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Serves as a hash function for a <see cref="CameraFileEntry"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for the current <see cref="CameraFileEntry"/></returns>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Reference.ToInt64().GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A Stream encapsulating an unmanaged SDK Stream.
|
||||||
|
/// This class can be used to overcome the differences between SDK versions
|
||||||
|
/// </summary>
|
||||||
|
public class SDKStream : Stream
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports reading.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports seeking.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanSeek
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the current stream supports writing.
|
||||||
|
/// </summary>
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the length in bytes of the stream.
|
||||||
|
/// </summary>
|
||||||
|
public override long Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (CanonSDK.IsVerGE34)
|
||||||
|
{
|
||||||
|
long length;
|
||||||
|
CanonSDK.EdsGetLength(Reference, out length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
CanonSDK.EdsGetLength(Reference, out length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the position within the current stream.
|
||||||
|
/// </summary>
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (CanonSDK.IsVerGE34)
|
||||||
|
{
|
||||||
|
long position;
|
||||||
|
CanonSDK.EdsGetPosition(Reference, out position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int position;
|
||||||
|
CanonSDK.EdsGetPosition(Reference, out position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set { Seek(value, SeekOrigin.Begin); }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the underlying SDK stream
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Reference
|
||||||
|
{
|
||||||
|
get { return _Reference; }
|
||||||
|
protected set { _Reference = value; }
|
||||||
|
}
|
||||||
|
private IntPtr _Reference;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sdkStream">Pointer to the SDK stream</param>
|
||||||
|
public SDKStream(IntPtr sdkStream)
|
||||||
|
{
|
||||||
|
if (sdkStream == IntPtr.Zero) throw new ArgumentNullException(nameof(sdkStream));
|
||||||
|
Reference = sdkStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK file stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filepath">Path to the file</param>
|
||||||
|
/// <param name="createDisposition">State how to create the stream</param>
|
||||||
|
/// <param name="access">File access type</param>
|
||||||
|
public SDKStream(string filepath, FileCreateDisposition createDisposition, FileAccess access)
|
||||||
|
{
|
||||||
|
if (filepath == null) throw new ArgumentNullException(nameof(filepath));
|
||||||
|
ErrorHandler.CheckError(CanonSDK.EdsCreateFileStreamEx(filepath, createDisposition, access, out _Reference));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||||
|
/// This stream will resize itself if the current length is exceeded
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">Initial buffer size of the stream in bytes</param>
|
||||||
|
public SDKStream(long length)
|
||||||
|
{
|
||||||
|
ErrorCode err;
|
||||||
|
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStream(length, out _Reference);
|
||||||
|
else err = CanonSDK.EdsCreateMemoryStream((int)length, out _Reference);
|
||||||
|
ErrorHandler.CheckError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||||
|
/// Note that this stream will not resize itself
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">The memory buffer to use for the stream</param>
|
||||||
|
public SDKStream(byte[] buffer)
|
||||||
|
{
|
||||||
|
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
|
||||||
|
|
||||||
|
ErrorCode err;
|
||||||
|
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, buffer.LongLength, out _Reference);
|
||||||
|
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)buffer.LongLength, out _Reference);
|
||||||
|
ErrorHandler.CheckError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
|
||||||
|
/// Note that this stream will not resize itself
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">Pointer to the memory buffer to use for the stream</param>
|
||||||
|
/// <param name="length">The size of the memory buffer in bytes</param>
|
||||||
|
public SDKStream(IntPtr buffer, long length)
|
||||||
|
{
|
||||||
|
if (buffer == IntPtr.Zero) throw new ArgumentNullException(nameof(buffer));
|
||||||
|
|
||||||
|
ErrorCode err;
|
||||||
|
if (CanonSDK.IsVerGE34) err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, length, out _Reference);
|
||||||
|
else err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)length, out _Reference);
|
||||||
|
ErrorHandler.CheckError(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="SDKStream"/> class from an existing SDK stream.
|
||||||
|
/// Note that this calls <see cref="SDKStream(IntPtr)"/> internally and ignores all parameters but <paramref name="sdkStream"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">Pointer to the underlying SDK buffer. Ignored parameter</param>
|
||||||
|
/// <param name="sdkStream">Pointer to the SDK stream</param>
|
||||||
|
/// <param name="length">The size of the underlying SDK buffer in bytes. Ignored parameter</param>
|
||||||
|
[Obsolete("Not necessary anymore. Buffer and length is not used.")]
|
||||||
|
public SDKStream(IntPtr buffer, IntPtr sdkStream, long length)
|
||||||
|
: this(sdkStream)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all buffers for this stream and causes any buffered data to be
|
||||||
|
/// written to the underlying device.
|
||||||
|
/// This is not applicable to the SDK and therefore does nothing.
|
||||||
|
/// </summary>
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
//Nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a sequence of bytes from the current stream and advances the position
|
||||||
|
/// within the stream by the number of bytes read.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||||
|
/// byte array with the values between offset and (offset + count - 1) replaced by
|
||||||
|
/// the bytes read from the current source.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||||
|
/// from the current stream.</param>
|
||||||
|
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer. This can be less than the number
|
||||||
|
/// of bytes requested if that many bytes are not currently available, or zero (0)
|
||||||
|
/// if the end of the stream has been reached.</returns>
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
return (int)Read(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a sequence of bytes from the current stream and advances the position
|
||||||
|
/// within the stream by the number of bytes read.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
|
||||||
|
/// byte array with the values between offset and (offset + count - 1) replaced by
|
||||||
|
/// the bytes read from the current source.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
|
||||||
|
/// from the current stream.</param>
|
||||||
|
/// <param name="count">The maximum number of bytes to be read from the current stream.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer. This can be less than the number
|
||||||
|
/// of bytes requested if that many bytes are not currently available, or zero (0)
|
||||||
|
/// if the end of the stream has been reached.</returns>
|
||||||
|
public unsafe long Read(byte[] buffer, long offset, long count)
|
||||||
|
{
|
||||||
|
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
fixed (byte* bufferPtr = buffer)
|
||||||
|
{
|
||||||
|
byte* offsetBufferPtr = bufferPtr + offset;
|
||||||
|
|
||||||
|
if (CanonSDK.IsVerGE34)
|
||||||
|
{
|
||||||
|
long read;
|
||||||
|
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, count, (IntPtr)offsetBufferPtr, out read));
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, (int)count, (IntPtr)offsetBufferPtr, out read));
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the position within the current stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">A byte offset relative to the origin parameter.</param>
|
||||||
|
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current stream.</returns>
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
SDK.SeekOrigin sdkOrigin;
|
||||||
|
switch (origin)
|
||||||
|
{
|
||||||
|
case SeekOrigin.Begin:
|
||||||
|
sdkOrigin = SDK.SeekOrigin.Begin;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.Current:
|
||||||
|
sdkOrigin = SDK.SeekOrigin.Current;
|
||||||
|
break;
|
||||||
|
case SeekOrigin.End:
|
||||||
|
sdkOrigin = SDK.SeekOrigin.End;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("Not a valid enum value", nameof(origin));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CanonSDK.IsVerGE34) ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, offset, sdkOrigin));
|
||||||
|
else ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, (int)offset, sdkOrigin));
|
||||||
|
|
||||||
|
return Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Always throws a <see cref="NotSupportedException"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The desired length of the current stream in bytes.</param>
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a sequence of bytes to the current stream and advances
|
||||||
|
/// the current position within this stream by the number of bytes written.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
|
||||||
|
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
Write(buffer, (long)offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Writes a sequence of bytes to the current stream and advances
|
||||||
|
/// the current position within this stream by the number of bytes written.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream.</param>
|
||||||
|
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
|
||||||
|
/// <param name="count">The number of bytes to be written to the current stream.</param>
|
||||||
|
public unsafe void Write(byte[] buffer, long offset, long count)
|
||||||
|
{
|
||||||
|
if (buffer.LongLength < offset + count) throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
fixed (byte* bufferPtr = buffer)
|
||||||
|
{
|
||||||
|
byte* offsetBufferPtr = bufferPtr + offset;
|
||||||
|
|
||||||
|
if (CanonSDK.IsVerGE34)
|
||||||
|
{
|
||||||
|
long written;
|
||||||
|
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, count, (IntPtr)offsetBufferPtr, out written));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int written;
|
||||||
|
ErrorHandler.CheckError(CanonSDK.EdsWrite(_Reference, (int)count, (IntPtr)offsetBufferPtr, out written));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases the unmanaged resources used by the <see cref="SDKStream"/> and optionally
|
||||||
|
/// releases the managed resources.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true to release both managed and unmanaged resources;
|
||||||
|
/// false to release only unmanaged</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (_Reference != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
int err = CanonSDK.EdsRelease(_Reference);
|
||||||
|
Reference = IntPtr.Zero;
|
||||||
|
if (disposing) ErrorHandler.CheckError(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
324
src/CamBooth/EDSDKLib/API/Helper/STAThread.cs
Normal file
324
src/CamBooth/EDSDKLib/API/Helper/STAThread.cs
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This static class executes things on an STA thread and provides a method to create an STA thread
|
||||||
|
/// </summary>
|
||||||
|
public class STAThread
|
||||||
|
{
|
||||||
|
#region Variables
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Object that is used for the lock keyword to ensure only one SDK command is executed at a time
|
||||||
|
/// </summary>
|
||||||
|
public static readonly object ExecLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// States if the calling thread is in a Single Threaded Apartment or not
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsSTAThread
|
||||||
|
{
|
||||||
|
get { return Thread.CurrentThread.GetApartmentState() == ApartmentState.STA; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States if this thread is currently running
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRunning
|
||||||
|
{
|
||||||
|
get { return isRunning; }
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// ID of the associated thread
|
||||||
|
/// </summary>
|
||||||
|
public int ThreadID
|
||||||
|
{
|
||||||
|
get { return mainThread.ManagedThreadId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main thread where everything will be executed on
|
||||||
|
/// </summary>
|
||||||
|
private Thread mainThread;
|
||||||
|
/// <summary>
|
||||||
|
/// States if the execution thread is currently running
|
||||||
|
/// </summary>
|
||||||
|
private bool isRunning = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lock object to make sure only one command at a time is executed
|
||||||
|
/// </summary>
|
||||||
|
private object runLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// Lock object to ensure that an action executed on the thread does not invoke on itself
|
||||||
|
/// </summary>
|
||||||
|
private object cmdLock = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// Lock object to synchronize between execution and calling thread
|
||||||
|
/// </summary>
|
||||||
|
protected object threadLock1 = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// Lock object to synchronize between execution and calling thread
|
||||||
|
/// </summary>
|
||||||
|
private object threadLock2 = new object();
|
||||||
|
/// <summary>
|
||||||
|
/// States if the first lock is currently blocking or not
|
||||||
|
/// </summary>
|
||||||
|
protected bool block1 = true;
|
||||||
|
/// <summary>
|
||||||
|
/// States if the second lock is currently blocking or not
|
||||||
|
/// </summary>
|
||||||
|
private bool block2 = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The action to be executed
|
||||||
|
/// </summary>
|
||||||
|
private Action runAction;
|
||||||
|
/// <summary>
|
||||||
|
/// Storage for an exception that might have happened on the execution thread
|
||||||
|
/// </summary>
|
||||||
|
private Exception runException;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the <see cref="STAThread"/> class
|
||||||
|
/// </summary>
|
||||||
|
internal STAThread()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the execution loop
|
||||||
|
/// </summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
lock (runLock)
|
||||||
|
{
|
||||||
|
if (!isRunning)
|
||||||
|
{
|
||||||
|
mainThread = CreateThread(ExecutionLoop);
|
||||||
|
isRunning = true;
|
||||||
|
mainThread.Start();
|
||||||
|
WaitForThread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shuts down the execution loop and waits for it to finish
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
lock (runLock)
|
||||||
|
{
|
||||||
|
if (isRunning)
|
||||||
|
{
|
||||||
|
isRunning = false;
|
||||||
|
NotifyThread();
|
||||||
|
mainThread.Join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes an action on this STA thread
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">The action to execute</param>
|
||||||
|
/// <exception cref="ArgumentNullException">will be thrown if action is null</exception>
|
||||||
|
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
|
||||||
|
/// it will be rethrown as inner exception of this exception</exception>
|
||||||
|
public void Invoke(Action action)
|
||||||
|
{
|
||||||
|
if (action == null) throw new ArgumentNullException(nameof(action));
|
||||||
|
|
||||||
|
//If the method is called from the execution thread, directly execute it.
|
||||||
|
//This prevents possible deadlocks when trying to acquire the runLock while waiting within for the thread to finish.
|
||||||
|
if (Monitor.TryEnter(cmdLock))
|
||||||
|
{
|
||||||
|
try { action(); }
|
||||||
|
finally { Monitor.Exit(cmdLock); }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lock (runLock)
|
||||||
|
{
|
||||||
|
if (!isRunning) throw new InvalidOperationException("Thread is not running");
|
||||||
|
|
||||||
|
runAction = action;
|
||||||
|
NotifyThread();
|
||||||
|
WaitForThread();
|
||||||
|
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a function on this STA thread
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function to execute</param>
|
||||||
|
/// <returns>the return value of the function</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">will be thrown if func is null</exception>
|
||||||
|
/// <exception cref="ExecutionException">if an exception is thrown on the thread,
|
||||||
|
/// it will be rethrown as inner exception of this exception</exception>
|
||||||
|
public T Invoke<T>(Func<T> func)
|
||||||
|
{
|
||||||
|
if (func == null) throw new ArgumentNullException(nameof(func));
|
||||||
|
|
||||||
|
T result = default(T);
|
||||||
|
Invoke(delegate { result = func(); });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Static Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a thread in a Single Threaded Apartment
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">The command to run on this thread</param>
|
||||||
|
/// <returns>An STA thread</returns>
|
||||||
|
public static Thread CreateThread(Action action)
|
||||||
|
{
|
||||||
|
var thread = new Thread(new ThreadStart(action));
|
||||||
|
thread.SetApartmentState(ApartmentState.STA);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes an action on a newly created STA Thread
|
||||||
|
/// and optionally waits for it to finish executing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">The action to execute</param>
|
||||||
|
/// <param name="wait">If true, the action is executed synchronously or if false, asynchronously.</param>
|
||||||
|
public static void ExecuteThread(Action action, bool wait)
|
||||||
|
{
|
||||||
|
Exception runException = null;
|
||||||
|
Thread thread = CreateThread(delegate
|
||||||
|
{
|
||||||
|
try { action(); }
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (wait) runException = ex;
|
||||||
|
else throw;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
thread.Start();
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
thread.Join();
|
||||||
|
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a function on a newly created STA Thread
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="func">The function to execute</param>
|
||||||
|
/// <returns>The return value of the given function</returns>
|
||||||
|
public static T ExecuteThread<T>(Func<T> func)
|
||||||
|
{
|
||||||
|
Exception runException = null;
|
||||||
|
T result = default(T);
|
||||||
|
Thread thread = CreateThread(delegate
|
||||||
|
{
|
||||||
|
try { result = func(); }
|
||||||
|
catch (Exception ex) { runException = ex; }
|
||||||
|
});
|
||||||
|
thread.Start();
|
||||||
|
thread.Join();
|
||||||
|
if (runException != null) throw new ExecutionException(runException.Message, runException);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Subroutines
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notifies the execution loop to execute something
|
||||||
|
/// </summary>
|
||||||
|
private void NotifyThread()
|
||||||
|
{
|
||||||
|
lock (threadLock1)
|
||||||
|
{
|
||||||
|
block1 = false;
|
||||||
|
Monitor.Pulse(threadLock1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blocks until the execution loop is done with the work
|
||||||
|
/// </summary>
|
||||||
|
private void WaitForThread()
|
||||||
|
{
|
||||||
|
lock (threadLock2)
|
||||||
|
{
|
||||||
|
while (block2) Monitor.Wait(threadLock2);
|
||||||
|
block2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases the waiting <see cref="WaitForThread"/> method to continue
|
||||||
|
/// </summary>
|
||||||
|
private void ReleaseWait()
|
||||||
|
{
|
||||||
|
lock (threadLock2)
|
||||||
|
{
|
||||||
|
block2 = false;
|
||||||
|
Monitor.Pulse(threadLock2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The waiting routine on the execution loop
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void WaitForNotification()
|
||||||
|
{
|
||||||
|
lock (threadLock1)
|
||||||
|
{
|
||||||
|
while (block1 && isRunning) { Monitor.Wait(threadLock1); }
|
||||||
|
block1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The loop that is executed on the thread and where the work is done
|
||||||
|
/// </summary>
|
||||||
|
private void ExecutionLoop()
|
||||||
|
{
|
||||||
|
ReleaseWait();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (cmdLock)
|
||||||
|
{
|
||||||
|
while (isRunning)
|
||||||
|
{
|
||||||
|
WaitForNotification();
|
||||||
|
if (!isRunning) return;
|
||||||
|
|
||||||
|
runException = null;
|
||||||
|
try { lock (ExecLock) { runAction(); } }
|
||||||
|
catch (Exception ex) { runException = ex; }
|
||||||
|
|
||||||
|
ReleaseWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
isRunning = false;
|
||||||
|
ReleaseWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
788
src/CamBooth/EDSDKLib/API/Helper/ValueCollections.cs
Normal file
788
src/CamBooth/EDSDKLib/API/Helper/ValueCollections.cs
Normal file
@ -0,0 +1,788 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using EOSDigital.SDK;
|
||||||
|
|
||||||
|
namespace EOSDigital.API
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores CameraValues and provides methods to get those values. Abstract class.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int out of given possible values.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||||
|
/// <returns>The CameraValue with given uint representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value, List<CameraValue> Values)
|
||||||
|
{
|
||||||
|
var arr = Values.Where(t => t.IntValue == value).ToArray();
|
||||||
|
if (arr.Length == 0)
|
||||||
|
{
|
||||||
|
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
|
||||||
|
if (invalid != null) return invalid;
|
||||||
|
else throw new KeyNotFoundException("There is no CameraValue for this ID");
|
||||||
|
}
|
||||||
|
else { return arr[0]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string out of given possible values.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value, List<CameraValue> Values)
|
||||||
|
{
|
||||||
|
var arr = Values.Where(t => t.StringValue == value).ToArray();
|
||||||
|
if (arr.Length == 0)
|
||||||
|
{
|
||||||
|
var invalid = Values.FirstOrDefault(t => t.IntValue == unchecked((int)0xFFFFFFFF));
|
||||||
|
if (invalid != null) return invalid;
|
||||||
|
else throw new KeyNotFoundException("There is no CameraValue for this ID");
|
||||||
|
}
|
||||||
|
else { return arr[0]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double out of given possible values.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <param name="Values">Possible values that will be searched for the given value</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value, List<CameraValue> Values)
|
||||||
|
{
|
||||||
|
CameraValue[] sorted = Values.Distinct(new CameraValueComparer())
|
||||||
|
.Where(t => t.IntValue != unchecked((int)0xFFFFFFFF) && t != TvValues.Bulb && t != ISOValues.Auto)
|
||||||
|
.OrderBy(t => t.DoubleValue).ToArray();
|
||||||
|
|
||||||
|
for (int i = 0; i < sorted.Length; i++)
|
||||||
|
{
|
||||||
|
//Exact match:
|
||||||
|
if (Math.Abs(sorted[i].DoubleValue - value) <= 0.00000000001) return sorted[i];
|
||||||
|
else if (sorted[i].DoubleValue > value)
|
||||||
|
{
|
||||||
|
//Value is smaller than the range of given list. Return first:
|
||||||
|
if (i == 0) return sorted[i];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Select CameraValue closest to given value
|
||||||
|
double delta1 = value - sorted[i - 1].DoubleValue;
|
||||||
|
double delta = sorted[i].DoubleValue - value;
|
||||||
|
if (delta > delta1) return sorted[i - 1];
|
||||||
|
else return sorted[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Value is bigger than the range of given list. Return last:
|
||||||
|
return sorted[sorted.Length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Comparer for <see cref="CameraValue"/>s
|
||||||
|
/// </summary>
|
||||||
|
protected sealed class CameraValueComparer : IEqualityComparer<CameraValue>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="CameraValue"/>s are equal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The first <see cref="CameraValue"/></param>
|
||||||
|
/// <param name="y">The second <see cref="CameraValue"/></param>
|
||||||
|
/// <returns>true if the specified <see cref="CameraValue"/>s are equal; otherwise, false.</returns>
|
||||||
|
public bool Equals(CameraValue x, CameraValue y)
|
||||||
|
{
|
||||||
|
return x.Equals(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serves as a hash function for a <see cref="CameraValue"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for the current <see cref="CameraValue"/></returns>
|
||||||
|
public int GetHashCode(CameraValue obj)
|
||||||
|
{
|
||||||
|
return obj.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores Av Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AvValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Av <see cref="CameraValue"/> of the "Auto" or "None" setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Av);
|
||||||
|
/// <summary>
|
||||||
|
/// The Av <see cref="CameraValue"/> of an invalid setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Av);
|
||||||
|
|
||||||
|
static AvValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>()
|
||||||
|
{
|
||||||
|
Auto,
|
||||||
|
new CameraValue("1", 0x08, 1, PropertyID.Av),
|
||||||
|
new CameraValue("1.1", 0x0B, 1.1, PropertyID.Av),
|
||||||
|
new CameraValue("1.2", 0x0C, 1.2, PropertyID.Av),
|
||||||
|
new CameraValue("1.2 (1/3)", 0x0D, 1.2, PropertyID.Av),
|
||||||
|
new CameraValue("1.4", 0x10, 1.4, PropertyID.Av),
|
||||||
|
new CameraValue("1.6", 0x13, 1.6, PropertyID.Av),
|
||||||
|
new CameraValue("1.8", 0x14, 1.8, PropertyID.Av),
|
||||||
|
new CameraValue("1.8 (1/3)", 0x15, 1.8, PropertyID.Av),
|
||||||
|
new CameraValue("2", 0x18, 2, PropertyID.Av),
|
||||||
|
new CameraValue("2.2", 0x1B, 2.2, PropertyID.Av),
|
||||||
|
new CameraValue("2.5", 0x1C, 2.5, PropertyID.Av),
|
||||||
|
new CameraValue("2.5 (1/3)", 0x1D, 2.5, PropertyID.Av),
|
||||||
|
new CameraValue("2.8", 0x20, 2.8, PropertyID.Av),
|
||||||
|
new CameraValue("3.2", 0x23, 3.2, PropertyID.Av),
|
||||||
|
new CameraValue("3.5", 0x24, 3.5, PropertyID.Av),
|
||||||
|
new CameraValue("3.5 (1/3)", 0x25, 3.5, PropertyID.Av),
|
||||||
|
new CameraValue("4", 0x28, 4, PropertyID.Av),
|
||||||
|
new CameraValue("4.5", 0x2B, 4.5, PropertyID.Av),
|
||||||
|
new CameraValue("4.5 (1/3)", 0x2C, 4.5, PropertyID.Av),
|
||||||
|
new CameraValue("5.0", 0x2D, 5.0, PropertyID.Av),
|
||||||
|
new CameraValue("5.6", 0x30, 5.6, PropertyID.Av),
|
||||||
|
new CameraValue("6.3", 0x33, 6.3, PropertyID.Av),
|
||||||
|
new CameraValue("6.7", 0x34, 6.7, PropertyID.Av),
|
||||||
|
new CameraValue("7.1", 0x35, 7.1, PropertyID.Av),
|
||||||
|
new CameraValue("8", 0x38, 8, PropertyID.Av),
|
||||||
|
new CameraValue("9", 0x3B, 9, PropertyID.Av),
|
||||||
|
new CameraValue("9.5", 0x3C, 9.5, PropertyID.Av),
|
||||||
|
new CameraValue("10", 0x3D, 10, PropertyID.Av),
|
||||||
|
new CameraValue("11", 0x40, 11, PropertyID.Av),
|
||||||
|
new CameraValue("13 (1/3)", 0x43, 13, PropertyID.Av),
|
||||||
|
new CameraValue("13", 0x44, 13, PropertyID.Av),
|
||||||
|
new CameraValue("14", 0x45, 14, PropertyID.Av),
|
||||||
|
new CameraValue("16", 0x48, 16, PropertyID.Av),
|
||||||
|
new CameraValue("18", 0x4B, 18, PropertyID.Av),
|
||||||
|
new CameraValue("19", 0x4C, 19, PropertyID.Av),
|
||||||
|
new CameraValue("20", 0x4D, 20, PropertyID.Av),
|
||||||
|
new CameraValue("22", 0x50, 22, PropertyID.Av),
|
||||||
|
new CameraValue("25", 0x53, 25, PropertyID.Av),
|
||||||
|
new CameraValue("27", 0x54, 27, PropertyID.Av),
|
||||||
|
new CameraValue("29", 0x55, 29, PropertyID.Av),
|
||||||
|
new CameraValue("32", 0x58, 32, PropertyID.Av),
|
||||||
|
new CameraValue("36", 0x5B, 36, PropertyID.Av),
|
||||||
|
new CameraValue("38", 0x5C, 38, PropertyID.Av),
|
||||||
|
new CameraValue("40", 0x5D, 40, PropertyID.Av),
|
||||||
|
new CameraValue("45", 0x60, 45, PropertyID.Av),
|
||||||
|
new CameraValue("51", 0x63, 51, PropertyID.Av),
|
||||||
|
new CameraValue("54", 0x64, 54, PropertyID.Av),
|
||||||
|
new CameraValue("57", 0x65, 57, PropertyID.Av),
|
||||||
|
new CameraValue("64", 0x68, 64, PropertyID.Av),
|
||||||
|
new CameraValue("72", 0x6B, 72, PropertyID.Av),
|
||||||
|
new CameraValue("76", 0x6C, 76, PropertyID.Av),
|
||||||
|
new CameraValue("80", 0x6D, 80, PropertyID.Av),
|
||||||
|
new CameraValue("91", 0x70, 91, PropertyID.Av),
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores Tv Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class TvValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Tv <see cref="CameraValue"/> of the "Auto" setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Auto = new CameraValue("Auto", 0x00000000, 0, PropertyID.Tv);
|
||||||
|
/// <summary>
|
||||||
|
/// The Tv <see cref="CameraValue"/> of the "Bulb" setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Bulb = new CameraValue("Bulb", 0x0C, 0, PropertyID.Tv);
|
||||||
|
/// <summary>
|
||||||
|
/// The Tv <see cref="CameraValue"/> of an invalid setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.Tv);
|
||||||
|
|
||||||
|
static TvValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>()
|
||||||
|
{
|
||||||
|
Auto,
|
||||||
|
Bulb,
|
||||||
|
new CameraValue("30\"", 0x10, 30, PropertyID.Tv),
|
||||||
|
new CameraValue("25\"", 0x13, 25, PropertyID.Tv),
|
||||||
|
new CameraValue("20\"", 0x14, 20, PropertyID.Tv),
|
||||||
|
new CameraValue("20\" (1/3)", 0x15, 20, PropertyID.Tv),
|
||||||
|
new CameraValue("15\"", 0x18, 15, PropertyID.Tv),
|
||||||
|
new CameraValue("13\"", 0x1B, 13, PropertyID.Tv),
|
||||||
|
new CameraValue("10\"", 0x1C, 10, PropertyID.Tv),
|
||||||
|
new CameraValue("10\" (1/3)", 0x1D, 10, PropertyID.Tv),
|
||||||
|
new CameraValue("8\"", 0x20, 8, PropertyID.Tv),
|
||||||
|
new CameraValue("6\" (1/3)", 0x23, 6, PropertyID.Tv),
|
||||||
|
new CameraValue("6\"", 0x24, 6, PropertyID.Tv),
|
||||||
|
new CameraValue("5\"", 0x25, 5, PropertyID.Tv),
|
||||||
|
new CameraValue("4\"", 0x28, 4, PropertyID.Tv),
|
||||||
|
new CameraValue("3\"2", 0x2B, 3.2, PropertyID.Tv),
|
||||||
|
new CameraValue("3\"", 0x2C, 3, PropertyID.Tv),
|
||||||
|
new CameraValue("2\"5", 0x2D, 2.5, PropertyID.Tv),
|
||||||
|
new CameraValue("2\"", 0x30, 2, PropertyID.Tv),
|
||||||
|
new CameraValue("1\"6", 0x33, 1.6, PropertyID.Tv),
|
||||||
|
new CameraValue("1\"5", 0x34, 1.5, PropertyID.Tv),
|
||||||
|
new CameraValue("1\"3", 0x35, 1.3, PropertyID.Tv),
|
||||||
|
new CameraValue("1\"", 0x38, 1, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"8", 0x3B, 0.8, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"7", 0x3C, 0.7, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"6", 0x3D, 0.6, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"5", 0x40, 0.5, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"4", 0x43, 0.4, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"3", 0x44, 0.3, PropertyID.Tv),
|
||||||
|
new CameraValue("0\"3 (1/3)", 0x45, 0.3, PropertyID.Tv),
|
||||||
|
new CameraValue("1/4", 0x48, 1 / 4d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/5", 0x4B, 1 / 5d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/6", 0x4C, 1 / 6d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/6 (1/3)", 0x4D, 1 / 6d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/8", 0x50, 1 / 8d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/10 (1/3)", 0x53, 1 / 10d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/10", 0x54, 1 / 10d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/13", 0x55, 1 / 13d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/15", 0x58, 1 / 15d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/20 (1/3)", 0x5B, 1 / 20d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/20", 0x5C, 1 / 20d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/25", 0x5D, 1 / 25d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/30", 0x60, 1 / 30d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/40", 0x63, 1 / 40d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/45", 0x64, 1 / 45d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/50", 0x65, 1 / 50d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/60", 0x68, 1 / 60d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/80", 0x6B, 1 / 80d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/90", 0x6C, 1 / 90d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/100", 0x6D, 1 / 100d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/125", 0x70, 1 / 125d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/160", 0x73, 1 / 160d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/180", 0x74, 1 / 180d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/200", 0x75, 1 / 200d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/250", 0x78, 1 / 150d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/320", 0x7B, 1 / 320d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/350", 0x7C, 1 / 350d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/400", 0x7D, 1 / 400d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/500", 0x80, 1 / 500d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/640", 0x83, 1 / 640d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/750", 0x84, 1 / 750d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/800", 0x85, 1 / 800d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/1000", 0x88, 1 / 1000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/1250", 0x8B, 1 / 1250d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/1500", 0x8C, 1 / 1500d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/1600", 0x8D, 1 / 1600d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/2000", 0x90, 1 / 2000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/2500", 0x93, 1 / 2500d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/3000", 0x94, 1 / 3000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/3200", 0x95, 1 / 3200d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/4000", 0x98, 1 / 4000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/5000", 0x9B, 1 / 5000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/6000", 0x9C, 1 / 6000d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/6400", 0x9D, 1 / 6400d, PropertyID.Tv),
|
||||||
|
new CameraValue("1/8000", 0xA0, 1 / 8000d, PropertyID.Tv),
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores ISO Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ISOValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ISO <see cref="CameraValue"/> of the "Auto" setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Auto = new CameraValue("ISO Auto", 0x00000000, 0, PropertyID.ISO);
|
||||||
|
/// <summary>
|
||||||
|
/// The ISO <see cref="CameraValue"/> of an invalid setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ISO);
|
||||||
|
|
||||||
|
static ISOValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>()
|
||||||
|
{
|
||||||
|
Auto,
|
||||||
|
new CameraValue("ISO 50", 0x00000040, 50, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 100", 0x00000048, 100, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 125", 0x0000004b, 125, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 160", 0x0000004d, 160, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 200", 0x00000050, 200, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 250", 0x00000053, 250, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 320", 0x00000055, 320, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 400", 0x00000058, 400, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 500", 0x0000005b, 500, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 640", 0x0000005d, 640, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 800", 0x00000060, 800, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 1000", 0x00000063, 1000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 1250", 0x00000065, 1250, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 1600", 0x00000068, 1600, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 2000", 0x0000006b, 2000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 2500", 0x0000006d, 2500, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 3200", 0x00000070, 3200, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 4000", 0x00000073, 4000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 5000", 0x00000075, 5000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 6400", 0x00000078, 6400, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 8000", 0x0000007b, 8000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 10000", 0x0000007d, 10000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 12800", 0x00000080, 12800, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 16000", 0x00000083, 16000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 20000", 0x00000085, 20000, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 25600", 0x00000088, 25600, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 51200", 0x00000090, 51200, PropertyID.ISO),
|
||||||
|
new CameraValue("ISO 102400", 0x00000098, 102400, PropertyID.ISO),
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores Exposure Compensation Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ExpCompValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ExposureCompensation <see cref="CameraValue"/> of Zero
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Zero = new CameraValue("0", 0x00, 0, PropertyID.ExposureCompensation);
|
||||||
|
/// <summary>
|
||||||
|
/// The ExposureCompensation <see cref="CameraValue"/> of an invalid setting
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CameraValue Invalid = new CameraValue("N/A", unchecked((int)0xFFFFFFFF), 0, PropertyID.ExposureCompensation);
|
||||||
|
|
||||||
|
static ExpCompValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>()
|
||||||
|
{
|
||||||
|
new CameraValue("+5", 0x28, 5, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+4 2/3", 0x25, 4 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+4 1/2", 0x24, 4 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+4 1/3", 0x23, 4 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+4", 0x20, 4, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+3 2/3", 0x1D, 3 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+3 1/2", 0x1C, 3 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+3 1/3", 0x1B, 3 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+3", 0x18, 3, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+2 2/3", 0x15, 2 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+2 1/2", 0x14, 2 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+2 1/3", 0x13, 2 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+2", 0x10, 2, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1 2/3", 0x0D, 1 + (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1 1/2", 0x0C, 1 + (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1 1/3", 0x0B, 1 + (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1", 0x08, 1, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+2/3", 0x05, 2 / 3d, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1/2", 0x04, 1 / 2d, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("+1/3", 0x03, 1 / 3d, PropertyID.ExposureCompensation),
|
||||||
|
Zero,
|
||||||
|
new CameraValue("–1/3", 0xFD, -1 / 3d, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–1/2", 0xFC, -1 / 2d, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–2/3", 0xFB, -2 / 3d, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–1", 0xF8, -1, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–1 1/3", 0xF5, -1 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–1 1/2", 0xF4, -1 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–1 2/3", 0xF3, -1 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–2", 0xF0, -2, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–2 1/3", 0xED, -2 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–2 1/2", 0xEC, -2 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–2 2/3", 0xEB, -2 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("–3", 0xE8, -3, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-3 1/3", 0xE5, -3 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-3 1/2", 0xE4, -3 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-3 2/3", 0xE3, -3 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-4", 0xE0, -4, PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-4 1/3", 0xDD, -4 - (1 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-4 1/2", 0xDC, -4 - (1 / 2d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-4 2/3", 0xDB, -4 - (2 / 3d), PropertyID.ExposureCompensation),
|
||||||
|
new CameraValue("-5", 0xD8, -5, PropertyID.ExposureCompensation),
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores AE Mode Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AEModeValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
#pragma warning disable 1591
|
||||||
|
|
||||||
|
public static readonly CameraValue Program = new CameraValue("Program", 0, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Tv = new CameraValue("Tv", 1, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Av = new CameraValue("Av", 2, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Manual = new CameraValue("Manual", 3, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Bulb = new CameraValue("Bulb", 4, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue A_DEP = new CameraValue("A_DEP", 5, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue DEP = new CameraValue("DEP", 6, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Custom = new CameraValue("Custom", 7, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Lock = new CameraValue("Lock", 8, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Green = new CameraValue("Green", 9, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue NightPortrait = new CameraValue("NightPortrait", 10, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Sports = new CameraValue("Sports", 11, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Portrait = new CameraValue("Portrait", 12, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Landscape = new CameraValue("Landscape", 13, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Closeup = new CameraValue("Closeup", 14, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue FlashOff = new CameraValue("FlashOff", 15, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Custom2 = new CameraValue("Custom2", 16, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Custom3 = new CameraValue("Custom3", 17, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue CreativeAuto = new CameraValue("CreativeAuto", 19, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie = new CameraValue("Movie", 20, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue PhotoInMovie = new CameraValue("PhotoInMovie", 21, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue SceneIntelligentAuto = new CameraValue("SceneIntelligentAuto", 22, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Scene = new CameraValue("Scene", 25, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue NightScenes = new CameraValue("NightScenes", 23, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue BacklitScenes = new CameraValue("BacklitScenes", 24, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Children = new CameraValue("Children", 26, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Food = new CameraValue("Food", 27, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue CandlelightPortraits = new CameraValue("CandlelightPortraits", 28, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue CreativeFilter = new CameraValue("CreativeFilter", 29, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue RoughMonoChrome = new CameraValue("RoughMonoChrome", 30, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue SoftFocus = new CameraValue("SoftFocus", 31, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue ToyCamera = new CameraValue("ToyCamera", 32, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Fisheye = new CameraValue("Fisheye", 33, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue WaterColor = new CameraValue("WaterColor", 34, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Miniature = new CameraValue("Miniature", 35, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Hdr_Standard = new CameraValue("Hdr_Standard", 36, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Hdr_Vivid = new CameraValue("Hdr_Vivid", 37, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Hdr_Bold = new CameraValue("Hdr_Bold", 38, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Hdr_Embossed = new CameraValue("Hdr_Embossed", 39, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie_Fantasy = new CameraValue("Movie_Fantasy", 40, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie_Old = new CameraValue("Movie_Old", 41, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie_Memory = new CameraValue("Movie_Memory", 42, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie_DirectMono = new CameraValue("Movie_DirectMono", 43, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Movie_Mini = new CameraValue("Movie_Mini", 44, 0, PropertyID.AEMode);
|
||||||
|
public static readonly CameraValue Unknown = new CameraValue("Unknown", unchecked((int)0xFFFFFFFF), 0, PropertyID.AEMode);
|
||||||
|
|
||||||
|
#pragma warning restore 1591
|
||||||
|
|
||||||
|
static AEModeValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>();
|
||||||
|
values.Add(Program);
|
||||||
|
values.Add(Tv);
|
||||||
|
values.Add(Av);
|
||||||
|
values.Add(Manual);
|
||||||
|
values.Add(Bulb);
|
||||||
|
values.Add(A_DEP);
|
||||||
|
values.Add(DEP);
|
||||||
|
values.Add(Custom);
|
||||||
|
values.Add(Lock);
|
||||||
|
values.Add(Green);
|
||||||
|
values.Add(NightPortrait);
|
||||||
|
values.Add(Sports);
|
||||||
|
values.Add(Portrait);
|
||||||
|
values.Add(Landscape);
|
||||||
|
values.Add(Closeup);
|
||||||
|
values.Add(FlashOff);
|
||||||
|
values.Add(Custom2);
|
||||||
|
values.Add(Custom3);
|
||||||
|
values.Add(CreativeAuto);
|
||||||
|
values.Add(Movie);
|
||||||
|
values.Add(PhotoInMovie);
|
||||||
|
values.Add(SceneIntelligentAuto);
|
||||||
|
values.Add(Scene);
|
||||||
|
values.Add(NightScenes);
|
||||||
|
values.Add(BacklitScenes);
|
||||||
|
values.Add(Children);
|
||||||
|
values.Add(Food);
|
||||||
|
values.Add(CandlelightPortraits);
|
||||||
|
values.Add(CreativeFilter);
|
||||||
|
values.Add(RoughMonoChrome);
|
||||||
|
values.Add(SoftFocus);
|
||||||
|
values.Add(ToyCamera);
|
||||||
|
values.Add(Fisheye);
|
||||||
|
values.Add(WaterColor);
|
||||||
|
values.Add(Miniature);
|
||||||
|
values.Add(Hdr_Standard);
|
||||||
|
values.Add(Hdr_Vivid);
|
||||||
|
values.Add(Hdr_Bold);
|
||||||
|
values.Add(Hdr_Embossed);
|
||||||
|
values.Add(Movie_Fantasy);
|
||||||
|
values.Add(Movie_Old);
|
||||||
|
values.Add(Movie_Memory);
|
||||||
|
values.Add(Movie_DirectMono);
|
||||||
|
values.Add(Movie_Mini);
|
||||||
|
values.Add(Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores Metering Mode Values and provides methods to get those values
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MeteringModeValues : ValueBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All values for this property
|
||||||
|
/// </summary>
|
||||||
|
public static CameraValue[] Values { get { return values.ToArray(); } }
|
||||||
|
private static List<CameraValue> values;
|
||||||
|
|
||||||
|
#pragma warning disable 1591
|
||||||
|
|
||||||
|
public static readonly CameraValue Spot = new CameraValue("Spot", 1, 0, PropertyID.MeteringMode);
|
||||||
|
public static readonly CameraValue Evaluative = new CameraValue("Evaluative", 3, 0, PropertyID.MeteringMode);
|
||||||
|
public static readonly CameraValue Partial = new CameraValue("Partial", 4, 0, PropertyID.MeteringMode);
|
||||||
|
public static readonly CameraValue CenterWeightedAveraging = new CameraValue("Center-weighted averaging", 5, 0, PropertyID.MeteringMode);
|
||||||
|
public static readonly CameraValue NotValid = new CameraValue("Not valid", unchecked((int)0xFFFFFFFF), 0, PropertyID.MeteringMode);
|
||||||
|
|
||||||
|
#pragma warning restore 1591
|
||||||
|
|
||||||
|
static MeteringModeValues()
|
||||||
|
{
|
||||||
|
values = new List<CameraValue>();
|
||||||
|
values.Add(Spot);
|
||||||
|
values.Add(Evaluative);
|
||||||
|
values.Add(Partial);
|
||||||
|
values.Add(CenterWeightedAveraging);
|
||||||
|
values.Add(NotValid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from an int.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of the value to get</param>
|
||||||
|
/// <returns>The CameraValue with given int representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(int value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a string.
|
||||||
|
/// It has to be an exact match, otherwise an exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The ID of value to get</param>
|
||||||
|
/// <returns>The CameraValue with given string representation</returns>
|
||||||
|
/// <exception cref="KeyNotFoundException">No <see cref="CameraValue"/> for the given value</exception>
|
||||||
|
public static CameraValue GetValue(string value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the value from a double.
|
||||||
|
/// It searches for the closest representation and therefore might not return the exact input value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to get</param>
|
||||||
|
/// <returns>The CameraValue with given double representation</returns>
|
||||||
|
public static CameraValue GetValue(double value)
|
||||||
|
{
|
||||||
|
return GetValue(value, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
src/CamBooth/EDSDKLib/EDSDKLib.csproj
Normal file
65
src/CamBooth/EDSDKLib/EDSDKLib.csproj
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{15E99248-6161-46A4-9183-609CA62406A6}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>EDSDKLib</RootNamespace>
|
||||||
|
<AssemblyName>EDSDKLib</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<LangVersion>8</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<DocumentationFile>bin\Release\EDSDKLib.xml</DocumentationFile>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="API\Base\Camera.cs" />
|
||||||
|
<Compile Include="API\Base\CanonAPI.cs" />
|
||||||
|
<Compile Include="API\Helper\ApiThread.cs" />
|
||||||
|
<Compile Include="API\Helper\CameraValue.cs" />
|
||||||
|
<Compile Include="API\Helper\Delegates.cs" />
|
||||||
|
<Compile Include="API\Helper\ExceptionHandling.cs" />
|
||||||
|
<Compile Include="API\Helper\IO.cs" />
|
||||||
|
<Compile Include="API\Helper\STAThread.cs" />
|
||||||
|
<Compile Include="API\Helper\ValueCollections.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="SDK\SDKDelegates.cs" />
|
||||||
|
<Compile Include="SDK\SDKEnums.cs" />
|
||||||
|
<Compile Include="SDK\SDKMethods.cs" />
|
||||||
|
<Compile Include="SDK\SDKStructs.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
15
src/CamBooth/EDSDKLib/Properties/AssemblyInfo.cs
Normal file
15
src/CamBooth/EDSDKLib/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
[assembly: CLSCompliant(true)]
|
||||||
|
[assembly: AssemblyTitle("EDSDKLib")]
|
||||||
|
[assembly: AssemblyDescription("Canon SDK wrapper library")]
|
||||||
|
[assembly: AssemblyProduct("EDSDKLib")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © Johannes Bildstein 2016")]
|
||||||
|
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
[assembly: Guid("15e99248-6161-46a4-9183-609ca62406a6")]
|
||||||
|
|
||||||
|
[assembly: AssemblyVersion("1.1.1.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.1.1.0")]
|
||||||
44
src/CamBooth/EDSDKLib/SDK/SDKDelegates.cs
Normal file
44
src/CamBooth/EDSDKLib/SDK/SDKDelegates.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace EOSDigital.SDK
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for progress.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inPercent">The progress. A value between 0 and 100</param>
|
||||||
|
/// <param name="inContext">Reference to the object the progress is about</param>
|
||||||
|
/// <param name="outCancel">Pass true to cancel the underlying process</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public delegate ErrorCode SDKProgressCallback(int inPercent, IntPtr inContext, ref bool outCancel);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for property events.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inEvent">The property event ID</param>
|
||||||
|
/// <param name="inPropertyID">The property ID</param>
|
||||||
|
/// <param name="inParameter">A parameter for additional information</param>
|
||||||
|
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||||
|
/// <returns>Any of the SDK errors</returns>
|
||||||
|
public delegate ErrorCode SDKPropertyEventHandler(PropertyEventID inEvent, PropertyID inPropertyID, int inParameter, IntPtr inContext);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for object events.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inEvent">The object event ID</param>
|
||||||
|
/// <param name="inRef">A pointer to the object that has changed</param>
|
||||||
|
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||||
|
/// <returns>Any of the SDK errors</returns>
|
||||||
|
public delegate ErrorCode SDKObjectEventHandler(ObjectEventID inEvent, IntPtr inRef, IntPtr inContext);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate for state events.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inEvent">The state event ID</param>
|
||||||
|
/// <param name="inParameter">A parameter for additional information</param>
|
||||||
|
/// <param name="inContext">A reference to the object that has sent the event</param>
|
||||||
|
/// <returns>Any of the SDK errors</returns>
|
||||||
|
public delegate ErrorCode SDKStateEventHandler(StateEventID inEvent, int inParameter, IntPtr inContext);
|
||||||
|
/// <summary>
|
||||||
|
/// A delegate to inform of an added camera.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inContext">A reference to the added camera</param>
|
||||||
|
/// <returns>Any of the SDK errors</returns>
|
||||||
|
public delegate ErrorCode SDKCameraAddedHandler(IntPtr inContext);
|
||||||
|
}
|
||||||
1572
src/CamBooth/EDSDKLib/SDK/SDKEnums.cs
Normal file
1572
src/CamBooth/EDSDKLib/SDK/SDKEnums.cs
Normal file
File diff suppressed because it is too large
Load Diff
1521
src/CamBooth/EDSDKLib/SDK/SDKMethods.cs
Normal file
1521
src/CamBooth/EDSDKLib/SDK/SDKMethods.cs
Normal file
File diff suppressed because it is too large
Load Diff
1622
src/CamBooth/EDSDKLib/SDK/SDKStructs.cs
Normal file
1622
src/CamBooth/EDSDKLib/SDK/SDKStructs.cs
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user