Blame IlmImfUtil/README

Packit Service 6754ca
The IlmImfUtil Library
Packit Service 6754ca
----------------------
Packit Service 6754ca
Packit Service 6754ca
The IlmImfUtil library implements an in-memory image data structure, as
Packit Service 6754ca
well as simple function calls for saving images in OpenEXR files, and for
Packit Service 6754ca
constructing images from the contents of existing OpenEXR files.
Packit Service 6754ca
Packit Service 6754ca
The OpenEXR file format has a fairly large number of options for on-file
Packit Service 6754ca
image storage, including arbitrary sets of channels, per-channel pixel
Packit Service 6754ca
format selection, sub-sampled channels, multi-resolution images, deep
Packit Service 6754ca
images, or storing images as tiles or scan lines.  While reading a simple
Packit Service 6754ca
RGBA image does not require a lot of code, reading the contents of an
Packit Service 6754ca
arbitrary OpenEXR file, and representing those contents in main memory
Packit Service 6754ca
is not trivial.  The IlmImfUtil library simplifies those tasks.
Packit Service 6754ca
Packit Service 6754ca
Image, Image Level, Image Channel
Packit Service 6754ca
---------------------------------
Packit Service 6754ca
Packit Service 6754ca
An image (class Image) is a container for a set of image levels (class
Packit Service 6754ca
ImageLevel), and an image level is a container for a set of image channels
Packit Service 6754ca
(class ImageChannel).  An image channel contains an array of pixel values.
Packit Service 6754ca
Packit Service 6754ca
For example:
Packit Service 6754ca
Packit Service 6754ca
    image --+-- level 0,0 --+-- channel "R" --- pixel data
Packit Service 6754ca
            |               |
Packit Service 6754ca
            |               +-- channel "G" --- pixel data
Packit Service 6754ca
            |               |
Packit Service 6754ca
            |               +-- channel "B" --- pixel data
Packit Service 6754ca
            |
Packit Service 6754ca
            +-- level 1,1 --+-- channel "R" --- pixel data
Packit Service 6754ca
            |               |
Packit Service 6754ca
            |               +-- channel "G" --- pixel data
Packit Service 6754ca
            |               |
Packit Service 6754ca
            |               +-- channel "B" --- pixel data
Packit Service 6754ca
            |
Packit Service 6754ca
            +-- level 2,2 --+-- channel "R" --- pixel data
Packit Service 6754ca
                            |
Packit Service 6754ca
                            +-- channel "G" --- pixel data
Packit Service 6754ca
                            |
Packit Service 6754ca
                            +-- channel "B" --- pixel data
Packit Service 6754ca
Packit Service 6754ca
An image has a level mode (enum LevelMode), which can be ONE_LEVEL,
Packit Service 6754ca
MIPMAP_LEVELS or RIPMAP_LEVELS.  A ONE_LEVEL image contains only a single
Packit Service 6754ca
level, but a multi-resolution image, that is, one with level mode set to
Packit Service 6754ca
MIPMAP_LEVELS or RIPMAP_LEVELS, contains multiple levels.  The levels are
Packit Service 6754ca
analogous to the levels in an OpenEXR file, as described in the "Technical
Packit Service 6754ca
Introduction to OpenEXR" document.
Packit Service 6754ca
Packit Service 6754ca
Levels are indexed by a pairs of level numbers.  Level (0,0) contains the
Packit Service 6754ca
highest-resolution version of the image; level (lx,ly) contains an image
Packit Service 6754ca
whose resolution is reduced in x and y by a factor of 2^lx and 2^ly
Packit Service 6754ca
respectively.  The level has a data window that indicates the range of
Packit Service 6754ca
x and y for which pixel data are stored in the level.
Packit Service 6754ca
Packit Service 6754ca
All levels in an image have the same set of image channels.
Packit Service 6754ca
Packit Service 6754ca
An image channel has a name (e.g. "R", "Z", or "xVelocity"), a type (HALF,
Packit Service 6754ca
FLOAT or UINT) and x and y sampling rates.  A channel stores samples for
Packit Service 6754ca
a pixel if the pixel is inside the data window of the level to which the
Packit Service 6754ca
channel belongs, and the x and y coordinates of the pixel are divisible by
Packit Service 6754ca
the x and y sampling rates of the channel.
Packit Service 6754ca
Packit Service 6754ca
An image can be either flat or deep.  In a flat image each channel in each
Packit Service 6754ca
level stores at most one value per pixel.  In a deep image each channel in
Packit Service 6754ca
each level stores an arbitrary number of values per pixel.  As an exception,
Packit Service 6754ca
each level of a deep image has a sample count channel with a single value
Packit Service 6754ca
per pixel; this value determines how many values each of the other channels
Packit Service 6754ca
in the same level has at the same pixel location.
Packit Service 6754ca
Packit Service 6754ca
The Image, ImageLevel and ImageChannel classes are abstact base classes.
Packit Service 6754ca
Two sets of classes, one for flat images and one for deep images, are
Packit Service 6754ca
derived from the base classes.  The FlatImageChannel and DeepImageChannel
Packit Service 6754ca
classes, derived from ImageChannel, are themselves base classes for the
Packit Service 6754ca
templates TypedFlatImageChannel<T> and TypedDeepImageChannel<T>:
Packit Service 6754ca
Packit Service 6754ca
    Image -> FlatImage
