• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

ImfCheckFile.cppH A D23-Jan-202246.6 KiB1,5961,165

ImfCheckFile.hH A D23-Jan-20221.6 KiB5621

ImfDeepImage.cppH A D23-Jan-20221.5 KiB8250

ImfDeepImage.hH A D23-Jan-20221.7 KiB6827

ImfDeepImageChannel.cppH A D23-Jan-20228.6 KiB332199

ImfDeepImageChannel.hH A D23-Jan-20228.2 KiB288140

ImfDeepImageIO.cppH A D23-Jan-20229.8 KiB431303

ImfDeepImageIO.hH A D23-Jan-20225.3 KiB19478

ImfDeepImageLevel.cppH A D23-Jan-20226.1 KiB299212

ImfDeepImageLevel.hH A D23-Jan-202210.1 KiB449268

ImfFlatImage.cppH A D23-Jan-20221.5 KiB8250

ImfFlatImage.hH A D23-Jan-20221.7 KiB6726

ImfFlatImageChannel.cppH A D23-Jan-20223.1 KiB166112

ImfFlatImageChannel.hH A D23-Jan-20226.3 KiB241113

ImfFlatImageIO.cppH A D23-Jan-20228.3 KiB381279

ImfFlatImageIO.hH A D23-Jan-20225.3 KiB19277

ImfFlatImageLevel.cppH A D23-Jan-20224.4 KiB237160

ImfFlatImageLevel.hH A D23-Jan-20228.9 KiB401234

ImfImage.cppH A D23-Jan-202213 KiB643480

ImfImage.hH A D23-Jan-202212 KiB35285

ImfImageChannel.cppH A D23-Jan-20222.8 KiB10975

ImfImageChannel.hH A D23-Jan-20223 KiB11955

ImfImageChannelRenaming.hH A D23-Jan-20221.4 KiB5524

ImfImageDataWindow.cppH A D23-Jan-20221.4 KiB5733

ImfImageDataWindow.hH A D23-Jan-20221.1 KiB4818

ImfImageIO.cppH A D23-Jan-20223.1 KiB13597

ImfImageIO.hH A D23-Jan-20222.5 KiB8929

ImfImageLevel.cppH A D23-Jan-20222.1 KiB9663

ImfImageLevel.hH A D23-Jan-20222.8 KiB10755

ImfSampleCountChannel.cppH A D23-Jan-20228.3 KiB349224

ImfSampleCountChannel.hH A D23-Jan-202210.3 KiB352126

ImfUtilExport.hH A D23-Jan-20222.1 KiB6434

READMEH A D23-Jan-20229.9 KiB271190

README

