ArithmeticCoding 1.0.6

dotnet add package ArithmeticCoding --version 1.0.6
                    
NuGet\Install-Package ArithmeticCoding -Version 1.0.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ArithmeticCoding" Version="1.0.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ArithmeticCoding" Version="1.0.6" />
                    
Directory.Packages.props
<PackageReference Include="ArithmeticCoding" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ArithmeticCoding --version 1.0.6
                    
#r "nuget: ArithmeticCoding, 1.0.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ArithmeticCoding@1.0.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ArithmeticCoding&version=1.0.6
                    
Install as a Cake Addin
#tool nuget:?package=ArithmeticCoding&version=1.0.6
                    
Install as a Cake Tool

Arithmetic Coding for .NET

<img align="right" src="https://github.com/winscripter/ArithmeticCoding/blob/master/media/Logo/logo.png?raw=true" width="128" height="128">

ArithmeticCoding is a lightweight and fast library for .NET that simplifies implementation of arithmetically coded data found in codecs/file formats. It implements arithmetic decoding/encoding algorithms. It comes with:

  • An AV1 Symbol decoder
  • An H.263 SAC (Syntax-Based Arithmetic) decoder/encoder
  • An H.264 CABAC decoder
  • More upcoming

ArithmeticCoding on NuGet

It can do all of this in fully managed .NET - it does not rely on native dependencies, everything is written in C# code. Zero P/Invoke.

Arithmetic coding can be a very complex task. If you ever tried to write a file format or codec in C# or any other programming language, i.e. H.264, you know how hard it can be to implement arithmetic coding correctly and efficiently. This library aims to solve that problem by providing a simple and efficient API for arithmetic coding operations.

You'll need at least .NET Standard 2.0 or .NET Framework 4.6.1 to use this library. Modern versions, such as .NET 10.0, are also supported.

Getting started

To get started with ArithmeticCoding, you can install it via NuGet. Use the following command in the Package Manager Console:

dotnet add package ArithmeticCoding

Alternatively, if you use Visual Studio, you may do so by right-clicking on your project in the Solution Explorer, selecting "Manage NuGet Packages...", and searching for "ArithmeticCoding". Choose the package and click to Install it.

H.264

Here is an example of using the H.264 CABAC decoder. You'll need to implement IH264MacroblockProvider; see Implementing IH264MacroblockProvider. You should also implement IBitstreamReader, see Implementing IBitstreamReader. The slice type can be derived from the slice_type syntax element from the Slice Header (see clause 7.4.3 in the H.264 spec; table 7-6). The slice QP is defined with the QPY variable, which is specified in around at the bottom of clause 7.4.5 in the H.264 spec. Finally, codIOffset is read once during CABAC initialization right before reading the first syntax element, or, after all the cabac_alignment_one_bit bits.

using ArithmeticCoding;
using ArithmeticCoding.H264;

byte[] cabacData = { /* your CABAC encoded data */ };
IH264MacroblockProvider provider = new MyMacroblockProvider(); // Implement this interface to provide macroblock data

H264CabacSliceType sliceType = H264CabacSliceType.P; // Specify the slice type
int sliceQPy = 26; // Specify the slice QP

using var ms = new MemoryStream(cabacData);
IBitstreamReader bitstreamReader = new MyBitstreamReader(ms); // Implement this interface to read bits from the bitstream

int codIOffset = bitstreamReader.ReadBits(9); // Read the initial CABAC offset from the bitstream. (Do this right after reading all the necessary cabac_init bits)

H264CabacDecoder decoder = new H264CabacDecoder(sliceType, sliceQPy, provider, codIOffset, bitstreamReader);

I know... setup can be a bit involved, but once you have everything in place, using the decoder is super straightforward.

Here is an example of reading the mb_skip_flag syntax element:

bool mbSkipFlag = decoder.DecodeSkipFlag();

That's... pretty much it! You can now use the decoder to read other syntax elements as needed.

Here's another example with coded_block_pattern:

int codedBlockPattern = decoder.DecodeCodedBlockPattern();

Yep... like I said, super straightforward. 👍

Now, a few syntax elements do require a few input parameters in order to decode them. For instance, you need to provide the decoder the value of mbPartIdx and subMbPartIdx to decode mvd_l0 or mvd_l1, as you can see here:

decoder.MacroblockPartitionIndex = 1; // Example (mbPartIdx)
decoder.SubMacroblockPartitionIndex = 2; // Example (subMbPartIdx)

int mvdL0 = decoder.DecodeMotionVectorDifferenceL0(); // Reading mvd_l0

In Visual Studio, if you hover over methods starting with Decode, say, DecodeSkipFlag(), you'll see documentation regarding what syntax element that method decodes. But if that Decode method requires input parameters, like DecodeMotionVectorDifferenceL0, documentation actually states which properties you'll need to set up before you call the Decode method.