Packit Service 6754ca
          -> DeepImage
Packit Service 6754ca
Packit Service 6754ca
    ImageLevel -> FlatImageLevel
Packit Service 6754ca
               -> DeepImageLevel
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
    ImageChannel -> FlatImageChannel -> TypedFlatImageChannel<T>
Packit Service 6754ca
                 -> DeepImageChannel -> TypedDeepImageChannel<T>
Packit Service 6754ca
                 -> SampleCountChannel
Packit Service 6754ca
Packit Service 6754ca
Channel objects of type TypedFlatImageChannel<T> and TypedDeepImageChannel<T> 
Packit Service 6754ca
contain pixel values of type T, where T is either half, float or unsigned int.
Packit Service 6754ca
For convenience, the following typedefs are provided:
Packit Service 6754ca
Packit Service 6754ca
    typedef TypedFlatImageChannel<half>         FlatHalfChannel;
Packit Service 6754ca
    typedef TypedFlatImageChannel<float>        FlatFloatChannel;
Packit Service 6754ca
    typedef TypedFlatImageChannel<unsigned int> FlatUIntChannel;
Packit Service 6754ca
Packit Service 6754ca
    typedef TypedDeepImageChannel<half>         DeepHalfChannel;
Packit Service 6754ca
    typedef TypedDeepImageChannel<float>        DeepFloatChannel;
Packit Service 6754ca
    typedef TypedDeepImageChannel<unsigned int> DeepUIntChannel;
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
File I/O
Packit Service 6754ca
--------
Packit Service 6754ca
Packit Service 6754ca
An Image object can be saved in an OpenEXR file with a single function call:
Packit Service 6754ca
Packit Service 6754ca
    saveImage ("foo.exr", myImage);
Packit Service 6754ca
Packit Service 6754ca
The saveImage() function automatically creates a flat or a deep image file,
Packit Service 6754ca
depending on the type of the image.  All channels and all image levels will
Packit Service 6754ca
be saved in the file.
Packit Service 6754ca
Packit Service 6754ca
Optionally an OpenEXR Header object can be passed to the saveImage() function;
Packit Service 6754ca
this allows application code save custom attributes in the file, and to control
Packit Service 6754ca
how the file will be compressed:
Packit Service 6754ca
Packit Service 6754ca
    Header myHeader;
Packit Service 6754ca
    myHeader.compression() = PIZ_COMPRESSION;
Packit Service 6754ca
    myHeader.pixelAspectRatio() = 1.5;
Packit Service 6754ca
Packit Service 6754ca
    saveImage ("foo.exr", myHeader, myImage);
Packit Service 6754ca
Packit Service 6754ca
Loading an image from an OpenEXR file also requires only one function call,
Packit Service 6754ca
either
Packit Service 6754ca
Packit Service 6754ca
    Image* myImage = loadImage ("foo.exr");
Packit Service 6754ca
Packit Service 6754ca
or
Packit Service 6754ca
Packit Service 6754ca
    Header myHeader;
