# Image Pipeline

This page walks through every step `GET /c/img/{path}` takes from request to response, and what happens when a step fails.

## Steps

| Step | Behavior | Implementation |
|---|---|---|
| 1. Parse parameters | Reads `s`/`size`, `w`/`width`, `h`/`height`, `q`/`quality`, `o`/`origin`, `d`/`dark`, `t`/`type`; the short name wins | `GetFromPath.ts` |
| 2. Map the original | Replaces `/c/img/` with `storage/image/upload/` and drops the query string | Same |
| 3. PDF / SVG | For `.pdf` / `.svg`, streams the original and stops | `streamFile()` |
| 4. Normalize format | `type` outside `jpeg`/`jpg`/`png`/`avif`/`webp` becomes `webp`; `jpeg` becomes `jpg` | Same |
| 5. Build cache path | Builds the cache filename from parameters; see [Caching Layers](/caching#local-cache-file-naming) | Same |
| 6. Original mode | With `o=1`, streams the original and stops | `streamFile()` |
| 7. Cache hit | Reads the cache file with `readFileSync` and returns it on success | Same |
| 8. Convert | sharp reads the original and its metadata, calls `resize()` per the [Sizing Rules](/api-reference-sizing), then encodes | sharp |
| 9. Respond and write | Sends the response first, then writes the cache file with `writeFileSync` | Same |

## Encoding

| Format | sharp call | Default quality | `Content-Type` |
|---|---|---|---|
| `webp` | `image.webp({ quality })` | `75` | `image/webp` |
| `avif` | `image.avif({ quality })` | `50` | `image/avif` |
| `jpg` | `image.jpeg({ quality })` | `75` | `image/jpeg` |
| `png` | `image.png()` | Not used | `image/png` |

Quality is `parseInt`-ed and clamped to `0`–`100`.

## Streaming Originals

`.pdf`, `.svg`, and `o=1` stream through `createReadStream` (8 KB `highWaterMark`) with `Transfer-Encoding: chunked`. For `o=1`, `Content-Type` follows the extension: `.jpg`/`.jpeg` → `image/jpeg`, `.png` → `image/png`, `.webp` → `image/webp`, otherwise `application/octet-stream`. A read error returns an empty `404`.

## Failure Handling

| Case | Response |
|---|---|
| Original missing | `storage/static/404-light.svg` (`404-dark.svg` with `d=1`), HTTP status `200` |
| sharp cannot decode or a parameter is invalid (e.g. `w=abc`) | Same |
| Response headers | `Content-Type: image/svg+xml`, `Cache-Control: no-cache`, `Expires: -1`, `Pragma: no-cache` |

## Related Pages

- Parameter list: [Image Parameters](/api-reference-image)