Example with mvd_lX (requires mbPartIdx, subMbPartIdx):

mvd_l0 XML Documentation

Example with mb_skip_flag (no prior setup required):

mb_skip_flag XML Documentation

To obtain input values:

  • MacroblockPartitionIndex and SubMacroblockPartitionIndex map into variables mbPartIdx and subMbPartIdx, respectively. Their assignment is specified directly in clause 7.3.5.1 and 7.3.5.2 in the H.264 spec. Also, to decode mvd_l0, mvd_l1, ref_idx_l0, or ref_idx_l1: if you're parsing mb_pred(), you only have to provide mbPartIdx. And if you're parsing sub_mb_pred(), you have to provide mbPartIdx and subMbPartIdx. subMbPartIdx, when parsing mb_pred(), can be 0.
  • ResidualBlockKind is an enum that represents the current residual transform coefficient block that you're parsing, in residual(startIdx, endIdx). Think Intra16x16DCLevel, LumaLevel8x8, CbIntra16x16ACLevel, you name it.
  • LevelListIndex is the index of the transform coefficient level inside of a block. For instance, in residual_block_cabac, it is the index that you're using to assign to coeffLevel.
  • NumC8x8 is assigned in clause 7.3.5.3 in the H.264 spec. If ChromaArrayType is not 1 or 2, its value can be left as 0.
  • NumDecodedAbsLevelGreaterThan1 and NumDecodedAbsLevelEqualTo1 is the total number of coefficients in coeffLevel in residual_block_cabac whose values are > 1 and == 1, respectively.

H.263

Import the namespace:

using ArithmeticCoding.H263;

H.263 uses what's known as a Syntax-Based Arithmetic (SAC) coder. It relies on cumulative frequencies for decoding symbols. Before we get started, you'll need to implement the IH263PscFifo interface which implements a Picture Start Code (PSC) First-in First-out (FIFO). See Implementing IH263PscFifo.

IH263PscFifo pscFifo = ...; // <-- Implement

Let's start with the decoder.

H263SyntaxBasedArithmeticDecoder sacDecoder = new();

int lumaCodedBlockPattern = sacDecoder.DecodeSymbol(
	H263SyntaxBasedArithmeticModels.CbpY, pscFifo);

// Async is also supported
int asyncLumaCodedBlockPattern = await sacDecoder.DecodeSymbolAsync(
	H263SyntaxBasedArithmeticModels.CbpY.ToArray(), pscFifo);

The encoder part is also very simple.

H263SyntaxBasedArithmeticEncoder sacEncoder = new();

const int index = 4; // example index
sacEncoder.EncodeSymbol(index, H263SyntaxBasedArithmeticModels.CbpY, pscFifo);

// Async is also supported
await sacEncoder.EncodeSymbolAsync(index, H263SyntaxBasedArithmeticModels.CbpY.ToArray(), pscFifo);

AV1

Currently, ArithmeticCoding includes an AV1 Symbol Decoder. For comprehensive AV1 entropy coding support, Symbol Encoding/CDF support may be introduced in future versions. For now, here's how to use the symbol decoder.

disable_cdf_update is a syntax element. sz is the input parameter for the initialization process.

using ArithmeticCoding.Av1;

IBitstreamReader bitstreamReader = ...; // <-- Implement
const int sz = 10; // <-- Implement
const bool disable_cdf_update = false; // <-- Implement

var symbolDecoder = new Av1SymbolDecoder(
	bitstreamReader, sz, disable_cdf_update);

This will immediately read a few bits off of the bit-stream. This is necessary for proper initialization.

You can now use this to read AV1 bools, literals or symbols, as follows.

int boolean = symbolDecoder.ReadBooleanAsInt32();
int literal = symbolDecoder.ReadLiteral(5);
int customSymbol = symbolDecoder.ReadSymbol(provide CDF here);

Powers

Use of this library makes manual .NET implementations (remember, C#, VB.NET and even F#) of supported file formats and codecs that include arithmetically coded data significantly easier and faster to implement.

The license is very permissive (MIT License), so you can use this library in both open-source and commercial projects without worrying about licensing issues.

It is also greatly optimized for performance, so you can expect efficient arithmetic coding operations.

Got any questions?

You're more than welcome to ask for help through the GitHub Issues page.

In GitHub Issues, you can report bugs, request features, or seek assistance with using the library.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.6 28 12/31/2025
1.0.5 35 12/30/2025
1.0.4 169 12/25/2025
1.0.3 163 12/24/2025
1.0.2 163 12/24/2025
1.0.1 161 12/24/2025
1.0.0 163 12/24/2025