Packit Service 6754ca
    Image* myImage = loadImage ("foo.exr", myHeader);
Packit Service 6754ca
Packit Service 6754ca
The application owns the image that is returned by the loadImage() call.
Packit Service 6754ca
It is the application's responsibility to delete the Image object.
Packit Service 6754ca
Packit Service 6754ca
The IlmImfUtil library also provides versions of the saveImage() and
Packit Service 6754ca
loadImage() functions that work only on flat images or only on deep images:
Packit Service 6754ca
Packit Service 6754ca
    saveFlatImage()
Packit Service 6754ca
    saveFlatScanLineImage()
Packit Service 6754ca
    saveFlatTiledImage()
Packit Service 6754ca
    saveDeepImage()
Packit Service 6754ca
    saveDeepScanLineImage()
Packit Service 6754ca
    saveDeepTiledImage()
Packit Service 6754ca
Packit Service 6754ca
For details the the ImfFlatImageIO.h and ImfDeepImageIO.h header files.
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Manipulating Images in Memory
Packit Service 6754ca
-----------------------------
Packit Service 6754ca
Packit Service 6754ca
Creating a mip-mapped flat image with two channels:
Packit Service 6754ca
Packit Service 6754ca
    FlatImage fimg (Box2i (V2i (0, 0), V2i (255, 255)),    // data window
Packit Service 6754ca
                    MIPMAP_LEVELS);                        // level mode
Packit Service 6754ca
Packit Service 6754ca
    fimg.insertChannel ("R", HALF);
Packit Service 6754ca
    fimg.insertChannel ("Z", FLOAT);
Packit Service 6754ca
Packit Service 6754ca
Creating a single-level deep image:
Packit Service 6754ca
Packit Service 6754ca
    DeepImage dimg (Box2i (V2i (0, 0), V2i (255, 255)),    // data window
Packit Service 6754ca
                    ONE_LEVEL);                            // level mode
Packit Service 6754ca
Packit Service 6754ca
    dimg.insertChannel ("R", HALF);
Packit Service 6754ca
    dimg.insertChannel ("Z", FLOAT);
Packit Service 6754ca
Packit Service 6754ca
Reading and writing pixels in level (2,2) of the mip-mapped flat image
Packit Service 6754ca
(note: a mip-mapped image contains only levels where the x and y level
Packit Service 6754ca
numbers are equal.  For convenience, mip-map levels can be addressed
Packit Service 6754ca
using a single level number):
Packit Service 6754ca
Packit Service 6754ca
    FlatImageLevel &level = fimg.level (2);
Packit Service 6754ca
    FlatHalfChannel &R = level.typedChannel<half> ("R);
Packit Service 6754ca
Packit Service 6754ca
    half r1 = R.at (20, 15);    // read pixel (20,15), with bounds checking
Packit Service 6754ca
                                // (exception for access outside data window)
Packit Service 6754ca
Packit Service 6754ca
    half r2 = R (17, 4);        // read pixel (17,4) without bounds checking
Packit Service 6754ca
                                // faster, but crashes for access outside
Packit Service 6754ca
                                // data window
Packit Service 6754ca
Packit Service 6754ca
    R.at (20, 15) = 2 * r1;     // change pixel value, with and
Packit Service 6754ca
    R (17, 4) = 2 * r2;         // without bounds checking
Packit Service 6754ca
Packit Service 6754ca
Reading and writing pixels in the single-level deep image:
Packit Service 6754ca
Packit Service 6754ca
    DeepImageLevel &level = dimg.level();
Packit Service 6754ca
    DeepHalfChannel &R = level.typedChannel<half> ("R);
Packit Service 6754ca
Packit Service 6754ca
    // with bounds checking
Packit Service 6754ca
Packit Service 6754ca
    unsigned int n1 = R.sampleCounts().at (20, 15);
Packit Service 6754ca
    half r1;
Packit Service 6754ca
Packit Service 6754ca
    if (n1 > 0)
Packit Service 6754ca
        r1 = R.at(20, 15)[n1 - 1];  // read the last sample in pixel (20,15)
Packit Service 6754ca
Packit Service 6754ca
    // without bounds checking
Packit Service 6754ca
Packit Service 6754ca
    unsigned int n2 = R.sampleCounts()(20, 15);
Packit Service 6754ca
    half r2;
Packit Service 6754ca
Packit Service 6754ca
    if (n > 0)
Packit Service 6754ca
        r2 = R(17, 4)[n2 - 1];     // read the last sample in pixel (17,4)
Packit Service 6754ca
Packit Service 6754ca
    // change the value of an existing sample
Packit Service 6754ca
Packit Service 6754ca
    if (n1 > 0)
Packit Service 6754ca
        R(20,15)[n1 - 1] = r1 * 2;
Packit Service 6754ca
Packit Service 6754ca
    // append a new sample to a pixel and set the sample to 3.0
Packit Service 6754ca
Packit Service 6754ca
    R.sampleCounts().set (20, 15, n1 + 1);
Packit Service 6754ca
    R.(20, 15)[n1] = 3.0;
Packit Service 6754ca
Packit Service 6754ca
In addition to functions for reading and writing individual pixels, there
Packit Service 6754ca
are functions for accessing a whole row of pixels with a single function
Packit Service 6754ca
call.  For details see the ImfFlatImageChannel.h, ImfDeepImageChannel.h
Packit Service 6754ca
and ImfSampleCountChannel.h header files in the IlmImf library:
Packit Service 6754ca
Packit Service 6754ca
    T*                   TypedFlatImageChannel<T>::row (int r);
Packit Service 6754ca
    const T*             TypedFlatImageChannel<T>::row (int r) const;
Packit Service 6754ca
Packit Service 6754ca
    T * const *          TypedDeepImageChannel<T>::row (int r);
Packit Service 6754ca
    const T * const *    TypedDeepImageChannel<T>::row (int r) const;
Packit Service 6754ca
    const unsigned int * SampleCountChannel::row (int r) const;
Packit Service 6754ca
Packit Service 6754ca
To change the number of samples in all pixels in one row of a deep image
Packit Service 6754ca
level, use:
Packit Service 6754ca
Packit Service 6754ca
    void SampleCountChannel::set (int r, unsigned int newNumSamples[]);
Packit Service 6754ca
Packit Service 6754ca
Use an Edit object to temporarily make all sample counts in a deep image
Packit Service 6754ca
level editable:
Packit Service 6754ca
Packit Service 6754ca
    class SampleCountChannel::Edit;
Packit Service 6754ca
Packit Service 6754ca
Miscellaneous Functions:
Packit Service 6754ca
------------------------
Packit Service 6754ca
Packit Service 6754ca
Change the data window and the level mode of an image (pixel data are not
Packit Service 6754ca
preserved across the call):
Packit Service 6754ca
Packit Service 6754ca
    void Image::resize (const Box2i &dataWindow, LevelMode levelMode);
Packit Service 6754ca
Packit Service 6754ca
Shift the data window in x and y; shift the pixels along with the data window:
Packit Service 6754ca
Packit Service 6754ca
    void Image::shiftPixels (int dx, int dy);
Packit Service 6754ca
Packit Service 6754ca
Erase a channel, rename a channel, rename multiple channels at the same time:
Packit Service 6754ca
Packit Service 6754ca
    void Image::eraseChannel (const string &name);
Packit Service 6754ca
    void Image::renameChannel (const string &oldName, const string &newName);
Packit Service 6754ca
    void Image::renameChannels (const RenamingMap &oldToNewNames);
Packit Service 6754ca
Packit Service 6754ca
Missing Functionality:
Packit Service 6754ca
----------------------
Packit Service 6754ca
Packit Service 6754ca
At this point, the IlmImfUtil library cannot read or write multi-part
Packit Service 6754ca
files.  A future version of the library should probably define a new class
Packit Service 6754ca
MultiPartImage that contains a set of regular images.  The library should
Packit Service 6754ca
also define corresponding loadMultiPartImage() and saveMultiPartImage()
Packit Service 6754ca
functions.
Packit Service 6754ca
Packit Service 6754ca
Sample Code
Packit Service 6754ca
-----------
Packit Service 6754ca
Packit Service 6754ca
See the exrsave, exrmakescanlines, exrclip utilities.
Packit Service 6754ca
Packit Service 6754ca