# Which Image File Formats Support Tiled Storage vs Scanline Storage in OpenImageIO?

> Discover which image file formats support tiled storage in OpenImageIO. Learn about native tiled formats like TIFF and EXR versus scanline-only options.

- Repository: [Academy Software Foundation/openimageio](https://github.com/academysoftwarefoundation/openimageio)
- Tags: deep-dive
- Published: 2026-02-23

---

**OpenImageIO natively supports tiled storage in TIFF, OpenEXR, and IFF, while HEIF, AVIF, WebP, JPEG 2000, and JPEG XL declare tile support but emulate it through internal buffering; all other formats including PNG and JPEG are strictly scanline-only.**

OpenImageIO (OIIO) provides a unified `ImageOutput` interface for writing images, but not all file formats handle memory layout the same way. Understanding which image file formats support tiled storage versus scanline storage is critical for optimizing memory usage and I/O performance in high-resolution image processing pipelines. This guide examines the source code of the Academy SoftwareFoundation's OpenImageIO repository to identify exactly which formats advertise tile capabilities and how those capabilities are implemented.

## How OpenImageIO Determines Tile Support

OIIO abstracts format capabilities through the `ImageOutput::supports(string_view feature)` method. When the feature string is `"tiles"`, the method returns `true` if the format can write images with `ImageSpec.tile_width` and `tile_height` set to non-zero values. If the method returns `false`, the format only accepts scanline-oriented writes.

The following pattern demonstrates runtime detection:

```cpp
#include <OpenImageIO/imageio.h>
using namespace OIIO;

auto out = ImageOutput::create("output.tif");
ImageSpec spec (1920, 1080, 3);
spec.tile_width = 64;
spec.tile_height = 64;

if (!out->supports("tiles")) {
    // Fallback to scanline storage
    spec.tile_width = spec.tile_height = 0;
}
out->open("output.tif", spec);

```

## Formats with Native Tiled Storage Support

These formats implement true tiled I/O without requiring full-image buffering, as confirmed by their `supports` implementations in the OIIO source tree.

### TIFF

The TIFF writer in [`src/tiff.imageio/tiffoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/tiff.imageio/tiffoutput.cpp) (lines 362–367) explicitly declares tile support via `TIFFOutput::supports("tiles")`. This enables native tiled TIFF files compatible with the TIFF specification’s tile-based organization, allowing efficient random access to image regions.

### OpenEXR

Located in [`src/openexr.imageio/exroutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/openexr.imageio/exroutput.cpp) (lines 516–518), the `OpenEXROutput::supports` method returns `true` for tiles. OpenEXR supports both tiled and scanline modes natively, making it a preferred format for high-dynamic-range compositing workflows requiring arbitrary region access.

### IFF

The IFF writer ([`src/iff.imageio/iffoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/iff.imageio/iffoutput.cpp), lines 17–21) implements `IffOutput::supports("tiles")`, enabling native tiled storage for the IFF format used in legacy animation pipelines.

## Formats That Emulate Tiled Storage

Several formats declare tile support in their `supports` method but implement the actual write by buffering the entire image internally and then flushing it as scanlines. This behavior is documented in comments such as “emulate tiles” within the respective source files.

### HEIF and AVIF

The HEIF writer in [`src/heif.imageio/heifoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/heif.imageio/heifoutput.cpp) (lines 30–34) returns `true` for `supports("tiles")`. However, as noted in the source comments, the implementation emulates tiles by buffering the whole image before writing, since the underlying codec does not expose true tiled writing.

### JPEG 2000

In [`src/jpeg2000.imageio/jpeg2000output.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/jpeg2000.imageio/jpeg2000output.cpp) (lines 45–48), `Jpeg2000Output::supports` declares tile capability. The format supports tiled JP2/JPX natively in the codec, but OIIO’s implementation may buffer depending on the specific coding profile, with fallback to scanline emulation noted in the source.

### JPEG XL

The JPEG XL writer ([`src/jpegxl.imageio/jxloutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/jpegxl.imageio/jxloutput.cpp), lines 31–34) advertises tile support. Similar to HEIF, the actual write path may buffer the image to accommodate the format’s internal structure, effectively emulating tiles while exposing a tiled interface to the caller.

### WebP

Located in [`src/webp.imageio/webpoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/webp.imageio/webpoutput.cpp) (lines 55–58), the WebP writer declares tile support. The implementation notes indicate that while the API accepts tile parameters, the data is buffered and written as scanlines internally.

## Strictly Scanline-Only Formats

All remaining formats in the OpenImageIO distribution do not list `"tiles"` in their `supports` implementation, restricting them to scanline-only storage. These include:

- **PNG** ([`pngoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/pngoutput.cpp))
- **JPEG** ([`jpegoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/jpegoutput.cpp))
- **BMP** ([`bmpoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/bmpoutput.cpp))
- **GIF** ([`gifoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/gifoutput.cpp))
- **PNM** ([`pnmoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/pnmoutput.cpp))
- **SGI** ([`sgioutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/sgioutput.cpp))

When a caller attempts to configure tiled `ImageSpec` parameters for these formats, the writer either fails with an error (as in the SGI implementation) or silently ignores the tile dimensions, falling back to scanline writing. To avoid runtime errors, always verify `supports("tiles")` before setting non-zero `tile_width` or `tile_height`.

## Runtime Detection and Implementation Example

The following complete example demonstrates how to probe for tile support and conditionally write using the appropriate method:

```cpp
#include <OpenImageIO/imageio.h>
#include <iostream>

using namespace OIIO;

bool write_image(const char* filename, int w, int h, int ch, 
                 unsigned char* data, bool prefer_tiles) {
    auto out = ImageOutput::create(filename);
    if (!out) return false;

    ImageSpec spec(w, h, ch);
    
    // Request tiled storage if preferred and supported
    if (prefer_tiles && out->supports("tiles")) {
        spec.tile_width = 64;
        spec.tile_height = 64;
        std::cout << "Using tiled storage (64x64)\n";
    } else {
        spec.tile_width = spec.tile_height = 0;
        std::cout << "Using scanline storage\n";
    }

    if (!out->open(filename, spec)) return false;

    if (spec.tile_width) {
        // Write as tiles
        out->write_tiles(0, w, 0, h, 0, 1, TypeDesc::UINT8, data);
    } else {
        // Write as scanlines
        out->write_scanlines(0, h, 0, TypeDesc::UINT8, data);
    }
    
    out->close();
    return true;
}

```

## Summary

- **Native tiled storage** is available in TIFF, OpenEXR, IFF, JPEG 2000, JPEG XL, WebP, and HEIF/AVIF, though the latter four may buffer internally.
- **Scanline-only formats** include PNG, JPEG, BMP, GIF, PNM, and SGI; attempting to write tiles to these formats results in errors or silent fallback.
- **Runtime detection** relies on `ImageOutput::supports("tiles")`, which queries the specific writer implementation in files such as [`tiffoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/tiffoutput.cpp), [`exroutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/exroutput.cpp), and [`heifoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/heifoutput.cpp).
- **Implementation strategy** should always verify tile support before setting `ImageSpec` tile dimensions to ensure compatibility across the diverse format backends in the Academy Software Foundation's OpenImageIO repository.

## Frequently Asked Questions

### What is the difference between tiled and scanline storage in OpenImageIO?

**Tiled storage** organizes image data into rectangular blocks (typically 64×64 pixels) that can be read or written independently, enabling efficient random access for large images. **Scanline storage** processes the image one horizontal row at a time sequentially, which is memory-efficient for streaming but inefficient for accessing arbitrary regions. In OIIO, this distinction is controlled by setting `ImageSpec.tile_width` and `tile_height` to non-zero values for tiled mode.

### Can I force tiled storage on formats that only support scanlines?

No, you cannot force true tiled storage on strictly scanline-only formats such as PNG or JPEG. If you attempt to configure tile dimensions for these formats, OIIO will either return an error during `open()` or silently ignore the tile parameters and write scanlines. However, some formats like HEIF and WebP declare tile support in `supports("tiles")` but actually emulate tiling by buffering the entire image internally before writing scanline data.

### Which OpenImageIO formats support both tiled and scanline output?

TIFF and OpenEXR offer the most robust dual-mode support, natively handling both tiled and scanline storage without internal buffering. IFF also supports both modes natively. Formats like JPEG 2000, JPEG XL, WebP, and HEIF/AVIF technically support both through their OIIO writers, but they may buffer the full image when tiling is requested, effectively converting tile writes to scanline output internally.

### How do I check if a specific format supports tiled storage at runtime?

Call the `supports("tiles")` method on the `ImageOutput` instance before opening the file. This queries the format-specific implementation—such as `TIFFOutput::supports` in [`src/tiff.imageio/tiffoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/tiff.imageio/tiffoutput.cpp) or `HeifOutput::supports` in [`src/heif.imageio/heifoutput.cpp`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/heif.imageio/heifoutput.cpp)—to determine if the backend can handle non-zero `tile_width` and `tile_height` values. Always perform this check to ensure your code remains compatible across the diverse format plugins in the OpenImageIO distribution.