# Display Window vs Pixel Data Window in OpenImageIO: A Complete Technical Guide

> Understand OpenImageIO's display window vs pixel data window. Learn how to manage image extents and pixel data for effective I/O and compositing. Enhance your workflows.

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

---

**The display window defines the logical canvas extents for presentation and compositing, while the pixel data window defines the actual region containing stored pixel values available for I/O operations.**

When working with professional image formats in the Academy Software Foundation's OpenImageIO (OIIO) library, understanding the distinction between the **display window and pixel data window** is essential for managing overscan, cropping, and multi-layer compositing workflows. Implemented in [`src/include/OpenImageIO/imageio.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/include/OpenImageIO/imageio.h) and managed through ROI utilities in [`src/include/OpenImageIO/imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/include/OpenImageIO/imagebuf.h), this dual-window architecture allows files to store minimal pixel data while preserving critical metadata about their placement within a larger logical frame.

## Defining the Two Windows

OpenImageIO maintains two distinct rectangular regions for every image, each serving different purposes in the imaging pipeline.

### Pixel Data Window (Data ROI)

The **pixel data window** (commonly called the *data window*) specifies the exact region containing actual stored pixel values. According to [`src/include/OpenImageIO/imageio.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/include/OpenImageIO/imageio.h) lines 63–74, this window is defined by the `ImageSpec` fields `x`, `y`, `z`, `width`, `height`, and `depth`. 

Helper functions `get_roi()` and `set_roi()` defined in [`src/include/OpenImageIO/imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/include/OpenImageIO/imagebuf.h) lines 43–56 convert these raw fields into an **ROI** (Region of Interest) struct. This window determines memory allocation boundaries, valid pixel coordinates, and I/O operations—only pixels within these bounds contain readable or writable data.

### Display Window (Full ROI)

