# What Is the ImageDecoder Process in Ladybird?

> Discover the ImageDecoder process in Ladybird. Learn how this sandboxed helper safely decodes images, isolating codecs to prevent crashes and ensure a responsive browsing experience.

- Repository: [Ladybird/ladybird](https://github.com/LadybirdBrowser/ladybird)
- Tags: internals
- Published: 2026-03-05

---

**The ImageDecoder process in Ladybird is a sandboxed helper process that asynchronously decodes images via IPC, isolating complex native codec libraries from the browser's UI and web content to prevent crashes and maintain responsiveness.**

The Ladybird browser architecture isolates resource-intensive image parsing into a dedicated subprocess called the **ImageDecoder process**. By delegating work for formats like PNG, JPEG, and WebP to this separate entity, Ladybird ensures that decoding errors or security vulnerabilities in native libraries cannot compromise the main browser instance. This design leverages IPC communication and the existing LibGfx framework to provide robust, non-blocking image handling across all platforms.

## Why Ladybird Uses a Dedicated ImageDecoder Process

### Sandboxing and Stability

Decoding image formats involves complex native libraries that present security risks and crash hazards. The **ImageDecoder process** runs as an isolated IPC server, containing potential failures within its own memory space. If a malformed image triggers a crash in a codec library, only the helper process terminates, leaving the UI and web content processes unaffected.

### Asynchronous Performance

Image decoding is computationally expensive, particularly for large bitmaps or animated formats. By offloading this work to a separate process, Ladybird prevents the rendering thread from blocking. The **ImageDecoderClient** endpoints enable non-blocking requests, with results returned via `did_decode_image` or `did_decode_animation_frames` messages once processing completes.

### Decoder Reuse via LibGfx

Rather than implementing redundant parsers, the process leverages Ladybird's existing **LibGfx** framework. The server instantiates decoders using `ImageDecoder::try_create_for_raw_bytes` from [`Libraries/LibGfx/ImageFormats/ImageDecoder.h`](https://github.com/LadybirdBrowser/ladybird/blob/main/Libraries/LibGfx/ImageFormats/ImageDecoder.h), calling methods like `frame()`, `frame_duration()`, `cmyk_frame()`, and `vector_frame()` to extract data.

## Architecture and IPC Flow

The communication between client and server follows a strict request-response pattern:

1. A web content process or UI component sends raw image bytes and a unique request ID through the **ImageDecoderClient** IPC endpoint defined in `Services/ImageDecoder/ImageDecoderClient.ipc`.
2. The **ImageDecoderService**—running in its own process with a `LibIPC::SingleServer` and `Core::EventLoop`—receives the request.
3. The service creates a decoder instance and extracts frames, handling animations via `frame_duration()` loops.
4. The server responds with either `did_decode_image` (single-frame) or `did_decode_animation_frames` (animated), containing the bitmap sequence and metadata.

## Key Implementation Files

Several source files define the ImageDecoder process behavior:

- **[`UI/Android/src/main/cpp/ImageDecoderService.cpp`](https://github.com/LadybirdBrowser/ladybird/blob/main/UI/Android/src/main/cpp/ImageDecoderService.cpp)**: Implements the server entry point `service_main` and the main event loop for Android platforms.
- **`Services/ImageDecoder/ImageDecoderClient.ipc`**: Defines the IPC protocol and message types exchanged between clients and the decoder service.
- **[`Libraries/LibGfx/ImageFormats/ImageDecoder.h`](https://github.com/LadybirdBrowser/ladybird/blob/main/Libraries/LibGfx/ImageFormats/ImageDecoder.h)**: Provides the core decoding API, including `try_create_for_raw_bytes` and frame extraction methods.
- **[`UI/CMakeLists.txt`](https://github.com/LadybirdBrowser/ladybird/blob/main/UI/CMakeLists.txt)**: Declares "ImageDecoder" in the `ladybird_helper_processes` list, triggering process generation during builds.
- **[`UI/Android/src/main/java/org/serenityos/ladybird/ImageDecoderService.kt`](https://github.com/LadybirdBrowser/ladybird/blob/main/UI/Android/src/main/java/org/serenityos/ladybird/ImageDecoderService.kt)**: Java-side wrapper that loads the native `imagedecoderservice` library and binds the IPC socket.

## Code Example: Synchronous Decoding Inside the Process

Within the ImageDecoder process, decoding operates synchronously against the LibGfx API:

```cpp
// Inside ImageDecoderService.cpp
auto decoder = TRY(Gfx::ImageDecoder::try_create_for_raw_bytes(file->bytes()));
auto frame   = TRY(decoder->frame(0));               // first frame
auto bitmap  = frame.image;                         // NonnullRefPtr<Gfx::Bitmap>

```

This pattern executes within the sandboxed process, with the resulting bitmap data serialized back to the requesting client via IPC.

## Summary

- The **ImageDecoder process in Ladybird** isolates image parsing in a sandboxed subprocess to prevent crashes from affecting the main browser.
- Communication occurs via IPC through `ImageDecoderClient.ipc`, using async messages like `did_decode_image` and `did_decode_animation_frames`.
- The process reuses existing **LibGfx** decoders via `ImageDecoder::try_create_for_raw_bytes` and related frame methods.
- Key files include [`ImageDecoderService.cpp`](https://github.com/LadybirdBrowser/ladybird/blob/main/ImageDecoderService.cpp) for the server implementation and `ImageDecoderClient.ipc` for protocol definitions.

## Frequently Asked Questions

### What is the ImageDecoder process in Ladybird?

The ImageDecoder process is a dedicated helper subprocess that handles image decoding separately from the main browser UI. It runs as an IPC server using `LibIPC::SingleServer` and `Core::EventLoop`, decoding images asynchronously via the LibGfx library and returning bitmap data through IPC messages.

### Why does Ladybird decode images in a separate process?

Ladybird decodes images in a separate process primarily for **sandboxing and stability**. Isolating native codec libraries prevents security vulnerabilities and crashes from propagating to web content or UI processes. It also enables **asynchronous processing**, ensuring the rendering thread remains responsive during expensive decode operations.

### How does the ImageDecoder process communicate with the browser?

Communication occurs through IPC endpoints defined in `Services/ImageDecoder/ImageDecoderClient.ipc`. Clients send raw bytes with a request ID, and the server responds with `did_decode_image` for static images or `did_decode_animation_frames` for animations, transmitting the decoded bitmap sequences back to the requester.

### Which image formats does the ImageDecoder process support?

The process supports all formats implemented in Ladybird's **LibGfx** library, including PNG, JPEG, WebP, and others. The service creates appropriate decoders dynamically using `ImageDecoder::try_create_for_raw_bytes` from [`Libraries/LibGfx/ImageFormats/ImageDecoder.h`](https://github.com/LadybirdBrowser/ladybird/blob/main/Libraries/LibGfx/ImageFormats/ImageDecoder.h), which detects format types automatically from raw byte streams.