Skip to content
Merged
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
18 changes: 12 additions & 6 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,16 @@
# treat as binary
###############################################################################
*.basis binary
*.a binary
*.dll binary
*.eot binary
*.dylib binary
*.exe binary
*.otf binary
*.pdf binary
*.ppt binary
*.pptx binary
*.pvr binary
*.so binary
*.snk binary
*.ttc binary
*.ttf binary
*.woff binary
*.woff2 binary
*.xls binary
*.xlsx binary
###############################################################################
Expand Down Expand Up @@ -144,3 +141,12 @@
# Handle ICC files by git lfs
###############################################################################
*.icc filter=lfs diff=lfs merge=lfs -text
###############################################################################
# Handle font files by git lfs
###############################################################################
*.eot filter=lfs diff=lfs merge=lfs -text
*.otf filter=lfs diff=lfs merge=lfs -text
*.ttc filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.woff filter=lfs diff=lfs merge=lfs -text
*.woff2 filter=lfs diff=lfs merge=lfs -text
3 changes: 3 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# GitHub Copilot Instructions

Read and follow [AGENTS.md](../AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Prefer existing local patterns and repository configuration whenever generated code or suggestions are accepted.
43 changes: 43 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Six Labors AI Coding Guidelines

These instructions apply to the entire repository. More-specific `AGENTS.md` files may add to or override them for their directory tree.

## Working Practices

- Inspect only the source and supporting files needed for the task before proposing or making changes. Do not infer current behavior when the source is available.
- Make the smallest complete change that solves the requested problem. Avoid unrelated cleanup, speculative abstractions, and formatting churn.
- Trace the existing execution path before changing it. Extend and optimize the existing implementation within the requested behavior and affected path.
- Before implementing an operation, find and inspect the existing APIs that provide it. Use or extend those APIs instead of writing equivalent logic elsewhere. This includes color conversion, pixel conversion, memory management, and vectorized operations. If an API lacks required behavior, improve its owning implementation rather than bypassing it with a separate implementation.
- Follow existing naming, formatting, documentation, and test patterns. Treat `.editorconfig`, analyzers, and repository build settings as authoritative.
- Use simple technical English in all communication, documentation, and comments. Use short sentences, active voice, and existing code terminology.
- Preserve public API and observable behavior unless the task explicitly requires a change. Public API documentation must describe observable behavior, not implementation details.
- Do not use reflection against built assemblies, ad hoc assembly loading, or temporary probe projects unless explicitly requested.
- Build .NET projects in Release configuration unless explicitly instructed otherwise.

## Performance

- Treat throughput, latency, memory use, and binary size as design constraints, especially in pixel-processing, drawing, parsing, encoding, and other hot paths.
- Avoid unnecessary allocations, copies, boxing, closures, interface dispatch, repeated enumeration, and extra passes over data.
- Reuse existing memory ownership, pooling, span, vectorization, and parallelization mechanisms.
- Use a SIMD-first design for suitable data processing code. Build on existing vectorized operations, dispatch mechanisms, and scalar fallbacks. Keep hot loops simple, hoist invariant work, and preserve memory locality.
- Preserve correctness and maintainability during optimization. Distinguish source-based reasoning from measured results. Claim a speedup only with measurements. Use existing benchmarks first. Add or update cases only when they measure relevant behavior that existing benchmarks miss.
- Consider all supported target frameworks and runtime capabilities. Do not regress fallback paths while optimizing newer runtimes.

## C# Conventions

- Follow local patterns when they comply with the explicit rules.
- Do not use `record` or `record struct` types.
- Prefer established invariants over redundant guards. Validate at real external boundaries and do not add defensive checks for internally controlled states.
- Do not extract single-use helpers merely to name a block. Extract only for genuine reuse, an established local pattern, or independently complex logic.
- Add vertical whitespace after multi-line statements and declarations and between distinct logical stages. Never add trailing whitespace.
- Document every added method, constructor, and property, regardless of visibility. Update documentation when a member's behavior or contract changes. Keep public API documentation limited to observable behavior. Use private and internal documentation to explain the contract and intent.
- Add inline comments that explain why complex code works. Explain algorithms, formulas, invariants, memory ownership, compatibility behavior, and performance decisions where they apply.
- For SIMD, explain lane layouts, operations, alignment, remainders, and scalar equivalence so an unfamiliar maintainer can follow the code.

## Verification

- Add or update tests only when they prove a required behavior or expose a real defect. Derive expectations from established contracts, explicit requirements, or defect evidence. Use source to identify contracts and integration points, not to copy implementation results into expectations. Prefer extending existing tests. Avoid redundant cases and assertions that merely repeat the implementation.
- Never weaken, skip, or bypass a valid test to make it pass. Fix the production defect or the genuine test defect. Replace or remove a test only with evidence that its expectation is invalid or its coverage is redundant.
- Do not update golden files, reference images, snapshots, baselines, or expected-output artifacts merely to silence a failure. Investigate mismatches. Update expected results only for an established requirement change or an incorrect reference result proved by independent contract or defect evidence.
- Test the actual behavior through the existing execution path. Synthetic inputs must exercise an established requirement or reproduce a real defect. Do not invent requirements or substitute internal structure and helper calls for assertions about required behavior. Run the narrowest relevant formatting, test, and Release build commands.
- Report what changed, the verification performed, and any remaining risks or unverified assumptions.
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Claude Code Instructions

Read and follow [AGENTS.md](AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Apply any more-specific `AGENTS.md` or `CLAUDE.md` found below the files being changed.
3 changes: 3 additions & 0 deletions GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Gemini CLI Instructions

Read and follow [AGENTS.md](AGENTS.md) as the repository-wide source of coding, performance, and verification requirements. Apply any more-specific `AGENTS.md` or `GEMINI.md` found below the files being changed.
21 changes: 14 additions & 7 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

## Supported Versions

Six Labors provides security fixes only for the latest major version of each library.
Six Labors provides security updates for the latest major version of each library.

Older major versions are end-of-life and do not receive security fixes.
Each major version remains eligible for security updates for 12 months after the first stable release of the next major version of that library.
After this period, that major version is end-of-life and does not receive security updates.

Users must upgrade to the latest major version to receive security fixes.
Users must install the latest available patch or minor release within a supported major version to receive security fixes.
Older releases within that major version are not maintained separately.

| Version | Supported |
| -------------------- | --------- |
| Latest major version | Yes |
| Older major versions | No |
| Version | Supported |
| ------- | --------- |
| Latest major version | Yes |
| Superseded major version within 12 months of the next major's first stable release | Yes |
| Superseded major version after that 12-month period | No |

Security updates may require a license key under the existing license terms. This does not change the license terms.

This policy covers security fixes only. It does not include feature backports or extend support for underlying .NET versions.

Security fixes, if any, are provided at Six Labors' discretion.

Expand Down
2 changes: 1 addition & 1 deletion src/ImageSharp.Textures/ImageSharp.Textures.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
<PackageReference Include="SixLabors.ImageSharp" Version="4.1.3" />
</ItemGroup>

<ItemGroup>
Expand Down
35 changes: 35 additions & 0 deletions src/ImageSharp.Textures/PixelFormats/AlphaConversion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Numerics;
using System.Runtime.CompilerServices;

namespace SixLabors.ImageSharp.Textures.PixelFormats;

internal static class AlphaConversion
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Premultiply(Vector4 vector)
{
float alpha = vector.W;
vector *= alpha;
vector.W = alpha;

return vector;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 UnPremultiply(Vector4 vector)
{
float alpha = vector.W;
if (alpha == 0F)
{
return Vector4.Zero;
}

vector /= alpha;
vector.W = alpha;

return vector;
}
}
73 changes: 56 additions & 17 deletions src/ImageSharp.Textures/PixelFormats/Ayuv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,59 +60,98 @@ public override readonly string ToString()

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public PixelOperations<Ayuv> CreatePixelOperations() => new();
public static PixelOperations<Ayuv> CreatePixelOperations() => new();

/// <inheritdoc />
public static PixelTypeInfo GetPixelTypeInfo()
=> PixelTypeInfo.Create<Ayuv>(
PixelComponentInfo.Create<Ayuv>(4, 8, 8, 8, 8),
PixelColorType.YCbCr | PixelColorType.Alpha,
PixelAlphaRepresentation.Unassociated);

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToAssociatedScaledVector4() => AlphaConversion.Premultiply(this.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToUnassociatedScaledVector4() => this.ToScaledVector4();

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToAssociatedVector4() => AlphaConversion.Premultiply(this.ToVector4());

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Vector4 ToUnassociatedVector4() => this.ToVector4();

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ayuv FromAssociatedScaledVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ayuv FromUnassociatedScaledVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ayuv FromAssociatedVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Ayuv FromUnassociatedVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override readonly int GetHashCode() => this.Yuv.GetHashCode();

/// <inheritdoc/>
public void FromArgb32(Argb32 source) => throw new NotImplementedException();
public static Ayuv FromArgb32(Argb32 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromBgr24(Bgr24 source) => throw new NotImplementedException();
public static Ayuv FromBgr24(Bgr24 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromBgra32(Bgra32 source) => throw new NotImplementedException();
public static Ayuv FromBgra32(Bgra32 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromAbgr32(Abgr32 source) => throw new NotImplementedException();
public static Ayuv FromAbgr32(Abgr32 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromBgra5551(Bgra5551 source) => throw new NotImplementedException();
public static Ayuv FromBgra5551(Bgra5551 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromL16(L16 source) => throw new NotImplementedException();
public static Ayuv FromL16(L16 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromL8(L8 source) => throw new NotImplementedException();
public static Ayuv FromL8(L8 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromLa16(La16 source) => throw new NotImplementedException();
public static Ayuv FromLa16(La16 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromLa32(La32 source) => throw new NotImplementedException();
public static Ayuv FromLa32(La32 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromRgb24(Rgb24 source) => throw new NotImplementedException();
public static Ayuv FromRgb24(Rgb24 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromRgb48(Rgb48 source) => throw new NotImplementedException();
public static Ayuv FromRgb48(Rgb48 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromRgba32(Rgba32 source) => throw new NotImplementedException();
public static Ayuv FromRgba32(Rgba32 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromRgba64(Rgba64 source) => throw new NotImplementedException();
public static Ayuv FromRgba64(Rgba64 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromScaledVector4(Vector4 vector) => throw new NotImplementedException();
public static Ayuv FromScaledVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void FromVector4(Vector4 vector) => throw new NotImplementedException();
public static Ayuv FromVector4(Vector4 source) => throw new NotImplementedException();

/// <inheritdoc/>
public void ToRgba32(ref Rgba32 dest) => throw new NotImplementedException();
public readonly Rgba32 ToRgba32() => Rgba32.FromScaledVector4(this.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Loading
Loading