OpenEXR

From Free net encyclopedia

OpenEXR is a high dynamic range imaging image file format, released as an open standard along with a set of software tools created by Industrial Light and Magic, released under an open source license similar to the BSD license.

It is notable for supporting 16-bits-per-channel floating point values (half precision), with a sign bit, five bits of exponent, and a ten-bit mantissa. This allows a dynamic range of over thirty stops of exposure, and is directly supported by the Cg programming language.

Lossless compression of high dynamic range data is also supported.

This article is a work in progress, thank you for your patience.

Contents

OpenEXR Overview

For a full technical introduction of OpenEXR, please see the Technical Introduction available on the OpenEXR.org website. A link to this document can be found in the External Links section.

OpenEXR, or simply EXR for short, is a deep raster format developed by ILM and very broadly used in the CG industry, both visual effects and animation.

OpenEXR's multi-resolution and arbitrary channel format makes it appealing for compositing. OpenEXR alleviates several painful elements of the compositing process. Since it can store arbitrary channels, specular, diffuse, alpha, RGB, normals, and various other types of channels in one file, it takes away the need store this information in separate files. The multi-channel concept also reduces the necessity to "bake" in the before mentioned data to the final image. If a compositer is not happy with the current level of specularity, he or she can adjust that specific channel.

OpenEXR's straight forward API also makes tools development a relative ease for developers. Since there's almost never two production pipelines that are the same, custom tools always needs to be developed to address problems in the production process. Many times these tools are to address some type of image manipulation issue. OpenEXR's library reduces the pain of having to manage bulky header information and allows quick and easy access to the image's attributes such as tiles and channels.

History

OpenEXR began life at ILM in 1999. In 2003, OpenEXR was released to the public.[5]

Credits

From OpenEXR.org's Technical Introduction:

The ILM OpenEXR file format was designed and implemented by Florian Kainz, Wojciech Jarosz, and Rod Bogart. The PIZ compression scheme is based on an algorithm by Christian Rouet. Josh Pines helped extend the PIZ algorithm for 16-bit and found optimizations for the float-to-half conversions. Drew Hess packaged and adapted ILM's internal source code for public release and maintains the OpenEXR software distribution. The PXR24 compression method is based on an algorithm written by Loren Carpenter at Pixar Animation Studios. [5]

OpenEXR Terminology

A list of terms and definitions related to OpenEXR in one form or another.

AOV

Arbitrary Output Variables. Usually corresponds to a channel.

Attribute(s)

Auxiliary data stored with the image.

Channel

Fundamental component of data stored in an image. In respect to OpenEXR, a channel stores specifically a type of data defined by the application. Common channels include the different color planes, RGB and sometimes A in an image. The name of the channel is set by the host application.

Each OpenEXR channel contains a name, data type, and separate x, y sampling rates.

There are four assumed predefined channels in OpenEXR: RGBA. There are no predefined channel names assigned to any other channel.[5]

Channel groups

There is no default mechanism for grouping channels. However, what seems to become an accepted convention is groupname.channelname. PRMan and Nuke, both, support this convention.

Some Nuke users have been overheard referring to channel groups as layers.

Color space

Color space.

Cropping

A smaller region of the original image defined by the values stored in the Data Window.

Refer to the Cropped Images section for an expanded discussion.

Cropping Images.

Data Window

A pair of integer coordinates (xmin, ymin) and (xmax, ymax) that specify the offsets, width, height, and area of the data contained in the image. Offset from the origin of the original image is (xmin, ymin).

 Width = (xmax-xmin)+1
 Height = (ymax-ymin)+1
 Area = width*height

The data window in an OpenEXR file can an arbitrary size. That is, it can be bigger, smaller, or equal to the size of the Display Window. In a cropped image, the Data Window fits the cropped region, while the Display Window remains the full size of the image.

The data window may or may not define the size of the image. In the case of a cropped image, it does not.

Display Window

Defines the upper/left and lower/right boundaries of the image. Stored as (xmin, ymin and (xmax, ymax).

 Width = (xmax-xmin)+1 
 Height = (ymax-ymin)+1. 

Usually (xmin, ymin) defines the upper/left origin of the image.

Float

32bit floating point data type. Conforms to the IEEE 754 floating-point number standard.[5]

NVIDIA's hardware also has support for a float format called S8E24.

Framebuffer

Half

16 bit floating point data type. Half the size of the IEEE single-precision floating-point format, this is "Half precision". It is composed of a sign bit, five bits of exponent, and a 10 bit mantissa.

Half is also a native data type in many shading languages, notably Cg. Half is also a native data size for various GPU hardware, most notably NVIDIA's line of Geforce chips.

Since there is no native format for a 16 bit float data type in C++, it is implemented as a class.

Also referred to as S5E10.

Houdini PIC

A deep raster format that shares some similarities to OpenEXR developed by SideFX Software Inc. Houdini PIC is a closed format and is used by SideFX products. Houdini PIC manipulation is handled via the HDK, Houdini Development Kit.

OdForce has further information on the Houdini PIC format.

Layers

The OpenEXR API does have minimal support for layer, specifically layer information. A layer is just a channel group, for instance, if there were three data channels with the name: AmbOcc.R, AmbOcc.G, AmbOcc.B. The layer name would be AmbOcc.

Keep in mind that the term "layer" here is different from the concept of a layer in applications such as Photoshop. There is no code to directly manipulate layers. Layers must be handled in terms of their channels.

RGBA

Red Green Blue Alpha.

RPF

Rich Pixel Format. A deep raster format developed by Discreet. RPF is based on the RLA format. RPF is used in Discreet products as well as products from Discreet's parent company, Autdodesk.

Information about the RPF format available in the 3D Studio Max SDK.

Scanline

A row of pixel data in an image.

Scanline.

Slice

As Channel is to Channel List, Slice is to FrameBuffer. A slice is the corresponding data structure to the channel where the actual data is held.

Softimage PIC

Softimage's own flavour of PIC.

See Paul Bourke's page on the Softimage PIC Format for more information.

Tile(s)

A tile is a rectangular subdivision of an image defined by a width and height. The entirety of the image is still defined by the data window. Tiling breaks up the data window into rectangular blocks.

If an image is tiled, the tiles are all of equal width and height. The right column and bottom of row of tiles may contain areas that are outside the data window. In this case, the tile's width and height still remains consistent with the other tiles. When the image data is written to disk, the empty area is simply discarded. The same applies for the bottom row of tiles.

Tiles are ordered in pairs of (x, y) going from left to right, then top to bottom. For example, if an image was subdivided into six tiles, 3x2, the tiles would be ordered: first row [0,0), (1,0), (2,0)], second row [(0,1), (1,1), (2,1)].

For a visual example, see page 6 of the OpenEXR's Technical Introduction.

UINT

Unsigned 32bit integer.[5] Most major hardware platforms, CPU and GPU have native support for unsigned 32bit integers. When a pixel is stored in 32bits, it stores four components at 8 bits each. The components are alpha, red, blue, green. The arrangements of the components can come in a variety of ways depending on specific needs. The two most comment arrangments are: RGBA and ARGB. Generally, speaking the endianess of the platform does not affect the ordering of the components. That is ARGB, with A being at the most significant end and B being at the least significant bit end will always be in that order regardless of the platform. However, their storage and arrangement in memory might be different.

Sometimes referred to as: uint32 or uint.

OpenEXR File Format

Data Types

OpenEXR supports three primitive data types: float, half, uint

float

32 bit floating-point number data type. Conforms to the IEEE 754 floating-point number standard. Useful for storing triplets or quadruplets of RGB or RGBA, respectively. On non grouped data, floats can also be used to store z-depth or 1/z depth. Other uses of triplets are normals, points, or various color space information. Two tuple uses include u, v or s, t coodinate information for applications that requiring such.