The **display window** (also called the *full window*) represents the logical extents of the image as it should appear to viewers or compositors. Stored in `ImageSpec` fields `full_x`, `full_y`, `full_z`, `full_width`, `full_height`, and `full_depth` per [`imageio.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imageio.h) lines 63–74, this window may be larger than the data window (indicating overscan) or smaller (indicating a crop).

The functions `get_roi_full()` and `set_roi_full()` in [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h) lines 47–60 manage this window as an ROI. Compositors rely on these coordinates to position the image correctly within a larger canvas or film frame, regardless of how much pixel data is actually stored.

## Why Two Windows Matter

The separation between display and pixel data windows enables several professional workflows in visual effects and animation:

*   **Overscan:** The data window extends beyond the display window to provide extra pixels for edge filtering, motion blur, or lens distortion calculations.
*   **Cropping:** The data window is a subset of the display window, storing only a rendered region while preserving the original canvas size for later expansion.
*   **Tile-based Rendering:** Individual files may contain only specific tiles of a larger frame; the display window indicates where those tiles belong in the final composition.

All pixel-based operations (e.g., `ImageBuf::interppixel`) work in **pixel-data coordinates**, while normalized-device-coordinate (NDC) helpers such as `interppixel_NDC()` map the range **(0,0)–(1,1)** to the **display window** as documented in [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h) lines 80–86.

## Working with Windows in Code

The following examples demonstrate how to create, inspect, and manipulate both windows using the OIIO API according to the academysoftwarefoundation/openimageio source code.

### Creating an ImageSpec with Different Windows

To define an image with a cropped data window inside a larger display canvas:

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

ImageSpec spec;
spec.x = 100;                // data window origin
spec.y = 50;
spec.width  = 640;           // data window size
spec.height = 480;

spec.full_x = 0;             // display window origin (full canvas)
spec.full_y = 0;
spec.full_width  = 800;      // display window size (larger than data)
spec.full_height = 600;

// Verify the windows
ROI dataROI   = get_roi(spec);      // → (100,740) × (50,530)
ROI fullROI   = get_roi_full(spec); // → (0,800) × (0,600)

```

This creates a 640×480 pixel data region positioned at offset (100, 50) within an 800×600 logical display canvas.

### Reading Files and Inspecting Windows

When opening existing files, inspect both windows to understand the image structure:

```cpp
auto in = ImageInput::open("scene.exr");
if (!in) return;
const ImageSpec &spec = in->spec();

std::cout << "Data window:  " << spec.x << ", " << spec.y
          << "  size " << spec.width << "x" << spec.height << "\n";
std::cout << "Display window: " << spec.full_x << ", " << spec.full_y
          << "  size " << spec.full_width << "x" << spec.full_height << "\n";

```

As noted in [`imageio.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imageio.h) lines 38–44, formats such as OpenEXR often utilize this distinction to represent crop regions or overscan data where the stored pixels differ from the presentation bounds.

### Using NDC Coordinates Relative to the Display Window

Normalized coordinates map to the display window, not the data window:

```cpp
ImageBuf img("render.exr");   // automatically reads the data window
float pixel[4];
img.interppixel_NDC(0.5f, 0.5f, pixel);   // centre of the *display* window
std::cout << "Pixel at centre of display: "
          << pixel[0] << "," << pixel[1] << "," << pixel[2] << "\n";

```

According to [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h) lines 80–86, `interppixel_NDC` maps (0,0) to the upper-left of the **display** window and (1,1) to the lower-right, regardless of where the actual pixel data resides.

### Cropping While Preserving the Display Window

To extract only the valid pixel data while maintaining the original display metadata:

```cpp
ImageBuf src("scene.exr");
ImageBuf dst;
ImageBufAlgo::crop(dst, src, get_roi(src.spec()));
// dst now contains only the pixel data, but its full window
// is still the original display window (unchanged)

```

The `crop` operation defined in [`src/include/OpenImageIO/imagebufalgo.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/src/include/OpenImageIO/imagebufalgo.h) lines 475–482 operates on the **pixel-data ROI** and does not modify the display window, ensuring that compositing metadata remains intact for downstream processes.

## Summary

*   **Display window** (`full_x`, `full_y`, `full_width`, `full_height`): Defines the logical canvas size and presentation bounds; accessed via `get_roi_full()` in [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h).
*   **Pixel data window** (`x`, `y`, `width`, `height`): Defines the actual stored pixels and I/O boundaries; accessed via `get_roi()` in [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h).
*   **ROI utilities**: Helper functions in [`imagebuf.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebuf.h) lines 43–60 convert between `ImageSpec` integer fields and ROI structs for easier manipulation.
*   **NDC coordinates**: Methods like `interppixel_NDC()` use the display window as their coordinate reference, mapping (0,0)–(1,1) to the full window extents.
*   **Algorithm behavior**: Operations in [`imagebufalgo.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imagebufalgo.h) typically respect the separation, processing pixel data without altering display metadata unless explicitly requested.

## Frequently Asked Questions

### What happens if the display window and pixel data window are identical?

When both windows share the same dimensions and origin coordinates, the image contains valid data for every pixel in the display area with no overscan or cropping. This configuration is common in basic formats like PNG or JPEG, though professional formats like OpenEXR often utilize differing windows for advanced compositing workflows.

### How do I detect overscan in an OpenImageIO image?

Compare the ROI returned by `get_roi()` (pixel data) against `get_roi_full()` (display window). If the data window extends beyond the full window boundaries in any dimension, the image contains overscan. Conversely, if the data window is smaller, the image represents a crop of a larger canvas.

### Can I change the display window without modifying pixel values?

Yes. Use `set_roi_full()` on an `ImageSpec` or `ImageBuf` to update the logical canvas metadata without touching the actual pixel array. This is useful when repositioning a cropped render within a different compositing context while preserving the original pixel data intact.

### Which window determines memory allocation in ImageBuf?

Memory allocation is based strictly on the **pixel data window** dimensions returned by `get_roi()`. The display window only affects coordinate transformations and metadata; it does not influence how much memory is allocated for pixel storage, as defined in the `ImageSpec` field documentation in [`imageio.h`](https://github.com/academysoftwarefoundation/openimageio/blob/main/imageio.h).