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

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 and managed through ROI utilities in 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 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 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 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 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 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:

#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:

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 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:

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 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:

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 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.
  • Pixel data window (x, y, width, height): Defines the actual stored pixels and I/O boundaries; accessed via get_roi() in imagebuf.h.
  • ROI utilities: Helper functions in 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →