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
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,32 @@ codec.DctMethod = DctMethod.Float; // Faster encoding
var header = new FrameHeader(1920, 1080, 1920 * 3, PixelFormat.Rgb24, 1920 * 1080 * 3);
var frame = new FrameImage(header, rawPixelData);

byte[] jpegBuffer = new byte[header.Length];
int jpegLength = codec.Encode(frame, jpegBuffer);
using var jpeg = codec.EncodeRgb24(frame, quality: 90); // Encode() takes I420 or Gray8 only
```

### Rgb24 Decode/Encode

`Decode`/`Encode` work on Gray8 and I420. For packed Rgb24 (R, G, B) use the four `IJpegCodec` members below
(added in 1.5.0). **Breaking change for custom `IJpegCodec` implementations:** they must add these four members.

| Method | Result |
|--------|--------|
| `FrameHeader DecodeRgb24(ReadOnlyMemory<byte> jpeg, Memory<byte> output)` | Full-resolution Rgb24, stride = width * 3; output must hold width * height * 3 bytes |
| `FrameImage DecodeRgb24(ReadOnlyMemory<byte> jpeg)` | Same, buffer rented from `MemoryPool<byte>.Shared` (dispose it) |
| `int EncodeRgb24(in FrameImage frame, int quality, Memory<byte> output, JpegSubsampling subsampling = Ratio420)` | Baseline JPEG; returns bytes written |
| `FrameImage EncodeRgb24(in FrameImage frame, int quality, JpegSubsampling subsampling = Ratio420)` | Same, buffer rented from the shared pool (worst-case `tjBufSize` bound) |

- Decoding uses libjpeg-turbo's default (fancy) chroma upsampling; output is bit-identical to `djpeg -ppm`.
- Encoding uses `jpeg_set_defaults` + `jpeg_set_quality(quality, force_baseline)` and the integer DCT. The default
subsampling is libjpeg's default, 4:2:0 (`JpegSubsampling.Ratio420`); pass `JpegSubsampling.Ratio444` to keep
chroma at full resolution (sharp coloured edges, larger files). `FrameHeader.Stride` may include row padding.
- The Rgb24 calls are stateless native calls: they ignore the codec's `Quality`/`DctMethod` and are safe to call
concurrently on one `JpegCodec`.
- Errors: `InvalidOperationException` for undecodable data or a too-small output buffer; `ArgumentException` when the
frame data is shorter than `Stride * (Height - 1) + Width * 3`; `ArgumentOutOfRangeException` for quality outside 1-100.
- Platforms: the native Rgb24 entry points ship in the **linux-x64** `LibJpegWrap.so`. On linux-arm64 and win-x64 the
bundled binaries predate them, and the Rgb24 methods throw `NotSupportedException`.

---

## HDR Blending API
Expand Down Expand Up @@ -716,6 +738,15 @@ cmake --build build --config Release
### Dependencies

No external NuGet dependencies for JPEG codec - native binaries are bundled.
On Linux the bundled `LibJpegWrap.so` links `libjpeg.so.8` dynamically: install `libjpeg-turbo8` (Ubuntu/Debian).

The linux-x64 binary is built in an `ubuntu:22.04` container (glibc 2.35 baseline) against `libjpeg-turbo8-dev`:

```bash
docker run --rm -v $PWD/src/LibJpegWrap:/src:ro -v $PWD/out:/out ubuntu:22.04 bash -c \
'apt-get update && apt-get install -y g++ cmake libjpeg-turbo8-dev && cmake -S /src -B /b -DCMAKE_BUILD_TYPE=Release \
&& cmake --build /b && strip --strip-unneeded /b/libLibJpegWrap.so && cp /b/libLibJpegWrap.so /out/LibJpegWrap.so'
```

| Component | Purpose | Platforms |
|-----------|---------|-----------|
Expand Down
Loading
Loading