Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly

16 changes: 16 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## What changed

-

## Verification

- [ ] `msbuild SampleProject\UsbCameraSample.sln /m /p:Configuration=Debug /p:Platform="Any CPU"`
- [ ] `msbuild SampleProject\UsbCameraSample.sln /m /p:Configuration=Release /p:Platform="Any CPU"`
- [ ] `Tests\UsbCamera.Tests\bin\Debug\UsbCamera.Tests.exe`
- [ ] Camera-dependent behavior was tested manually or explicitly not touched

## Review focus

- [ ] `UsbCamera.cs` API behavior remains backward compatible
- [ ] Sample projects still build without external packages
- [ ] Generated `bin` / `obj` artifacts are not committed
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
push:
branches:
- master
- codex/add-github-actions-ci
pull_request:

jobs:
build-samples:
name: Build sample projects
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
configuration: [Debug, Release]

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up MSBuild
uses: microsoft/setup-msbuild@v2

- name: Build solution
run: msbuild SampleProject\UsbCameraSample.sln /m /p:Configuration=${{ matrix.configuration }} /p:Platform="Any CPU" /p:RestorePackages=false

- name: Run unit tests
run: Tests\UsbCamera.Tests\bin\${{ matrix.configuration }}\UsbCamera.Tests.exe
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Visual Studio build outputs
[Bb]in/
[Oo]bj/
.vs/
*.user
*.suo
*.rsuser

# Logs and generated diagnostics
*.log
*.binlog
TestResult.xml
[Tt]est[Rr]esult*/
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
C# source code for using usb camera and web camera in WinForms/WPF.
With only single CSharp source code. No external library required.

Sample projects are verified by GitHub Actions on every push and pull request.

# How to use
Add UsbCamera.cs to your project.
Following is how to use. see also [SampleProject](https://github.com/secile/UsbCamera/tree/master/SampleProject).
Expand Down
6 changes: 6 additions & 0 deletions SampleProject/UsbCameraSample.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsbCameraWpf", "UsbCameraWp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsbCameraByteArray", "UsbCameraByteArray\UsbCameraByteArray.csproj", "{B0F887EF-0F54-4176-9E3C-2BCB4B3C8667}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UsbCamera.Tests", "..\Tests\UsbCamera.Tests\UsbCamera.Tests.csproj", "{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -27,6 +29,10 @@ Global
{B0F887EF-0F54-4176-9E3C-2BCB4B3C8667}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0F887EF-0F54-4176-9E3C-2BCB4B3C8667}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0F887EF-0F54-4176-9E3C-2BCB4B3C8667}.Release|Any CPU.Build.0 = Release|Any CPU
{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
83 changes: 83 additions & 0 deletions Tests/UsbCamera.Tests/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using Camera = GitHub.secile.Video.UsbCamera;

namespace UsbCamera.Tests
{
internal static class Program
{
private static int Main()
{
try
{
Rgb24SetAndGetRoundTripsBottomUpCoordinates();
Y800SetAndGetRoundTripsTopDownCoordinates();
Y16SetAndGetRoundTripsCommonBitDepths();
VideoFormatDefaultHasStableLabel();
Console.WriteLine("All UsbCamera.Tests passed.");
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
return 1;
}
}

private static void Rgb24SetAndGetRoundTripsBottomUpCoordinates()
{
const int width = 2;
const int height = 2;
var buffer = new byte[width * height * 3];

Camera.ByteArrayUtility.RGB24.SetValue(buffer, width, height, 1, 0, 0x112233);

AssertEqual(0x112233, Camera.ByteArrayUtility.RGB24.GetValue(buffer, width, height, 1, 0), "RGB24 round trip");
AssertEqual(0x33, buffer[9], "RGB24 blue byte");
AssertEqual(0x22, buffer[10], "RGB24 green byte");
AssertEqual(0x11, buffer[11], "RGB24 red byte");
}

private static void Y800SetAndGetRoundTripsTopDownCoordinates()
{
const int width = 3;
const int height = 2;
var buffer = new byte[width * height];

Camera.ByteArrayUtility.Y800.SetValue(buffer, width, height, 2, 1, 0x7F);

AssertEqual(0x7F, Camera.ByteArrayUtility.Y800.GetValue(buffer, width, height, 2, 1), "Y800 round trip");
AssertEqual(0x7F, buffer[5], "Y800 buffer position");
}

private static void Y16SetAndGetRoundTripsCommonBitDepths()
{
VerifyY16RoundTrip(8, 0xAB);
VerifyY16RoundTrip(10, 0x02AA);
VerifyY16RoundTrip(12, 0x0ABC);
}

private static void VerifyY16RoundTrip(int bits, ushort value)
{
const int width = 2;
const int height = 2;
var buffer = new byte[width * height * 2];

Camera.ByteArrayUtility.Y16.SetValue(buffer, bits, width, height, 1, 1, value);

AssertEqual(value, Camera.ByteArrayUtility.Y16.GetValue(buffer, bits, width, height, 1, 1), "Y16 round trip " + bits);
}

private static void VideoFormatDefaultHasStableLabel()
{
AssertEqual("Default Video Format", Camera.VideoFormat.Default.ToString(), "VideoFormat default label");
}

private static void AssertEqual<T>(T expected, T actual, string name)
{
if (!object.Equals(expected, actual))
{
throw new InvalidOperationException(string.Format("{0}: expected {1}, got {2}", name, expected, actual));
}
}
}
}
49 changes: 49 additions & 0 deletions Tests/UsbCamera.Tests/UsbCamera.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" 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>{C9C7F432-6D25-43D8-86D6-04C6ED8CBB2D}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>UsbCamera.Tests</RootNamespace>
<AssemblyName>UsbCamera.Tests</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\UsbCamera.cs">
<Link>UsbCamera.cs</Link>
</Compile>
<Compile Include="Program.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>