1The OpenEXRUtil Library
2----------------------
3
4The OpenEXRUtil library implements an in-memory image data structure, as
5well as simple function calls for saving images in OpenEXR files, and for
6constructing images from the contents of existing OpenEXR files.
7
8The OpenEXR file format has a fairly large number of options for on-file
9image storage, including arbitrary sets of channels, per-channel pixel
10format selection, sub-sampled channels, multi-resolution images, deep
11images, or storing images as tiles or scan lines.  While reading a simple
12RGBA image does not require a lot of code, reading the contents of an
13arbitrary OpenEXR file, and representing those contents in main memory
14is not trivial.  The OpenEXRUtil library simplifies those tasks.
15
16Image, Image Level, Image Channel
17---------------------------------
18
19An image (class Image) is a container for a set of image levels (class
20ImageLevel), and an image level is a container for a set of image channels
21(class ImageChannel).  An image channel contains an array of pixel values.
22
23For example:
24
25    image --+-- level 0,0 --+-- channel "R" --- pixel data
26            |               |
27            |               +-- channel "G" --- pixel data
28            |               |
29            |               +-- channel "B" --- pixel data
30            |
31            +-- level 1,1 --+-- channel "R" --- pixel data
32            |               |
33            |               +-- channel "G" --- pixel data
34            |               |
35            |               +-- channel "B" --- pixel data
36            |
37            +-- level 2,2 --+-- channel "R" --- pixel data
38                            |
39                            +-- channel "G" --- pixel data
40                            |
41                            +-- channel "B" --- pixel data
42
43An image has a level mode (enum LevelMode), which can be ONE_LEVEL,
44MIPMAP_LEVELS or RIPMAP_LEVELS.  A ONE_LEVEL image contains only a single
45level, but a multi-resolution image, that is, one with level mode set to
46MIPMAP_LEVELS or RIPMAP_LEVELS, contains multiple levels.  The levels are
47analogous to the levels in an OpenEXR file, as described in the "Technical
48Introduction to OpenEXR" document.
49
50Levels are indexed by a pairs of level numbers.  Level (0,0) contains the
51highest-resolution version of the image; level (lx,ly) contains an image
52whose resolution is reduced in x and y by a factor of 2^lx and 2^ly
53respectively.  The level has a data window that indicates the range of
54x and y for which pixel data are stored in the level.
55
56All levels in an image have the same set of image channels.
57
58An image channel has a name (e.g. "R", "Z", or "xVelocity"), a type (HALF,
59FLOAT or UINT) and x and y sampling rates.  A channel stores samples for
60a pixel if the pixel is inside the data window of the level to which the
61channel belongs, and the x and y coordinates of the pixel are divisible by
62the x and y sampling rates of the channel.
63
64An image can be either flat or deep.  In a flat image each channel in each
65level stores at most one value per pixel.  In a deep image each channel in
66each level stores an arbitrary number of values per pixel.  As an exception,
67each level of a deep image has a sample count channel with a single value
68per pixel; this value determines how many values each of the other channels
69in the same level has at the same pixel location.
70
71The Image, ImageLevel and ImageChannel classes are abstact base classes.
72Two sets of classes, one for flat images and one for deep images, are
73derived from the base classes.  The FlatImageChannel and DeepImageChannel
74classes, derived from ImageChannel, are themselves base classes for the
75templates TypedFlatImageChannel<T> and TypedDeepImageChannel<T>:
76
77    Image -> FlatImage
78          -> DeepImage
79
80    ImageLevel -> FlatImageLevel
81               -> DeepImageLevel
82
83
84    ImageChannel -> FlatImageChannel -> TypedFlatImageChannel<T>
85                 -> DeepImageChannel -> TypedDeepImageChannel<T>
86                 -> SampleCountChannel
87
88Channel objects of type TypedFlatImageChannel<T> and TypedDeepImageChannel<T>
89contain pixel values of type T, where T is either half, float or unsigned int.
90For convenience, the following typedefs are provided:
91
92    typedef TypedFlatImageChannel<half>         FlatHalfChannel;
93    typedef TypedFlatImageChannel<float>        FlatFloatChannel;
94    typedef TypedFlatImageChannel<unsigned int> FlatUIntChannel;
95
96    typedef TypedDeepImageChannel<half>         DeepHalfChannel;
97    typedef TypedDeepImageChannel<float>        DeepFloatChannel;
98    typedef TypedDeepImageChannel<unsigned int> DeepUIntChannel;
99
100
101File I/O
102--------
103
104An Image object can be saved in an OpenEXR file with a single function call:
105
106    saveImage ("foo.exr", myImage);
107
108The saveImage() function automatically creates a flat or a deep image file,
109depending on the type of the image.  All channels and all image levels will
110be saved in the file.
111
112Optionally an OpenEXR Header object can be passed to the saveImage() function;
113this allows application code save custom attributes in the file, and to control
114how the file will be compressed:
115
116    Header myHeader;
117    myHeader.compression() = PIZ_COMPRESSION;
118    myHeader.pixelAspectRatio() = 1.5;
119
120    saveImage ("foo.exr", myHeader, myImage);
121
122Loading an image from an OpenEXR file also requires only one function call,
123either
124
125    Image* myImage = loadImage ("foo.exr");
126
127or
128
129    Header myHeader;
130    Image* myImage = loadImage ("foo.exr", myHeader);
131
132The application owns the image that is returned by the loadImage() call.
133It is the application's responsibility to delete the Image object.
134
135The OpenEXRUtil library also provides versions of the saveImage() and
136loadImage() functions that work only on flat images or only on deep images:
137
138    saveFlatImage()
139    saveFlatScanLineImage()
140    saveFlatTiledImage()
141    saveDeepImage()
142    saveDeepScanLineImage()
143    saveDeepTiledImage()
144
145For details the the ImfFlatImageIO.h and ImfDeepImageIO.h header files.
146
147
148Manipulating Images in Memory
149-----------------------------
150
151Creating a mip-mapped flat image with two channels:
152
153    FlatImage fimg (Box2i (V2i (0, 0), V2i (255, 255)),    // data window
154                    MIPMAP_LEVELS);                        // level mode
155
156    fimg.insertChannel ("R", HALF);
157    fimg.insertChannel ("Z", FLOAT);
158
159Creating a single-level deep image:
160
161    DeepImage dimg (Box2i (V2i (0, 0), V2i (255, 255)),    // data window
162                    ONE_LEVEL);                            // level mode
163
164    dimg.insertChannel ("R", HALF);
165    dimg.insertChannel ("Z", FLOAT);
166
167Reading and writing pixels in level (2,2) of the mip-mapped flat image
168(note: a mip-mapped image contains only levels where the x and y level
169numbers are equal.  For convenience, mip-map levels can be addressed
170using a single level number):
171
172    FlatImageLevel &level = fimg.level (2);
173    FlatHalfChannel &R = level.typedChannel<half> ("R);
174
175    half r1 = R.at (20, 15);    // read pixel (20,15), with bounds checking
176                                // (exception for access outside data window)
177
178    half r2 = R (17, 4);        // read pixel (17,4) without bounds checking
179                                // faster, but crashes for access outside
180                                // data window
181
182    R.at (20, 15) = 2 * r1;     // change pixel value, with and
183    R (17, 4) = 2 * r2;         // without bounds checking
184
185Reading and writing pixels in the single-level deep image:
186
187    DeepImageLevel &level = dimg.level();
188    DeepHalfChannel &R = level.typedChannel<half> ("R);
189
190    // with bounds checking
191
192    unsigned int n1 = R.sampleCounts().at (20, 15);
193    half r1;
194
195    if (n1 > 0)
196        r1 = R.at(20, 15)[n1 - 1];  // read the last sample in pixel (20,15)
197
198    // without bounds checking
199
200    unsigned int n2 = R.sampleCounts()(20, 15);
201    half r2;
202
203    if (n > 0)
204        r2 = R(17, 4)[n2 - 1];     // read the last sample in pixel (17,4)
205
206    // change the value of an existing sample
207
208    if (n1 > 0)
209        R(20,15)[n1 - 1] = r1 * 2;
210
211    // append a new sample to a pixel and set the sample to 3.0
212
213    R.sampleCounts().set (20, 15, n1 + 1);
214    R.(20, 15)[n1] = 3.0;
215
216In addition to functions for reading and writing individual pixels, there
217are functions for accessing a whole row of pixels with a single function
218call.  For details see the ImfFlatImageChannel.h, ImfDeepImageChannel.h
219and ImfSampleCountChannel.h header files in the OpenEXR library:
220
221    T*                   TypedFlatImageChannel<T>::row (int r);
222    const T*             TypedFlatImageChannel<T>::row (int r) const;
223
224    T * const *          TypedDeepImageChannel<T>::row (int r);
225    const T * const *    TypedDeepImageChannel<T>::row (int r) const;
226    const unsigned int * SampleCountChannel::row (int r) const;
227
228To change the number of samples in all pixels in one row of a deep image
229level, use:
230
231    void SampleCountChannel::set (int r, unsigned int newNumSamples[]);
232
233Use an Edit object to temporarily make all sample counts in a deep image
234level editable:
235
236    class SampleCountChannel::Edit;
237
238Miscellaneous Functions:
239------------------------
240
241Change the data window and the level mode of an image (pixel data are not
242preserved across the call):
243
244    void Image::resize (const Box2i &dataWindow, LevelMode levelMode);
245
246Shift the data window in x and y; shift the pixels along with the data window:
247
248    void Image::shiftPixels (int dx, int dy);
249
250Erase a channel, rename a channel, rename multiple channels at the same time:
251
252    void Image::eraseChannel (const string &name);
253    void Image::renameChannel (const string &oldName, const string &newName);
254    void Image::renameChannels (const RenamingMap &oldToNewNames);
255
256Missing Functionality:
257----------------------
258
259At this point, the OpenEXRUtil library cannot read or write multi-part
260files.  A future version of the library should probably define a new class
261MultiPartImage that contains a set of regular images.  The library should
262also define corresponding loadMultiPartImage() and saveMultiPartImage()
263functions.
264
265Sample Code
266-----------
267
268See the exrsave, exrmakescanlines, exrclip utilities.
269
270
271