Nearly all hardware platforms that OpenEXR currently runs on has native support for 32 bit floats.

float is a primtive data type in C++.

half

16 bit floating-point data type. There are many advantages in using half to store image data over the standard 8 bit usngiend integer.

NVIDIA's Geforce line of GPUs has support for half.

half is not a primitive data type in C++, it is handled by means of a class called, half.

uint

32 bit integer.

unsigned int is the primitive data type in C++ corresponding to uint.

Note: When developing with OpenEXR on 64 bit platforms, it's wise to stick to one typedef that is known to be a 32 bit unsigned integer. Interchanging variable types could lead to alignment problems. int is not always 32 bits on every 64 bit platforms. A good practice is to consult the platform and compiler's documentation to verify primitive data types.

Header

Storage

OpenEXR Compression

OpenEXR supports serveral different types of compression, this is a list of compression methods as described in the OpenEXR Technical Introduction PDF.

PIZ

As stated in the Technical Introduction, the PIZ is a wavelet transformation applied to the pixel data. The result of that the transformation a Huffman encoding. PIZ has several somewhat unique characteristics: (1) data is compressed and uncompressed at roughly the same speed (2) works well for scan-line based files as well as tiles (3) small tiles do not shrink much in the compression and finally (4) images with film graim can be reduced down to somewhere between 35 and 55 percent of their uncompressed size. The previously stated is a rough paraphrase of the information provided by the Technical Introduction, please refer to it for a few more specific details. PIZ is lossless.

ZIP

Standard ZIP compression applied to data channels. OpenEXR relies on zlib to handle this compression method. The compression ratio is 45 to 55 of the original size. ZIP decompression is faster then PIZ. Like PIZ, ZIP is lossless.

The Technical Introduction states that for texture maps, ZIP is generally the best compression method.

RLE

Run Length Encoding. RLE is lossless. RLE is fast both in encoding and decoding. For images that have long spans of the same values, RLE is quite effective. RLE generally compresses down to 60 to 75 of its original size.

PXR24

A lossy compression format based on an algorithm by Loren Carpenter of Pixar.[5] PXR24 rounds a 32 bit float down to 24 bits.[5]

From the Technical Introduction:

After reducing 32-bit floating-point data to 24 bits by rounding, differences between horizontally adjacent pixels are compressed with zlib, similar to ZIP. PXR24 compression preserves image channels of type HALF and UINT exactly, but the relative error of FLOAT data increases to about 3×10-5. This compression method works well for depth buffers and similar images, where the possible range of values is very large, but where full 32-bit floating-point accuracy is not necessary. Rounding improves compression significantly by eliminating the pixels' 8 least significant bits, which tend to be very noisy, and difficult to compress.[5]

OpenEXR Usage Cases

Cropped Images

OpenEXR's flexibility in data storage allows for an image to be cropped down to smaller regions and stored in individual files without losing its offset information in the original image. The stored region is denoted by the Data Window in the OpenEXR file. Note that while cropped images shares some similar characteristics with tiled images, they are not quite the same thing. Given an image A, a series of images can be produced by cropping specific regions from A into a smaller subset of images. Generally, this subset of images is stored acrossed multiple files. Where as a tiled image is generally stored in the same file.

Why is cropping necessary?

There are many scenarios that cropping an image can be useful. There are other scenarios when cropping an image is necessary. Below is a brief discussion of a few scenarios.

Rendering High Resolution Images

When a very high resolution image is desired, it may be necessary to subdivide the render into different render regions. In this scenario, there is a possibility that the renderer may crash due to exhausted resources. When this happens, and if the renderer supports OpenEXR and region based rendering, the render can be broken down to a series of renders. Each so called sub-render handles a specific region of the image. The facilitation of sub-renders across multiple computers or on a single machine is left up to the discretion of the operator. Once all the sub-renders are completed, the final image is composited together using some compositing application to form the larger image.

