Sdcb.SimdCodecs.Jpeg 1.2.0

Prefix Reserved
dotnet add package Sdcb.SimdCodecs.Jpeg --version 1.2.0
                    
NuGet\Install-Package Sdcb.SimdCodecs.Jpeg -Version 1.2.0
                    
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="Sdcb.SimdCodecs.Jpeg" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Sdcb.SimdCodecs.Jpeg" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Sdcb.SimdCodecs.Jpeg" />
                    
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 Sdcb.SimdCodecs.Jpeg --version 1.2.0
                    
#r "nuget: Sdcb.SimdCodecs.Jpeg, 1.2.0"
                    
#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 Sdcb.SimdCodecs.Jpeg@1.2.0
                    
#: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=Sdcb.SimdCodecs.Jpeg&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Sdcb.SimdCodecs.Jpeg&version=1.2.0
                    
Install as a Cake Tool

<img src="https://raw.githubusercontent.com/sdcb/SimdCodecs/main/assets/icon.png" width="64" align="right" alt="Sdcb.SimdCodecs icon">

Sdcb.SimdCodecs CI NuGet License: MIT

English | 简体中文

Pure-managed image codecs for .NET 10: JPEG, PNG, TIFF, WebP, GIF, BMP, ICO / CUR, QOI, Netpbm (PBM / PGM / PPM / PAM / PFM), JPEG 2000 and JBIG2, plus EXIF and ICC. No native dependencies, NativeAOT-compatible, and SIMD-accelerated (AVX2, SSE, AdvSimd) with a scalar fallback. The JPEG decoder is faster than libjpeg-turbo on the benchmark corpus.

JPEG, PNG, WebP, TIFF, JPEG 2000 and JBIG2 images, all decoded by Sdcb.SimdCodecs

<sub>Every tile above was decoded by this library; the files are the LINQPad samples' images (how they were made).</sub>

Quick start

dotnet add package Sdcb.SimdCodecs
using Sdcb.SimdCodecs;
using Sdcb.SimdCodecs.Abstractions;
using Sdcb.SimdCodecs.Jpeg;

byte[] file = File.ReadAllBytes("photo.webp");   // JPEG, PNG, TIFF, WebP, GIF, BMP, ICO, CUR, QOI, Netpbm, JPEG 2000 or JBIG2

// The facade sniffs the format from the magic bytes and decodes into a buffer you own (R G B A).
if (!SimdCodecs.TryReadInfo(file, out ImageInfo info)) throw new InvalidDataException("Not a supported image");
byte[] rgba = new byte[info.Width * info.Height * 4];
SimdCodecs.TryDecodeIntoRgba8(file, rgba);

// Encode it as a JPEG: SIMD, baseline / optimised Huffman / progressive, 4:2:0 or 4:4:4.
byte[] jpeg = JpegEncoder.Encode(rgba, info.Width, info.Height, channels: 4, new JpegEncodeOptions { Quality = 90 });
File.WriteAllBytes("photo.jpg", jpeg);

The rest of the facade:

  • SimdCodecs.TryDecodeInto(file, buffer, stride, format) — BGRA (Windows / WPF / Skia), RGB, BGR (OpenCV) or grey (OCR) straight into your buffer, at any row stride. JPEG and PNG write these natively, with no RGBA frame in between; a colour JPEG's grey is its Y plane.
  • SimdCodecs.TryDecode(file, out image) — the native layout: channel count (grey JPEG 1, colour JPEG 3), 8/16-bit or float samples, ICC profile.
  • SimdCodecs.TryReadInfo(file, out info) — from the headers alone: format, stored bit depth, EXIF orientation (reported, never applied), frame or page count.
  • SimdCodecs.DetectFormat(file) — also names formats it recognises but does not decode (HEIF, AVIF, JPEG XL, …); SimdCodecs.IsDecodable(format) tells the two apart.
  • SimdCodecs.TryOpenFrames(file, out reader) — every frame, by index, in any layout: animated WebP / GIF frames with durations, multi-page TIFF pages, the images of an icon (any other image is one frame). reader.EnumerateFramesInto(buffer, stride, format) plays them in order through one buffer.

Each format is also its own package with a richer API: scaled JPEG decoding, TIFF segment reads, WebP animation seeking by timestamp, Ultra HDR, and more.

Formats

Format Decode Encode Highlights
JPEG ✅ ✅ Decodes baseline and progressive DCT JPEG, any subsampling, CMYK / YCCK, scaled 1/2–1/8, zero-allocation DecodeTo; the separate LosslessJpeg.FromMemory API handles SOF3; encodes baseline / optimised Huffman / progressive with EXIF, XMP and ICC
Ultra HDR JPEG ✅ ✅ Gain-map read, assemble and HDR reconstruction (Ultra HDR / Adobe)
PNG ✅ ✅ All bit depths (1–16, indexed); text chunks; HDR signalling (cICP, mDCV, cLLI)
TIFF ✅ ✅ Multi-page; 8/16/32-bit integer and float; strips or tiles; reads Deflate, LZW, PackBits, CCITT G3/G4 and single tiles; writes Deflate
WebP ✅ — Lossy, lossless, alpha; animation with seeking; byte-exact with libwebp
GIF ✅ ✅ 87a / 89a: interlacing, transparency, every disposal method; animation with seeking; encodes stills and animations (exact palette, or Wu quantization + dithering)
BMP ✅ ✅ Every Windows and OS/2 variant: core to V5 headers, 1–32 bits, any channel masks, RLE4 / RLE8 / RLE24, OS/2 Huffman 1D, embedded PNG, ICC; SIMD rows into your buffer with no allocation; encodes palettes (exact or quantized), RLE, 555 / 565, 24 / 32-bit
ICO / CUR ✅ ✅ Every image of an icon or cursor, PNG or DIB with its AND mask, hotspots; multi-size encoding
QOI ✅ ✅ RGB and RGBA, from the specification; decodes into your buffer with no allocation; encodes to an array or a stream
Netpbm ✅ ✅ PBM, PGM, PPM plain and raw at any maximum up to 65535, PAM with 1–4 channels, PFM float; native 8/16-bit or float samples, or any layout into your buffer with no allocation; encodes every variant
JPEG 2000 ✅ — Part 1 (T.800), for PDF /JPXDecode
JBIG2 ✅ — T.88, for PDF /JBIG2Decode
EXIF ✅ ✅ From JPEG, TIFF, PNG and WebP; ExifWriter builds a block for the JPEG encoder
ICC profiles ✅ ✅ Decoders return embedded profiles; IccProfiles.Describe names one; bundled sRGB v4 profile; splice a profile into an existing JPEG

The table describes the individual format packages. The Sdcb.SimdCodecs facade intentionally exposes a narrower dispatch/display contract; for example, the separate LosslessJpeg.FromMemory API supports SOF3 directly, while JpegDecoder and the facade reject it. The other facade-specific limits are listed in docs/known-gaps.md (in Chinese).

Performance

Single-threaded, AMD Ryzen 7 5800X, .NET 10. Time relative to the native library (lower is faster):