This same scenario can apply to renders that require a large pixel sampling rate, such as 16x16.

Joining Cropped Images

The general idea behind joining images is allocating an image of the proper depth and size, then reading in the sequences of images that have been cropped. The data window, if used properly will prevent reading of images into an incorrect or overlapping location.

OpenEXR and HDRI

HDRI, by Reinhard et. al [7] has a brief discussion in the 3rd Chapter regarding the usage of OpenEXR in HDRI.

Luminance

OpenEXR in Production Environments

OpenEXR is used in a variety of different ways in a production environment. This section describes a small subset of possible uses.

OpenEXR and Rendering

OpenEXR is supported by rendering software by means of a plugin or a driver.

OpenEXR and Brazil

Splutterfish provides a plugin for their Brazil renderer to handle I/O for OpenEXR.

OpenEXR and Blender

Blenders Internal Renderer (CVS Version) can render to OpenEXR and Blender (CVS) can read and write OpenEXR and was used heavily in the production of Elephants Dream

OpenEXR and Houdini

As of version 7.0 Houdini is said to have OpenEXR I/O support.

Houdini's Mplay

Houdini's MPlay can handle viewing of OpenEXR images and playback of OpenEXR sequences. However, as of version 7.x only RGBA are supported.

OpenEXR and Mental Ray

As of version 3.3, mental ray supports OpenEXR for both texturing and image output.

OpenEXR and Renderman

This information is somewhat specific to PRMan. PRMan ships with an OpenEXR driver that allows it to render directly to an OpenEXR file. Other Renderman compliant renderers support various types of formats. A common one is TIFF. PRMan can also write out specific channels such as diffuse, specular, or normals to a separate file or as one file. This channel is specified in the RIB file.

OpenEXR and Compositing

Brief bits of information about compositing applications that support OpenEXR.

Nuke

D2's Nuke, a compositing application, directly supports OpenEXR.

Shake

Shake 4 supports both reading and writing of OpenEXR. Source code is available for a Shake 3.x plugin.

Blender

Blender (CVS) directly supports both reading and writing of OpenEXR

OpenEXR and General Image Processing

Only information on Photoshop is present right now.

Photoshop

Adobe Photoshop CS2 can read and write OpenEXR files. In addition, there is source code and binaries available on OpenEXR.org's for a Photoshop plugin.

Developing with OpenEXR

The information in this section is provided as of the 1.2.2 API. Later revision to the API will be added as it becomes available from OpenEXR.org.

The OpenEXR library is developed in C++ and is available in source format as well as compiled format for Windows and MacOS X. Careful attention was taken to ensure that OpenEXR easily compiles on almost any platform that supports C++.

Sample Code

Code snippets.

IlmImfExamples

The OpenEXR source comes with some example programs called IlmImfExamples. The examples are straight forward and cover everything from basic information queries to reading, writing, and even displaying OpenEXR images.

OpenEXR Interfaces

Generally speaking, there are two interfaces available for OpenEXR, tiled and scan-lined. However, a custom interface can be written to handle specific needs of the pipeline.

Channel Conversion: Float to Half

Data format conversion for OpenEXR is supported on the read, but not on the write. For instance, if you wish to convert a channel from float to half, the channel must be initialized with the type as half. That is, the desired channel would be declared in the header with half, and the frame buffer must be initialized with half. When readPixels is called, it will handle the conversion from half to float. The output file must be opened with the corresponding information as well.

Channel Conversion: Half to Float

Generally speaking, it works the same way as the Float to Half conversion process works - swap float and half accordingly.

OpenEXR Tools

exrtools has a wonderful collection of command line tools for manipulating OpenEXR images. exrtool's is developed Billy Biggs. Full source code is available.

External links