JPEG decode to RGBA, 446 files Time Managed allocation per decode
libjpeg-turbo 3.2.0 (native) 1.00× —
Sdcb.SimdCodecs 0.82× 0 B
ImageSharp 3.1.12 1.77× about 16 KiB, plus its own image
WebP decode to RGBA, 1920×1080 lossy lossy + alpha lossless
libwebp 1.6.0 (native) 1.00× 1.00× 1.00×
Sdcb.SimdCodecs 0.88× 0.53× 0.72×
JPEG 2000 decode, 1600×1200 lossless (5/3) lossy (9/7, q=40) PSNR vs native
libopenjp2 2.5.4 (native) 1.00× (221 ms) 1.00× (49 ms) baseline
Sdcb.SimdCodecs 1.96× (433 ms) 2.03× (99 ms) Lossless Exact / Lossy 84 dB
BMP, 1920×1080, geometric mean decode (22 layouts) encode 24/32-bit to a stream (4)
WIC (Windows' native codec) 1.00× 1.00×
Sdcb.SimdCodecs 0.20× 0.08× from RGBA, 0.05× from BGR(A)
ImageSharp 3.1.12 1.62× 0.06×

BMP decoding writes into your buffer in any layout with no allocation and is pixel-for-pixel identical to WIC (apart from the documented decisions); every RLE, palette and mask layout decodes faster than both WIC and ImageSharp, and 5-6-5 and palette encoding are 2–6× faster than ImageSharp.

1920×1080, geometric mean vs. ImageSharp 3.1.12 decode encode to a stream
QOI (RGB, RGBA) 0.29× 0.49×
Netpbm (P1–P7, 8 and 16-bit, plain) 0.23× 0.54×

QOI and Netpbm decode into your buffer with no allocation; both match ImageMagick exactly, both ways.

The JPEG decoder is also at least as accurate as libjpeg-turbo's default (about 1 dB higher RGB PSNR against an exact reference where chroma is upsampled), and its output is bit-identical on AVX2, SSE, AdvSimd, scalar and NativeAOT. WebP output is byte-identical to libwebp. JPEG 2000 lossless decode is bit-identical to libopenjp2, and lossy decode achieves >84 dB PSNR. Full tables, corpora and methodology: JPEG, WebP, and JPEG 2000, BMP / ICO, QOI / Netpbm (on photo-like opaque lossy files WebP is on par: 0.87–1.13×; JPEG 2000 pure managed single-threaded decode is currently about 2× of libopenjp2).

Packages

All packages ship in lockstep under one version.

Package NuGet Contents
Sdcb.SimdCodecs NuGet Facade: sniffs the format and dispatches to the format decoders
Sdcb.SimdCodecs.Jpeg NuGet JPEG decoder and encoder
Sdcb.SimdCodecs.Jpeg.GainMap NuGet Ultra HDR / Adobe gain maps
Sdcb.SimdCodecs.Jpeg.IccInjector NuGet Splice an ICC profile into a JPEG
Sdcb.SimdCodecs.Png NuGet PNG decoder and encoder
Sdcb.SimdCodecs.Tiff NuGet TIFF reader and writer
Sdcb.SimdCodecs.Webp NuGet WebP decoder, including animation
Sdcb.SimdCodecs.Gif NuGet GIF decoder and encoder, including animation
Sdcb.SimdCodecs.Bmp NuGet BMP / DIB decoder and encoder
Sdcb.SimdCodecs.Ico NuGet ICO / CUR decoder and encoder
Sdcb.SimdCodecs.Qoi NuGet QOI decoder and encoder
Sdcb.SimdCodecs.Pnm NuGet Netpbm (PBM, PGM, PPM, PAM, PFM) decoder and encoder
Sdcb.SimdCodecs.Jpeg2000 NuGet JPEG 2000 decoder
Sdcb.SimdCodecs.Jbig2 NuGet JBIG2 decoder
Sdcb.SimdCodecs.Exif NuGet EXIF reader and writer
Sdcb.SimdCodecs.Color.Icc NuGet sRGB v4 ICC profile, cicp tag injector
Sdcb.SimdCodecs.Abstractions NuGet Shared types: IImageDecoder, RasterImage, ImagePixelFormat / PixelConverter, IImageFrameReader (frames and pages), H.273 colour vocabulary

<details> <summary>Feature details per package</summary>

  • Jpeg — T.81 decoder: baseline, progressive, restart intervals, any subsampling, grey / YCbCr / RGB / CMYK / YCCK, scaled 1/2–1/8 decode, lossless (SOF3). SIMD encoder: baseline, optimised Huffman or progressive; 4:4:4 / 4:2:0 / grey; embeds EXIF (APP1), XMP and an ICC profile (APP2).
  • Png — every standard bit depth (including 1/2/4-bit grey and indexed), tEXt / zTXt / iTXt text chunks, PNG-3 cICP / mDCV / cLLI HDR signalling.
  • Tiff — multi-page; 8/16/32-bit integer and float; Deflate / LZW (+ PackBits read); strips or tiles; chunky or planar; on-demand single strip or tile reads; reads 1/2/4-bit pages (expanded to 8-bit), CCITT fax (Group 3 1D/2D, Group 4, Modified Huffman) and the floating-point predictor.
  • Webp — RFC 6386 / RFC 9649: VP8 lossy, VP8L lossless, ALPH, animation with seek, ICC / EXIF / XMP. The facade's TryDecode returns a still or frame 0 of an animation, TryOpenFrames every frame; WebpAnimationDecoder adds seeking by timestamp and the frame rectangles.
  • Gif — GIF89a: global / local colour tables, interlacing, transparency, all disposal methods, NETSCAPE2.0 loop count; composited frames with seek. The decisions the spec leaves open are listed in the package README. Encoder: stills and animations, exact palettes or Wu quantization with optional Floyd–Steinberg dithering, changed-rectangle frames for opaque animations.
  • Bmp — the Windows DIB and OS/2 bitmap: core, OS/2 2.x, 40-byte, V2–V5 headers; 1/2/4/8-bit palettes and 16/24/32-bit; BI_BITFIELDS / BI_ALPHABITFIELDS; RLE4 / RLE8 with deltas, OS/2 RLE24 and Huffman 1D; BI_PNG; top-down rows; V5 ICC; packed DIBs (clipboard, icon images). Decodes into any ImagePixelFormat without allocating; checked pixel for pixel against WIC. The decisions the documentation leaves open are listed in the package README.
  • Ico — icons and cursors over Bmp and Png: every image, the largest and deepest by default, hotspots; encodes multi-size icons and cursors, each image PNG or a 1/4/8/24/32-bit DIB.
  • Qoi — the QOI specification: 3- and 4-channel images, the colour space reported (a linear one as a linear transfer); decodes into any ImagePixelFormat without allocating; encodes from RGBA, BGRA, RGB, BGR or grey.
  • Pnm — Netpbm: P1–P6 plain and raw at any maximum up to 65535 (16-bit samples above 255), PAM (P7) with 1–4 channels, PFM (Pf / PF) as float samples; only a file's first image. Encodes every format; plain output keeps lines within 70 characters. The decisions the format pages leave open are listed in the package README.
  • Exif — reads JPEG, TIFF, PNG and WebP; ExifWriter builds a blob for JpegEncodeOptions.Exif.

</details>

<details> <summary>Dependency graph</summary>

Sdcb.SimdCodecs (facade)
 ├─ Abstractions
 ├─ Png ──────────┬─ Color.Icc ─ Abstractions
 │                └─ Abstractions
 ├─ Tiff ─────────┬─ Png
 │                └─ Abstractions
 ├─ Jpeg ─────────── Abstractions
 ├─ Jpeg.GainMap ─┬─ Jpeg
 │                ├─ Color.Icc
 │                └─ Abstractions
 ├─ Jbig2 ────────── Abstractions
 ├─ Jpeg2000 ─────── Abstractions
 ├─ Webp ─────────── Abstractions
 ├─ Gif ──────────── Abstractions
 ├─ Bmp ──────────┬─ Png
 │                └─ Abstractions
 ├─ Ico ──────────┬─ Bmp
 │                ├─ Png
 │                └─ Abstractions
 ├─ Qoi ──────────── Abstractions
 └─ Pnm ──────────── Abstractions

Exif ─ Tiff        Jpeg.IccInjector (no dependencies)

The MQ arithmetic decoder (JBIG2, JPEG 2000), the T.4 fax code tables (JBIG2, TIFF, BMP), Wu's palette quantizer (GIF, BMP), the stream and array writers (QOI, Netpbm) and the EXIF orientation reader (JPEG, PNG, WebP) are shared as source (src/Shared), compiled into each package that uses them: no package uses another's internals.

</details>

LINQPad samples

Each package ships runnable samples in linqpad-samples/, which LINQPad lists in its NuGet browser (source: src/<package>/linqpad-samples/):

Package Samples
Sdcb.SimdCodecs quick-start, all-formats, skiasharp, opencvsharp
Sdcb.SimdCodecs.Jpeg encode (quality, subsampling, progressive, EXIF/XMP), scaled-decode
Sdcb.SimdCodecs.Jpeg.GainMap ultrahdr (write and read an Ultra HDR JPEG)
Sdcb.SimdCodecs.Png read-write
Sdcb.SimdCodecs.Tiff multi-page (incl. CCITT Group 4), float-and-tiles, write
Sdcb.SimdCodecs.Exif read-exif
Sdcb.SimdCodecs.Webp decode, animation
Sdcb.SimdCodecs.Gif decode, encode
Sdcb.SimdCodecs.Bmp bmp (every layout written, read back and compared)
Sdcb.SimdCodecs.Ico icons (a multi-size icon and a cursor, written and read back)
Sdcb.SimdCodecs.Qoi qoi (QOI against PNG on size and speed, decoding into a padded BGRA buffer)
Sdcb.SimdCodecs.Pnm netpbm (P1–P7 plain and raw, a hand-written PPM, 16-bit PGM, PFM)

They download their images from https://cv-public.sdcb.ai/simdcodecs/samples/v1/; how those were made and where they come from is in tools/sample-assets.

Build and test

dotnet build SimdCodecs.slnx -c Release
dotnet test  SimdCodecs.slnx -c Release

Oracle-backed tests skip when their reference tool is missing; set REQUIRE_ORACLES=1 to make a missing oracle fail instead (CI does). How to get each oracle is in AGENTS.md, which also holds the clean-room rules every contribution follows. Benchmarks are built on their own, by path: see benchmarks/README.md. Releasing: RELEASING.md.

Contact

WeChat group QR code

If the WeChat group is full or the QR code has expired, join the QQ group C#/.NET Computer Vision 579060605.

License

MIT — see LICENSE. Derived from SharpAstro/Codecs (released under the Unlicense).

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Sdcb.SimdCodecs.Jpeg:

Package Downloads
Sdcb.SimdCodecs

Image-codec facade over the Sdcb.SimdCodecs family: sniff a byte stream's format by its magic-byte signature and dispatch to the matching decoder (PNG, JPEG, TIFF, JBIG2, JPEG 2000, WebP, GIF, BMP, ICO, CUR, QOI, PBM / PGM / PPM / PAM, PFM), returning a codec-neutral IDecodedImage (fidelity tier: native bit depth + ColorEncoding colour signalling, with a ToFloats() RGBA float32 view) or decoding zero-copy into a caller-provided 8-bit RGBA buffer (display tier, integer-sample formats). AOT-compatible.

Sdcb.SimdCodecs.Jpeg.GainMap

Gain-map ("Ultra HDR") JPEG support: read, assemble, and generate Adobe hdrgm 1.0 / Android Ultra HDR v1 gain-map JPEGs (GContainer XMP + MPF, the form Chromium renders as HDR). Splices metadata around baseline JPEGs from any encoder (the IccInjector pattern), decodes both renditions via Sdcb.SimdCodecs.Jpeg, and reconstructs display-adaptive HDR linear floats. Pure-managed, AOT-compatible.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 0 10/30/2026
1.1.0 0 10/30/2026
1.0.1 52 10/29/2026