1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4
5
6 /////////////////////////////////////////////////////////////////////////////
7 /// \file
8 ///
9 /// Provides a simple API that abstracts the reading and writing of
10 /// images. Subclasses, which may be found in DSO/DLL's, implement
11 /// particular formats.
12 ///
13 /////////////////////////////////////////////////////////////////////////////
14
15 // clang-format off
16
17 #pragma once
18 #define OPENIMAGEIO_IMAGEIO_H
19
20 #if defined(_MSC_VER)
21 // Ignore warnings about DLL exported classes with member variables that are template classes.
22 // This happens with the std::vector<T> and std::string members of the classes below.
23 # pragma warning(disable : 4251)
24 #endif
25
26 #include <cmath>
27 #include <limits>
28 #include <string>
29 #include <vector>
30
31 #include <OpenImageIO/span.h>
32 #include <OpenImageIO/export.h>
33 #include <OpenImageIO/oiioversion.h>
34 #include <OpenImageIO/paramlist.h>
35 #include <OpenImageIO/platform.h>
36 #include <OpenImageIO/strutil.h>
37 #include <OpenImageIO/thread.h>
38 #include <OpenImageIO/typedesc.h>
39
40 OIIO_NAMESPACE_BEGIN
41
42 class DeepData;
43
44
45 /// Type we use for stride lengths between pixels, scanlines, or image
46 /// planes.
47 using stride_t = int64_t;
48
49 /// Type we use to express how many pixels (or bytes) constitute an image,
50 /// tile, or scanline.
51 using imagesize_t = uint64_t;
52
53 /// Special value to indicate a stride length that should be
54 /// auto-computed.
55 const stride_t AutoStride = std::numeric_limits<stride_t>::min();
56
57
58
59 /// Pointer to a function called periodically by read_image and
60 /// write_image. This can be used to implement progress feedback, etc.
61 /// It takes an opaque data pointer (passed to read_image/write_image)
62 /// and a float giving the portion of work done so far. It returns a
63 /// bool, which if 'true' will STOP the read or write.
64 typedef bool (*ProgressCallback)(void *opaque_data, float portion_done);
65
66
67
68 // Deprecated typedefs. Just use ParamValue and ParamValueList directly.
69 typedef ParamValue ImageIOParameter;
70 typedef ParamValueList ImageIOParameterList;
71
72
73 // Forward declaration of IOProxy
74 namespace Filesystem {
75 class IOProxy;
76 }
77
78
79 /// ROI is a small helper struct describing a rectangular region of interest
80 /// in an image. The region is [xbegin,xend) x [begin,yend) x [zbegin,zend),
81 /// with the "end" designators signifying one past the last pixel in each
82 /// dimension, a la STL style.
83 ///
84 struct ROI {
85 ///@{
86 /// @name ROI data members
87 /// The data members are:
88 ///
89 /// int xbegin, xend, ybegin, yend, zbegin, zend;
90 /// int chbegin, chend;
91 ///
92 /// These describe the spatial extent
93 /// [xbegin,xend) x [ybegin,yend) x [zbegin,zend)
94 /// And the channel extent:
95 /// [chbegin,chend)]
96 int xbegin, xend;
97 int ybegin, yend;
98 int zbegin, zend;
99 int chbegin, chend;
100 ///@}
101
102 /// Default constructor is an undefined region. Note that this is also
103 /// interpreted as All().
ROIROI104 constexpr ROI () noexcept : xbegin(std::numeric_limits<int>::min()), xend(0),
105 ybegin(0), yend(0), zbegin(0), zend(0), chbegin(0), chend(0)
106 { }
107
108 /// Constructor with an explicitly defined region.
109 ///
110 constexpr ROI (int xbegin, int xend, int ybegin, int yend,
111 int zbegin=0, int zend=1, int chbegin=0, int chend=10000) noexcept
xbeginROI112 : xbegin(xbegin), xend(xend), ybegin(ybegin), yend(yend),
113 zbegin(zbegin), zend(zend), chbegin(chbegin), chend(chend)
114 { }
115
116 /// Is a region defined?
definedROI117 constexpr bool defined () const noexcept { return (xbegin != std::numeric_limits<int>::min()); }
118
119 ///@{
120 /// @name Spatial size functions.
121 /// The width, height, and depth of the region.
widthROI122 constexpr int width () const noexcept { return xend - xbegin; } ///< Height
heightROI123 constexpr int height () const noexcept { return yend - ybegin; } ///< Width
depthROI124 constexpr int depth () const noexcept { return zend - zbegin; } ///< Depth
125 ///@}
126
127 /// Number of channels in the region. Beware -- this defaults to a
128 /// huge number, and to be meaningful you must consider
129 /// std::min (imagebuf.nchannels(), roi.nchannels()).
nchannelsROI130 constexpr int nchannels () const noexcept { return chend - chbegin; }
131
132 /// Total number of pixels in the region.
npixelsROI133 constexpr imagesize_t npixels () const noexcept {
134 return defined()
135 ? imagesize_t(width()) * imagesize_t(height()) * imagesize_t(depth())
136 : 0;
137 }
138
139 /// All() is an alias for the default constructor, which indicates that
140 /// it means "all" of the image, or no region restriction. For example,
141 /// float myfunc (ImageBuf &buf, ROI roi = ROI::All());
142 /// Note that this is equivalent to:
143 /// float myfunc (ImageBuf &buf, ROI roi = {});
AllROI144 static constexpr ROI All () noexcept { return ROI(); }
145
146 /// Test equality of two ROIs
147 friend constexpr bool operator== (const ROI &a, const ROI &b) noexcept {
148 return (a.xbegin == b.xbegin && a.xend == b.xend &&
149 a.ybegin == b.ybegin && a.yend == b.yend &&
150 a.zbegin == b.zbegin && a.zend == b.zend &&
151 a.chbegin == b.chbegin && a.chend == b.chend);
152 }
153 /// Test inequality of two ROIs
154 friend constexpr bool operator!= (const ROI &a, const ROI &b) noexcept {
155 return (a.xbegin != b.xbegin || a.xend != b.xend ||
156 a.ybegin != b.ybegin || a.yend != b.yend ||
157 a.zbegin != b.zbegin || a.zend != b.zend ||
158 a.chbegin != b.chbegin || a.chend != b.chend);
159 }
160
161 /// Test if the coordinate is within the ROI.
162 constexpr bool contains (int x, int y, int z=0, int ch=0) const noexcept {
163 return x >= xbegin && x < xend && y >= ybegin && y < yend
164 && z >= zbegin && z < zend && ch >= chbegin && ch < chend;
165 }
166
167 /// Test if another ROI is entirely within our ROI.
containsROI168 constexpr bool contains (const ROI& other) const noexcept {
169 return (other.xbegin >= xbegin && other.xend <= xend &&
170 other.ybegin >= ybegin && other.yend <= yend &&
171 other.zbegin >= zbegin && other.zend <= zend &&
172 other.chbegin >= chbegin && other.chend <= chend);
173 }
174
175 /// Stream output of the range
176 friend std::ostream & operator<< (std::ostream &out, const ROI &roi) {
177 out << roi.xbegin << ' ' << roi.xend << ' ' << roi.ybegin << ' '
178 << roi.yend << ' ' << roi.zbegin << ' ' << roi.zend << ' '
179 << roi.chbegin << ' ' << roi.chend;
180 return out;
181 }
182 };
183
184
185
186 /// Union of two regions, the smallest region containing both.
roi_union(const ROI & A,const ROI & B)187 inline constexpr ROI roi_union (const ROI &A, const ROI &B) noexcept {
188 return (A.defined() && B.defined())
189 ? ROI (std::min (A.xbegin, B.xbegin), std::max (A.xend, B.xend),
190 std::min (A.ybegin, B.ybegin), std::max (A.yend, B.yend),
191 std::min (A.zbegin, B.zbegin), std::max (A.zend, B.zend),
192 std::min (A.chbegin, B.chbegin), std::max (A.chend, B.chend))
193 : (A.defined() ? A : B);
194 }
195
196 /// Intersection of two regions.
roi_intersection(const ROI & A,const ROI & B)197 inline constexpr ROI roi_intersection (const ROI &A, const ROI &B) noexcept {
198 return (A.defined() && B.defined())
199 ? ROI (std::max (A.xbegin, B.xbegin), std::min (A.xend, B.xend),
200 std::max (A.ybegin, B.ybegin), std::min (A.yend, B.yend),
201 std::max (A.zbegin, B.zbegin), std::min (A.zend, B.zend),
202 std::max (A.chbegin, B.chbegin), std::min (A.chend, B.chend))
203 : (A.defined() ? A : B);
204 }
205
206
207
208
209 /// ImageSpec describes the data format of an image -- dimensions, layout,
210 /// number and meanings of image channels.
211 ///
212 /// The `width, height, depth` are the size of the data of this image, i.e.,
213 /// the number of pixels in each dimension. A ``depth`` greater than 1
214 /// indicates a 3D "volumetric" image. The `x, y, z` fields indicate the
215 /// *origin* of the pixel data of the image. These default to (0,0,0), but
216 /// setting them differently may indicate that this image is offset from the
217 /// usual origin.
218 /// Therefore the pixel data are defined over pixel coordinates
219 /// [`x` ... `x+width-1`] horizontally,
220 /// [`y` ... `y+height-1`] vertically,
221 /// and [`z` ... `z+depth-1`] in depth.
222 ///
223 /// The analogous `full_width`, `full_height`, `full_depth` and `full_x`,
224 /// `full_y`, `full_z` fields define a "full" or "display" image window over
225 /// the region [`full_x` ... `full_x+full_width-1`] horizontally, [`full_y`
226 /// ... `full_y+full_height-1`] vertically, and [`full_z`...
227 /// `full_z+full_depth-1`] in depth.
228 ///
229 /// Having the full display window different from the pixel data window can
230 /// be helpful in cases where you want to indicate that your image is a
231 /// *crop window* of a larger image (if the pixel data window is a subset of
232 /// the full display window), or that the pixels include *overscan* (if the
233 /// pixel data is a superset of the full display window), or may simply
234 /// indicate how different non-overlapping images piece together.
235 ///
236 /// For tiled images, `tile_width`, `tile_height`, and `tile_depth` specify
237 /// that the image is stored in a file organized into rectangular *tiles*
238 /// of these dimensions. The default of 0 value for these fields indicates
239 /// that the image is stored in scanline order, rather than as tiles.
240 ///
241
242 class OIIO_API ImageSpec {
243 public:
244 ///@{
245 /// @name ImageSpec data members
246 ///
247 /// The `ImageSpec` contains data fields for the values that are
248 /// required to describe nearly any image, and an extensible list of
249 /// arbitrary attributes that can hold metadata that may be user-defined
250 /// or specific to individual file formats.
251 ///
252 /// Here are the hard-coded data fields:
253
254 int x; ///< origin (upper left corner) of pixel data
255 int y; ///< origin (upper left corner) of pixel data
256 int z; ///< origin (upper left corner) of pixel data
257 int width; ///< width of the pixel data window
258 int height; ///< height of the pixel data window
259 int depth; ///< depth of pixel data, >1 indicates a "volume"
260 int full_x; ///< origin of the full (display) window
261 int full_y; ///< origin of the full (display) window
262 int full_z; ///< origin of the full (display) window
263 int full_width; ///< width of the full (display) window
264 int full_height; ///< height of the full (display) window
265 int full_depth; ///< depth of the full (display) window
266 int tile_width; ///< tile width (0 for a non-tiled image)
267 int tile_height; ///< tile height (0 for a non-tiled image)
268 int tile_depth; ///< tile depth (0 for a non-tiled image,
269 ///< 1 for a non-volume image)
270 int nchannels; ///< number of image channels, e.g., 4 for RGBA
271
272 TypeDesc format; ///< Data format of the channels.
273 ///< Describes the native format of the pixel data values
274 /// themselves, as a `TypeDesc`. Typical values would be
275 /// `TypeDesc::UINT8` for 8-bit unsigned values, `TypeDesc::FLOAT`
276 /// for 32-bit floating-point values, etc.
277 std::vector<TypeDesc> channelformats;
278 ///< Optional per-channel data formats. If all channels of the image
279 /// have the same data format, that will be described by `format`
280 /// and `channelformats` will be empty (zero length). If there are
281 /// different data formats for each channel, they will be described
282 /// in the `channelformats` vector, and the `format` field will
283 /// indicate a single default data format for applications that
284 /// don't wish to support per-channel formats (usually this will be
285 /// the format of the channel that has the most precision).
286
287 std::vector<std::string> channelnames;
288 ///< The names of each channel, in order. Typically this will be "R",
289 ///< "G", "B", "A" (alpha), "Z" (depth), or other arbitrary names.
290 int alpha_channel;
291 ///< The index of the channel that represents *alpha* (pixel
292 ///< coverage and/or transparency). It defaults to -1 if no alpha
293 ///< channel is present, or if it is not known which channel
294 ///< represents alpha.
295 int z_channel;
296 ///< The index of the channel that represents *z* or *depth* (from
297 ///< the camera). It defaults to -1 if no depth channel is present,
298 ///< or if it is not know which channel represents depth.
299 bool deep; ///< True if the image contains deep data.
300 ///< If `true`, this indicates that the image describes contains
301 ///< "deep" data consisting of multiple samples per pixel. If
302 ///< `false`, it's an ordinary image with one data value (per
303 ///< channel) per pixel.
304 ParamValueList extra_attribs;
305 ///< A list of arbitrarily-named and arbitrarily-typed additional
306 /// attributes of the image, for any metadata not described by the
307 /// hard-coded fields described above. This list may be manipulated
308 /// with the `attribute()` and `find_attribute()` methods.
309
310 ///@}
311
312 /// Constructor: given just the data format, set all other fields to
313 /// something reasonable.
314 ImageSpec (TypeDesc format = TypeDesc::UNKNOWN) noexcept;
315
316 /// Constructs an `ImageSpec` with the given x and y resolution, number
317 /// of channels, and pixel data format.
318 ///
319 /// All other fields are set to the obvious defaults -- the image is an
320 /// ordinary 2D image (not a volume), the image is not offset or a crop
321 /// of a bigger image, the image is scanline-oriented (not tiled),
322 /// channel names are "R", "G", "B"' and "A" (up to and including 4
323 /// channels, beyond that they are named "channel *n*"), the fourth
324 /// channel (if it exists) is assumed to be alpha.
325 ImageSpec (int xres, int yres, int nchans, TypeDesc fmt = TypeUInt8) noexcept;
326
327 /// Construct an `ImageSpec` whose dimensions (both data and "full") and
328 /// number of channels are given by the `ROI`, pixel data type by `fmt`,
329 /// and other fields are set to their default values.
330 explicit ImageSpec (const ROI &roi, TypeDesc fmt = TypeUInt8) noexcept;
331
332 /// Set the data format, and clear any per-channel format information
333 /// in `channelformats`.
334 void set_format (TypeDesc fmt) noexcept;
335
336 /// Sets the `channelnames` to reasonable defaults for the number of
337 /// channels. Specifically, channel names are set to "R", "G", "B,"
338 /// and "A" (up to and including 4 channels, beyond that they are named
339 /// "channel*n*".
340 void default_channel_names () noexcept;
341
342 /// Returns the number of bytes comprising each channel of each pixel
343 /// (i.e., the size of a single value of the type described by the
344 /// `format` field).
channel_bytes()345 size_t channel_bytes() const noexcept { return format.size(); }
346
347 /// Return the number of bytes needed for the single specified
348 /// channel. If native is false (default), compute the size of one
349 /// channel of `this->format`, but if native is true, compute the size
350 /// of the channel in terms of the "native" data format of that
351 /// channel as stored in the file.
352 size_t channel_bytes (int chan, bool native=false) const noexcept;
353
354 /// Return the number of bytes for each pixel (counting all channels).
355 /// If `native` is false (default), assume all channels are in
356 /// `this->format`, but if `native` is true, compute the size of a pixel
357 /// in the "native" data format of the file (these may differ in
358 /// the case of per-channel formats).
359 size_t pixel_bytes (bool native=false) const noexcept;
360
361 /// Return the number of bytes for just the subset of channels in each
362 /// pixel described by [chbegin,chend). If native is false (default),
363 /// assume all channels are in this->format, but if native is true,
364 /// compute the size of a pixel in the "native" data format of the file
365 /// (these may differ in the case of per-channel formats).
366 size_t pixel_bytes (int chbegin, int chend, bool native=false) const noexcept;
367
368 /// Returns the number of bytes comprising each scanline, i.e.,
369 /// `pixel_bytes(native) * width` This will return
370 /// `std::numeric_limits<imagesize_t>::max()` in the event of an
371 /// overflow where it's not representable in an `imagesize_t`.
372 imagesize_t scanline_bytes (bool native=false) const noexcept;
373
374 /// Return the number of pixels comprising a tile (or 0 if it is not a
375 /// tiled image). This will return
376 /// `std::numeric_limits<imagesize_t>::max()` in the event of an
377 /// overflow where it's not representable in an `imagesize_t`.
378 imagesize_t tile_pixels () const noexcept;
379
380 /// Returns the number of bytes comprising an image tile, i.e.,
381 /// `pixel_bytes(native) * tile_width * tile_height * tile_depth`
382 /// If native is false (default), assume all channels are in
383 /// `this->format`, but if `native` is true, compute the size of a pixel
384 /// in the "native" data format of the file (these may differ in the
385 /// case of per-channel formats).
386 imagesize_t tile_bytes (bool native=false) const noexcept;
387
388 /// Return the number of pixels for an entire image. This will
389 /// return `std::numeric_limits<imagesize_t>::max()` in the event of
390 /// an overflow where it's not representable in an `imagesize_t`.
391 imagesize_t image_pixels () const noexcept;
392
393 /// Returns the number of bytes comprising an entire image of these
394 /// dimensions, i.e.,
395 /// `pixel_bytes(native) * width * height * depth`
396 /// This will return `std::numeric_limits<image size_t>::max()` in the
397 /// event of an overflow where it's not representable in an
398 /// `imagesize_t`. If `native` is false (default), assume all channels
399 /// are in `this->format`, but if `native` is true, compute the size of
400 /// a pixel in the "native" data format of the file (these may differ in
401 /// the case of per-channel formats).
402 imagesize_t image_bytes (bool native=false) const noexcept;
403
404 /// Verify that on this platform, a `size_t` is big enough to hold the
405 /// number of bytes (and pixels) in a scanline, a tile, and the
406 /// whole image. If this returns false, the image is much too big
407 /// to allocate and read all at once, so client apps beware and check
408 /// these routines for overflows!
size_t_safe()409 bool size_t_safe() const noexcept {
410 const imagesize_t big = std::numeric_limits<size_t>::max();
411 return image_bytes() < big && scanline_bytes() < big &&
412 tile_bytes() < big;
413 }
414
415 /// Adjust the stride values, if set to AutoStride, to be the right
416 /// sizes for contiguous data with the given format, channels,
417 /// width, height.
auto_stride(stride_t & xstride,stride_t & ystride,stride_t & zstride,stride_t channelsize,int nchannels,int width,int height)418 static void auto_stride (stride_t &xstride, stride_t &ystride,
419 stride_t &zstride, stride_t channelsize,
420 int nchannels, int width, int height) noexcept {
421 if (xstride == AutoStride)
422 xstride = nchannels * channelsize;
423 if (ystride == AutoStride)
424 ystride = xstride * width;
425 if (zstride == AutoStride)
426 zstride = ystride * height;
427 }
428
429 /// Adjust the stride values, if set to AutoStride, to be the right
430 /// sizes for contiguous data with the given format, channels,
431 /// width, height.
auto_stride(stride_t & xstride,stride_t & ystride,stride_t & zstride,TypeDesc format,int nchannels,int width,int height)432 static void auto_stride (stride_t &xstride, stride_t &ystride,
433 stride_t &zstride, TypeDesc format,
434 int nchannels, int width, int height) noexcept {
435 auto_stride (xstride, ystride, zstride, format.size(),
436 nchannels, width, height);
437 }
438
439 /// Adjust xstride, if set to AutoStride, to be the right size for
440 /// contiguous data with the given format and channels.
auto_stride(stride_t & xstride,TypeDesc format,int nchannels)441 static void auto_stride (stride_t &xstride, TypeDesc format, int nchannels) noexcept {
442 if (xstride == AutoStride)
443 xstride = nchannels * format.size();
444 }
445
446 /// Add a metadata attribute to `extra_attribs`, with the given name and
447 /// data type. The `value` pointer specifies the address of the data to
448 /// be copied.
449 void attribute (string_view name, TypeDesc type, const void *value);
450
451 /// Add an `unsigned int` attribute to `extra_attribs`.
attribute(string_view name,unsigned int value)452 void attribute (string_view name, unsigned int value) {
453 attribute (name, TypeDesc::UINT, &value);
454 }
455
456 /// Add an `int` attribute to `extra_attribs`.
attribute(string_view name,int value)457 void attribute (string_view name, int value) {
458 attribute (name, TypeDesc::INT, &value);
459 }
460
461 /// Add a `float` attribute to `extra_attribs`.
attribute(string_view name,float value)462 void attribute (string_view name, float value) {
463 attribute (name, TypeDesc::FLOAT, &value);
464 }
465
466 /// Add a string attribute to `extra_attribs`.
attribute(string_view name,string_view value)467 void attribute (string_view name, string_view value) {
468 std::string str(value);
469 const char *s = str.c_str();
470 attribute (name, TypeDesc::STRING, &s);
471 }
472
473 /// Parse a string containing a textual representation of a value of
474 /// the given `type`, and add that as an attribute to `extra_attribs`.
475 /// Example:
476 ///
477 /// spec.attribute ("temperature", TypeString, "-273.15");
478 ///
479 void attribute (string_view name, TypeDesc type, string_view value);
480
481 /// Searches `extra_attribs` for any attributes matching `name` (as a
482 /// regular expression), removing them entirely from `extra_attribs`. If
483 /// `searchtype` is anything other than `TypeDesc::UNKNOWN`, matches
484 /// will be restricted only to attributes with the given type. The name
485 /// comparison will be case-sensitive if `casesensitive` is true,
486 /// otherwise in a case-insensitive manner.
487 void erase_attribute (string_view name,
488 TypeDesc searchtype=TypeDesc::UNKNOWN,
489 bool casesensitive=false);
490
491 /// Searches `extra_attribs` for an attribute matching `name`, returning
492 /// a pointer to the attribute record, or NULL if there was no match.
493 /// If `searchtype` is anything other than `TypeDesc::UNKNOWN`, matches
494 /// will be restricted only to attributes with the given type. The name
495 /// comparison will be exact if `casesensitive` is true, otherwise in a
496 /// case-insensitive manner if `caseinsensitive` is false.
497 ParamValue * find_attribute (string_view name,
498 TypeDesc searchtype=TypeDesc::UNKNOWN,
499 bool casesensitive=false);
500 const ParamValue *find_attribute (string_view name,
501 TypeDesc searchtype=TypeDesc::UNKNOWN,
502 bool casesensitive=false) const;
503
504 /// Search for the named attribute and return the pointer to its
505 /// `ParamValue` record, or NULL if not found. This variety of
506 /// `find_attribute(}` can retrieve items such as "width", which are
507 /// data members of the `ImageSpec`, but not in `extra_attribs`. The
508 /// `tmpparam` is a storage area owned by the caller, which is used as
509 /// temporary buffer in cases where the information does not correspond
510 /// to an actual `extra_attribs` (in this case, the return value will be
511 /// `&tmpparam`). The extra names it understands are:
512 ///
513 /// - `"x"` `"y"` `"z"` `"width"` `"height"` `"depth"`
514 /// `"full_x"` `"full_y"` `"full_z"` `"full_width"` `"full_height"` `"full_depth"`
515 ///
516 /// Returns the `ImageSpec` fields of those names (despite the
517 /// fact that they are technically not arbitrary named attributes
518 /// in `extra_attribs`). All are of type `int`.
519 ///
520 /// - `"datawindow"`
521 ///
522 /// Without a type, or if requested explicitly as an `int[4]`,
523 /// returns the OpenEXR-like pixel data min and max coordinates,
524 /// as a 4-element integer array: `{ x, y, x+width-1, y+height-1
525 /// }`. If instead you specifically request as an `int[6]`, it
526 /// will return the volumetric data window, `{ x, y, z, x+width-1,
527 /// y+height-1, z+depth-1 }`.
528 ///
529 /// - `"displaywindow"`
530 ///
531 /// Without a type, or if requested explicitly as an `int[4]`,
532 /// returns the OpenEXR-like pixel display min and max
533 /// coordinates, as a 4-element integer array: `{ full_x, full_y,
534 /// full_x+full_width-1, full_y+full_height-1 }`. If instead you
535 /// specifically request as an `int[6]`, it will return the
536 /// volumetric display window, `{ full_x, full_y, full_z,
537 /// full_x+full_width-1, full_y+full_height-1, full_z+full_depth-1 }`.
538 ///
539 /// EXAMPLES
540 ///
541 /// ImageSpec spec; // has the info
542 /// Imath::Box2i dw; // we want the displaywindow here
543 /// ParamValue tmp; // so we can retrieve pseudo-values
544 /// TypeDesc int4("int[4]"); // Equivalent: TypeDesc int4(TypeDesc::INT,4);
545 /// const ParamValue* p = spec.find_attribute ("displaywindow", int4);
546 /// if (p)
547 /// dw = Imath::Box2i(p->get<int>(0), p->get<int>(1),
548 /// p->get<int>(2), p->get<int>(3));
549 ///
550 /// p = spec.find_attribute("temperature", TypeFloat);
551 /// if (p)
552 /// float temperature = p->get<float>();
553 ///
554 const ParamValue * find_attribute (string_view name,
555 ParamValue &tmpparam,
556 TypeDesc searchtype=TypeDesc::UNKNOWN,
557 bool casesensitive=false) const;
558
559 /// If the named attribute can be found in the `ImageSpec`, return its
560 /// data type. If no such attribute exists, return `TypeUnknown`.
561 ///
562 /// This was added in version 2.1.
563 TypeDesc getattributetype (string_view name,
564 bool casesensitive = false) const;
565
566 /// If the `ImageSpec` contains the named attribute and its type matches
567 /// `type`, copy the attribute value into the memory pointed to by `val`
568 /// (it is up to the caller to ensure there is enough space) and return
569 /// `true`. If no such attribute is found, or if it doesn't match the
570 /// type, return `false` and do not modify `val`.
571 ///
572 /// EXAMPLES:
573 ///
574 /// ImageSpec spec;
575 /// ...
576 /// // Retrieving an integer attribute:
577 /// int orientation = 0;
578 /// spec.getattribute ("orientation", TypeInt, &orientation);
579 ///
580 /// // Retrieving a string attribute with a char*:
581 /// const char* compression = nullptr;
582 /// spec.getattribute ("compression", TypeString, &compression);
583 ///
584 /// // Alternately, retrieving a string with a ustring:
585 /// ustring compression;
586 /// spec.getattribute ("compression", TypeString, &compression);
587 ///
588 /// Note that when passing a string, you need to pass a pointer to the
589 /// `char*`, not a pointer to the first character. Also, the `char*`
590 /// will end up pointing to characters owned by the `ImageSpec`; the
591 /// caller does not need to ever free the memory that contains the
592 /// characters.
593 ///
594 /// This was added in version 2.1.
595 bool getattribute (string_view name, TypeDesc type, void* value,
596 bool casesensitive = false) const;
597
598 /// Retrieve the named metadata attribute and return its value as an
599 /// `int`. Any integer type will convert to `int` by truncation or
600 /// expansion, string data will parsed into an `int` if its contents
601 /// consist of of the text representation of one integer. Floating point
602 /// data will not succeed in converting to an `int`. If no such metadata
603 /// exists, or are of a type that cannot be converted, the `defaultval`
604 /// will be returned.
605 int get_int_attribute (string_view name, int defaultval=0) const;
606
607 /// Retrieve the named metadata attribute and return its value as a
608 /// `float`. Any integer or floating point type will convert to `float`
609 /// in the obvious way (like a C cast), and so will string metadata if
610 /// its contents consist of of the text representation of one floating
611 /// point value. If no such metadata exists, or are of a type that cannot
612 /// be converted, the `defaultval` will be returned.
613 float get_float_attribute (string_view name, float defaultval=0) const;
614
615 /// Retrieve any metadata attribute, converted to a string.
616 /// If no such metadata exists, the `defaultval` will be returned.
617 string_view get_string_attribute (string_view name,
618 string_view defaultval = string_view()) const;
619
620 /// For a given parameter `p`, format the value nicely as a string. If
621 /// `human` is true, use especially human-readable explanations (units,
622 /// or decoding of values) for certain known metadata.
623 static std::string metadata_val (const ParamValue &p, bool human=false);
624
625 enum SerialFormat { SerialText, SerialXML };
626 enum SerialVerbose { SerialBrief, SerialDetailed, SerialDetailedHuman };
627
628 /// Returns, as a string, a serialized version of the `ImageSpec`. The
629 /// `format` may be either `ImageSpec::SerialText` or
630 /// `ImageSpec::SerialXML`. The `verbose` argument may be one of:
631 /// `ImageSpec::SerialBrief` (just resolution and other vital
632 /// statistics, one line for `SerialText`, `ImageSpec::SerialDetailed`
633 /// (contains all metadata in original form), or
634 /// `ImageSpec::SerialDetailedHuman` (contains all metadata, in many
635 /// cases with human-readable explanation).
636 std::string serialize (SerialFormat format,
637 SerialVerbose verbose = SerialDetailed) const;
638
639 /// Converts the contents of the `ImageSpec` as an XML string.
640 std::string to_xml () const;
641
642 /// Populates the fields of the `ImageSpec` based on the XML passed in.
643 void from_xml (const char *xml);
644
645 /// Hunt for the "Compression" and "CompressionQuality" settings in the
646 /// spec and turn them into the compression name and quality. This
647 /// handles compression name/qual combos of the form "name:quality".
648 std::pair<string_view, int>
649 decode_compression_metadata(string_view defaultcomp = "",
650 int defaultqual = -1) const;
651
652 /// Helper function to verify that the given pixel range exactly covers
653 /// a set of tiles. Also returns false if the spec indicates that the
654 /// image isn't tiled at all.
valid_tile_range(int xbegin,int xend,int ybegin,int yend,int zbegin,int zend)655 bool valid_tile_range (int xbegin, int xend, int ybegin, int yend,
656 int zbegin, int zend) noexcept {
657 return (tile_width &&
658 ((xbegin-x) % tile_width) == 0 &&
659 ((ybegin-y) % tile_height) == 0 &&
660 ((zbegin-z) % tile_depth) == 0 &&
661 (((xend-x) % tile_width) == 0 || (xend-x) == width) &&
662 (((yend-y) % tile_height) == 0 || (yend-y) == height) &&
663 (((zend-z) % tile_depth) == 0 || (zend-z) == depth));
664 }
665
666 /// Return the channelformat of the given channel. This is safe even
667 /// if channelformats is not filled out.
channelformat(int chan)668 TypeDesc channelformat (int chan) const {
669 return chan >= 0 && chan < (int)channelformats.size()
670 ? channelformats[chan] : format;
671 }
672
673 /// Return the channel name of the given channel. This is safe even if
674 /// channelnames is not filled out.
channel_name(int chan)675 string_view channel_name (int chan) const {
676 return chan >= 0 && chan < (int)channelnames.size()
677 ? string_view(channelnames[chan]) : "";
678 }
679
680 /// Fill in an array of channel formats describing all channels in
681 /// the image. (Note that this differs slightly from the member
682 /// data channelformats, which is empty if there are not separate
683 /// per-channel formats.)
get_channelformats(std::vector<TypeDesc> & formats)684 void get_channelformats (std::vector<TypeDesc> &formats) const {
685 formats = channelformats;
686 if ((int)formats.size() < nchannels)
687 formats.resize (nchannels, format);
688 }
689
690 /// Return the index of the channel with the given name, or -1 if no
691 /// such channel is present in `channelnames`.
692 int channelindex (string_view name) const;
693
694 /// Return pixel data window for this ImageSpec expressed as a ROI.
roi()695 ROI roi () const noexcept {
696 return ROI (x, x+width, y, y+height, z, z+depth, 0, nchannels);
697 }
698
699 /// Return full/display window for this ImageSpec expressed as a ROI.
roi_full()700 ROI roi_full () const noexcept {
701 return ROI (full_x, full_x+full_width, full_y, full_y+full_height,
702 full_z, full_z+full_depth, 0, nchannels);
703 }
704
705 /// Set pixel data window parameters (x, y, z, width, height, depth)
706 /// for this ImageSpec from an ROI.
707 /// Does NOT change the channels of the spec, regardless of r.
set_roi(const ROI & r)708 void set_roi (const ROI &r) noexcept {
709 x = r.xbegin;
710 y = r.ybegin;
711 z = r.zbegin;
712 width = r.width();
713 height = r.height();
714 depth = r.depth();
715 }
716
717 /// Set full/display window parameters (full_x, full_y, full_z,
718 /// full_width, full_height, full_depth) for this ImageSpec from an ROI.
719 /// Does NOT change the channels of the spec, regardless of r.
set_roi_full(const ROI & r)720 void set_roi_full (const ROI &r) noexcept {
721 full_x = r.xbegin;
722 full_y = r.ybegin;
723 full_z = r.zbegin;
724 full_width = r.width();
725 full_height = r.height();
726 full_depth = r.depth();
727 }
728
729 /// Copy from `other` the image dimensions (x, y, z, width, height,
730 /// depth, full*, nchannels, format) and data types. It does *not* copy
731 /// arbitrary named metadata or channel names (thus, for an `ImageSpec`
732 /// with lots of metadata, it is much less expensive than copying the
733 /// whole thing with `operator=()`).
copy_dimensions(const ImageSpec & other)734 void copy_dimensions (const ImageSpec &other) {
735 x = other.x;
736 y = other.y;
737 z = other.z;
738 width = other.width;
739 height = other.height;
740 depth = other.depth;
741 full_x = other.full_x;
742 full_y = other.full_y;
743 full_z = other.full_z;
744 full_width = other.full_width;
745 full_height = other.full_height;
746 full_depth = other.full_depth;
747 tile_width = other.tile_width;
748 tile_height = other.tile_height;
749 tile_depth = other.tile_depth;
750 nchannels = other.nchannels;
751 format = other.format;
752 channelformats = other.channelformats;
753 alpha_channel = other.alpha_channel;
754 z_channel = other.z_channel;
755 deep = other.deep;
756 }
757
758 /// Returns `true` for a newly initialized (undefined) `ImageSpec`.
759 /// (Designated by no channels and undefined data type -- true of the
760 /// uninitialized state of an ImageSpec, and presumably not for any
761 /// ImageSpec that is useful or purposefully made.)
undefined()762 bool undefined () const noexcept {
763 return nchannels == 0 && format == TypeUnknown;
764 }
765
766 /// Array indexing by string will create an AttrDelegate that enables a
767 /// convenient shorthand for adding and retrieving values from the spec:
768 ///
769 /// 1. Assigning to the delegate adds a metadata attribute:
770 ///
771 /// ImageSpec spec;
772 /// spec["foo"] = 42; // int
773 /// spec["pi"] = float(M_PI); // float
774 /// spec["oiio:ColorSpace"] = "sRGB"; // string
775 /// spec["cameratoworld"] = Imath::Matrix44(...); // matrix
776 ///
777 /// Be very careful, the attribute's type will be implied by the C++
778 /// type of what you assign.
779 ///
780 /// 2. String data may be retrieved directly, and for other types, the
781 /// delegate supports a get<T>() that retrieves an item of type T:
782 ///
783 /// std::string colorspace = spec["oiio:ColorSpace"];
784 /// int dither = spec["oiio:dither"].get<int>();
785 ///
786 /// This was added in version 2.1.
787 AttrDelegate<ImageSpec> operator[](string_view name)
788 {
789 return { this, name };
790 }
791 AttrDelegate<const ImageSpec> operator[](string_view name) const
792 {
793 return { this, name };
794 }
795 };
796
797
798
799
800 /// ImageInput abstracts the reading of an image file in a file
801 /// format-agnostic manner.
802 class OIIO_API ImageInput {
803 public:
804 /// unique_ptr to an ImageInput
805 using unique_ptr = std::unique_ptr<ImageInput>;
806
807 /// @{
808 /// @name Creating an ImageIntput
809
810 /// Create an ImageInput subclass instance that is able to read the
811 /// given file and open it, returning a `unique_ptr` to the ImageInput
812 /// if successful. The `unique_ptr` is set up with an appropriate
813 /// deleter so the ImageInput will be properly closed and deleted when
814 /// the `unique_ptr` goes out of scope or is reset. If the open fails,
815 /// return an empty `unique_ptr` and set an error that can be retrieved
816 /// by `OIIO::geterror()`.
817 ///
818 /// The `config`, if not nullptr, points to an ImageSpec giving hints,
819 /// requests, or special instructions. ImageInput implementations are
820 /// free to not respond to any such requests, so the default
821 /// implementation is just to ignore `config`.
822 ///
823 /// `open()` will first try to make an ImageInput corresponding to
824 /// the format implied by the file extension (for example, `"foo.tif"`
825 /// will try the TIFF plugin), but if one is not found or if the
826 /// inferred one does not open the file, every known ImageInput type
827 /// will be tried until one is found that will open the file.
828 ///
829 /// @param filename
830 /// The name of the file to open.
831 ///
832 /// @param config
833 /// Optional pointer to an ImageSpec whose metadata contains
834 /// "configuration hints."
835 ///
836 /// @param ioproxy
837 /// Optional pointer to an IOProxy to use (not supported by all
838 /// formats, see `supports("ioproxy")`). The caller retains
839 /// ownership of the proxy.
840 ///
841 /// @returns
842 /// A `unique_ptr` that will close and free the ImageInput when
843 /// it exits scope or is reset. The pointer will be empty if the
844 /// required writer was not able to be created.
845 static unique_ptr open (const std::string& filename,
846 const ImageSpec *config = nullptr,
847 Filesystem::IOProxy* ioproxy = nullptr);
848
849 /// Create and return an ImageInput implementation that is able to read
850 /// the given file or format. If `do_open` is true (and the `filename`
851 /// is the name of a file, not just a format), fully open it if possible
852 /// (using the optional `config` configuration spec, if supplied),
853 /// otherwise just create the ImageInput but don't open it. The
854 /// plugin_searchpath parameter is an override of the searchpath.
855 /// colon-separated list of directories to search for ImageIO plugin
856 /// DSO/DLL's (not a searchpath for the image itself!).
857 ///
858 /// If the `filename` parameter is the name of a file format (such as
859 /// "openexr"), it will create an ImageInput that reads that particular
860 /// format. If the name is a file extension (such as "exr" or ".exr"),
861 /// it will guess the file format from the extension and return that
862 /// type of ImageInput.
863 ///
864 /// If `filename` is a full file name (such as "hawaii.exr"), it will
865 /// create an ImageInput that reads the format implied by the file
866 /// extension (".tif") and try to open the file with that reader. If the
867 /// file can be opened and appears to be of the correct type, then that
868 /// ImageInput (after being closed) will be returned to the caller. But
869 /// if it fails (say, because the file type does not match the
870 /// extension), then every known kind of image reader will be tried in
871 /// turn, until one can be found that succeeds in opening that file. The
872 /// `create()` file will fail entirely only if no known image reader
873 /// type succeeds.
874 ///
875 /// If the caller intends to immediately open the file, then it is often
876 /// simpler to call static `ImageInput::open()`.
877 ///
878 /// @param filename
879 /// The name of an image file, or a file extension, or the name
880 /// of a file format.
881 ///
882 /// @param do_open
883 /// If `true`, not only create but also open the file.
884 ///
885 /// @param config
886 /// Optional pointer to an ImageSpec whose metadata contains
887 /// "configuration hints" for the ImageInput implementation.
888 ///
889 /// @param ioproxy
890 /// Optional pointer to an IOProxy to use (not supported by all
891 /// formats, see `supports("ioproxy")`). The caller retains
892 /// ownership of the proxy. If this is not supplied, it is still
893 /// possible to set the proxy with a call to `set_proxy()` prior
894 /// to `open()`.
895 ///
896 /// @param plugin_searchpath
897 /// An optional colon-separated list of directories to search
898 /// for OpenImageIO plugin DSO/DLL's.
899 ///
900 /// @returns
901 /// A `unique_ptr` that will close and free the ImageInput when
902 /// it exits scope or is reset. The pointer will be empty if the
903 /// required writer was not able to be created.
904 static unique_ptr create (string_view filename, bool do_open=false,
905 const ImageSpec *config=nullptr,
906 Filesystem::IOProxy* ioproxy = nullptr,
907 string_view plugin_searchpath = "");
908
909 // DEPRECATED(2.2): back compatible version
910 static unique_ptr create (const std::string& filename, bool do_open,
911 const ImageSpec *config,
912 string_view plugin_searchpath);
913 // DEPRECATED(2.1) This method should no longer be used, it is redundant.
914 static unique_ptr create (const std::string& filename,
915 const std::string& plugin_searchpath);
916
917 /// @}
918
919 // DEPRECATED(2.1)
920 static void destroy (ImageInput *x);
921
922 protected:
923 ImageInput ();
924 public:
925 virtual ~ImageInput ();
926
927 typedef std::recursive_mutex mutex;
928 typedef std::lock_guard<mutex> lock_guard;
929
930 /// Return the name of the format implemented by this class.
931 virtual const char *format_name (void) const = 0;
932
933 /// Given the name of a "feature", return whether this ImageInput
934 /// supports output of images with the given properties. Most queries
935 /// will simply return 0 for "doesn't support" and 1 for "supports it,"
936 /// but it is acceptable to have queries return other nonzero integers
937 /// to indicate varying degrees of support or limits (but should be
938 /// clearly documented as such).
939 ///
940 /// Feature names that ImageInput implementations are expected to
941 /// recognize include:
942 ///
943 /// - `"arbitrary_metadata"` : Does this format allow metadata with
944 /// arbitrary names and types?
945 ///
946 /// - `"exif"` :
947 /// Can this format store Exif camera data?
948 ///
949 /// - `"iptc"` :
950 /// Can this format store IPTC data?
951 ///
952 /// - `"procedural"` :
953 /// Can this format create images without reading from a disk
954 /// file?
955 ///
956 /// - `"ioproxy"` :
957 /// Does this format reader support reading from an `IOProxy`?
958 ///
959 /// This list of queries may be extended in future releases. Since this
960 /// can be done simply by recognizing new query strings, and does not
961 /// require any new API entry points, addition of support for new
962 /// queries does not break ``link compatibility'' with
963 /// previously-compiled plugins.
supports(string_view feature OIIO_MAYBE_UNUSED)964 virtual int supports (string_view feature OIIO_MAYBE_UNUSED) const {
965 return false;
966 }
967
968 /// Return true if the `filename` names a file of the type for this
969 /// ImageInput. The implementation will try to determine this as
970 /// efficiently as possible, in most cases much less expensively than
971 /// doing a full `open()`. Note that there can be false positives: a
972 /// file can appear to be of the right type (i.e., `valid_file()`
973 /// returning `true`) but still fail a subsequent call to `open()`, such
974 /// as if the contents of the file are truncated, nonsensical, or
975 /// otherwise corrupted.
976 ///
977 /// @returns
978 /// `true` upon success, or `false` upon failure.
979 virtual bool valid_file (const std::string& filename) const;
980
981 /// Opens the file with given name and seek to the first subimage in the
982 /// file. Various file attributes are put in `newspec` and a copy
983 /// is also saved internally to the `ImageInput` (retrievable via
984 /// `spec()`. From examining `newspec` or `spec()`, you can
985 /// discern the resolution, if it's tiled, number of channels, native
986 /// data format, and other metadata about the image.
987 ///
988 /// @param name
989 /// Filename to open.
990 ///
991 /// @param newspec
992 /// Reference to an ImageSpec in which to deposit a full
993 /// description of the contents of the first subimage of the
994 /// file.
995 ///
996 /// @returns
997 /// `true` if the file was found and opened successfully.
998 virtual bool open (const std::string& name, ImageSpec &newspec) = 0;
999
1000 /// Open file with given name, similar to `open(name,newspec)`. The
1001 /// `config` is an ImageSpec giving requests or special instructions.
1002 /// ImageInput implementations are free to not respond to any such
1003 /// requests, so the default implementation is just to ignore config and
1004 /// call regular `open(name,newspec)`.
1005 ///
1006 /// @param name
1007 /// Filename to open.
1008 ///
1009 /// @param newspec
1010 /// Reference to an ImageSpec in which to deposit a full
1011 /// description of the contents of the first subimage of the
1012 /// file.
1013 ///
1014 /// @param config
1015 /// An ImageSpec whose metadata contains "configuration hints"
1016 /// for the ImageInput implementation.
1017 ///
1018 /// @returns
1019 /// `true` if the file was found and opened successfully.
open(const std::string & name,ImageSpec & newspec,const ImageSpec & config OIIO_MAYBE_UNUSED)1020 virtual bool open (const std::string& name, ImageSpec &newspec,
1021 const ImageSpec& config OIIO_MAYBE_UNUSED) {
1022 return open(name,newspec);
1023 }
1024
1025 /// Return a reference to the image specification of the current
1026 /// subimage/MIPlevel. Note that the contents of the spec are invalid
1027 /// before `open()` or after `close()`, and may change with a call to
1028 /// `seek_subimage()`. It is thus not thread-safe, since the spec may
1029 /// change if another thread calls `seek_subimage`, or any of the
1030 /// `read_*()` functions that take explicit subimage/miplevel.
spec(void)1031 virtual const ImageSpec &spec (void) const { return m_spec; }
1032
1033 /// Return a full copy of the ImageSpec of the designated subimage and
1034 /// MIPlevel. This method is thread-safe, but it is potentially
1035 /// expensive, due to the work that needs to be done to fully copy an
1036 /// ImageSpec if there is lots of named metadata to allocate and copy.
1037 /// See also the less expensive `spec_dimensions()`. Errors (such as
1038 /// having requested a nonexistent subimage) are indicated by returning
1039 /// an ImageSpec with `format==TypeUnknown`.
1040 virtual ImageSpec spec (int subimage, int miplevel=0);
1041
1042 /// Return a copy of the ImageSpec of the designated subimage and
1043 /// miplevel, but only the dimension and type fields. Just as with a
1044 /// call to `ImageSpec::copy_dimensions()`, neither the channel names
1045 /// nor any of the arbitrary named metadata will be copied, thus this is
1046 /// a relatively inexpensive operation if you don't need that
1047 /// information. It is guaranteed to be thread-safe. Errors (such as
1048 /// having requested a nonexistent subimage) are indicated by returning
1049 /// an ImageSpec with `format==TypeUnknown`.
1050 virtual ImageSpec spec_dimensions (int subimage, int miplevel=0);
1051
1052 /// Close an open ImageInput. The call to close() is not strictly
1053 /// necessary if the ImageInput is destroyed immediately afterwards,
1054 /// since it is required for the destructor to close if the file is
1055 /// still open.
1056 ///
1057 /// @returns
1058 /// `true` upon success, or `false` upon failure.
1059 virtual bool close () = 0;
1060
1061 /// Returns the index of the subimage that is currently being read.
1062 /// The first subimage (or the only subimage, if there is just one)
1063 /// is number 0.
current_subimage(void)1064 virtual int current_subimage (void) const { return 0; }
1065
1066 /// Returns the index of the MIPmap image that is currently being read.
1067 /// The highest-res MIP level (or the only level, if there is just
1068 /// one) is number 0.
current_miplevel(void)1069 virtual int current_miplevel (void) const { return 0; }
1070
1071 /// Seek to the given subimage and MIP-map level within the open image
1072 /// file. The first subimage of the file has index 0, the highest-
1073 /// resolution MIP level has index 0. The new subimage's vital
1074 /// statistics=may be retrieved by `this->spec()`. The reader is
1075 /// expected to give the appearance of random access to subimages and
1076 /// MIP levels -- in other words, if it can't randomly seek to the given
1077 /// subimage/level, it should transparently close, reopen, and
1078 /// sequentially read through prior subimages and levels.
1079 ///
1080 /// @returns
1081 /// `true` upon success, or `false` upon failure. A failure may
1082 /// indicate that no such subimage or MIP level exists in the
1083 /// file.
seek_subimage(int subimage,int miplevel)1084 virtual bool seek_subimage (int subimage, int miplevel) {
1085 // Default implementation assumes no support for subimages or
1086 // mipmaps, so there is no work to do.
1087 return subimage == current_subimage() && miplevel == current_miplevel();
1088 }
1089
1090 // Old version for backwards-compatibility: pass reference to newspec.
1091 // Some day this will be deprecated.
seek_subimage(int subimage,int miplevel,ImageSpec & newspec)1092 bool seek_subimage (int subimage, int miplevel, ImageSpec &newspec) {
1093 bool ok = seek_subimage (subimage, miplevel);
1094 if (ok)
1095 newspec = spec();
1096 return ok;
1097 }
1098
1099 // DEPRECATED(2.1)
1100 // Seek to the given subimage -- backwards-compatible call that
1101 // doesn't worry about MIP-map levels at all.
seek_subimage(int subimage,ImageSpec & newspec)1102 bool seek_subimage (int subimage, ImageSpec &newspec) {
1103 return seek_subimage (subimage, 0 /* miplevel */, newspec);
1104 }
1105
1106 /// @{
1107 /// @name Reading pixels
1108 ///
1109 /// Common features of all the `read` methods:
1110 ///
1111 /// * The `format` parameter describes the data type of the `data[]`
1112 /// buffer. The read methods automatically convert the data from the
1113 /// data type it is stored in the file into the `format` of the `data`
1114 /// buffer. If `format` is `TypeUnknown` it will just copy pixels of
1115 /// file's native data layout (including, possibly, per-channel data
1116 /// formats as specified by the ImageSpec's `channelfomats` field).
1117 ///
1118 /// * The `stride` values describe the layout of the `data` buffer:
1119 /// `xstride` is the distance in bytes between successive pixels
1120 /// within each scanline. `ystride` is the distance in bytes between
1121 /// successive scanlines. For volumetric images `zstride` is the
1122 /// distance in bytes between successive "volumetric planes". Strides
1123 /// set to the special value `AutoStride` imply contiguous data, i.e.,
1124 ///
1125 /// xstride = format.size() * nchannels
1126 /// ystride = xstride * width
1127 /// zstride = ystride * height
1128 ///
1129 /// * Any *range* parameters (such as `ybegin` and `yend`) describe a
1130 /// "half open interval", meaning that `begin` is the first item and
1131 /// `end` is *one past the last item*. That means that the number of
1132 /// items is `end - begin`.
1133 ///
1134 /// * For ordinary 2D (non-volumetric) images, any `z` or `zbegin`
1135 /// coordinates should be 0 and any `zend` should be 1, indicating
1136 /// that only a single image "plane" exists.
1137 ///
1138 /// * Some read methods take a channel range [chbegin,chend) to allow
1139 /// reading of a contiguous subset of channels (chbegin=0,
1140 /// chend=spec.nchannels reads all channels).
1141 ///
1142 /// * ImageInput readers are expected to give the appearance of random
1143 /// access -- in other words, if it can't randomly seek to the given
1144 /// scanline or tile, it should transparently close, reopen, and
1145 /// sequentially read through prior scanlines.
1146 ///
1147 /// * All read functions return `true` for success, `false` for failure
1148 /// (after which a call to `geterror()` may retrieve a specific error
1149 /// message).
1150 ///
1151
1152 /// Read the scanline that includes pixels (*,y,z) from the "current"
1153 /// subimage and MIP level. The `xstride` value gives the distance
1154 /// between successive pixels (in bytes). Strides set to `AutoStride`
1155 /// imply "contiguous" data.
1156 ///
1157 /// @note This variety of `read_scanline` is not re-entrant nor
1158 /// thread-safe. If you require concurrent reads to the same open
1159 /// ImageInput, you should use `read_scanlines` that has the `subimage`
1160 /// and `miplevel` passed explicitly.
1161 ///
1162 /// @param y/z The y & z coordinates of the scanline. For 2D
1163 /// images, z should be 0.
1164 /// @param format A TypeDesc describing the type of `data`.
1165 /// @param data Pointer to the pixel data buffer.
1166 /// @param xstride The distance in bytes between successive
1167 /// pixels in `data` (or `AutoStride`).
1168 /// @returns `true` upon success, or `false` upon failure.
1169 virtual bool read_scanline (int y, int z, TypeDesc format, void *data,
1170 stride_t xstride=AutoStride);
1171
1172 /// Simple read_scanline reads into contiguous float pixels.
read_scanline(int y,int z,float * data)1173 bool read_scanline (int y, int z, float *data) {
1174 return read_scanline (y, z, TypeFloat, data);
1175 }
1176
1177 /// Read multiple scanlines that include pixels (*,y,z) for all ybegin
1178 /// <= y < yend in the specified subimage and mip level, into `data`,
1179 /// using the strides given and converting to the requested data
1180 /// `format` (TypeUnknown indicates no conversion, just copy native data
1181 /// types). Only channels [chbegin,chend) will be read/copied
1182 /// (chbegin=0, chend=spec.nchannels reads all channels, yielding
1183 /// equivalent behavior to the simpler variant of `read_scanlines`).
1184 ///
1185 /// This version of read_scanlines, because it passes explicit
1186 /// subimage/miplevel, does not require a separate call to
1187 /// seek_subimage, and is guaranteed to be thread-safe against other
1188 /// concurrent calls to any of the read_* methods that take an explicit
1189 /// subimage/miplevel (but not against any other ImageInput methods).
1190 ///
1191 /// @param subimage The subimage to read from (starting with 0).
1192 /// @param miplevel The MIP level to read (0 is the highest
1193 /// resolution level).
1194 /// @param ybegin/yend The y range of the scanlines being passed.
1195 /// @param z The z coordinate of the scanline.
1196 /// @param chbegin/chend
1197 /// The channel range to read.
1198 /// @param format A TypeDesc describing the type of `data`.
1199 /// @param data Pointer to the pixel data.
1200 /// @param xstride/ystride
1201 /// The distance in bytes between successive pixels
1202 /// and scanlines (or `AutoStride`).
1203 /// @returns `true` upon success, or `false` upon failure.
1204 ///
1205 /// @note This call was changed for OpenImageIO 2.0 to include the
1206 /// explicit subimage and miplevel parameters. The previous
1207 /// versions, which lacked subimage and miplevel parameters (thus
1208 /// were dependent on a prior call to `seek_subimage`) are
1209 /// considered deprecated.
1210 virtual bool read_scanlines (int subimage, int miplevel,
1211 int ybegin, int yend, int z,
1212 int chbegin, int chend,
1213 TypeDesc format, void *data,
1214 stride_t xstride=AutoStride,
1215 stride_t ystride=AutoStride);
1216
1217 // DEPRECATED versions of read_scanlines (pre-1.9 OIIO). These will
1218 // eventually be removed. Try to replace these calls with ones to the
1219 // new variety of read_scanlines that takes an explicit subimage and
1220 // miplevel. These old versions are NOT THREAD-SAFE.
1221 bool read_scanlines (int ybegin, int yend, int z,
1222 TypeDesc format, void *data,
1223 stride_t xstride=AutoStride,
1224 stride_t ystride=AutoStride);
1225 bool read_scanlines (int ybegin, int yend, int z,
1226 int chbegin, int chend,
1227 TypeDesc format, void *data,
1228 stride_t xstride=AutoStride,
1229 stride_t ystride=AutoStride);
1230
1231 /// Read the tile whose upper-left origin is (x,y,z) into `data[]`,
1232 /// converting if necessary from the native data format of the file into
1233 /// the `format` specified. The stride values give the data spacing of
1234 /// adjacent pixels, scanlines, and volumetric slices (measured in
1235 /// bytes). Strides set to AutoStride imply 'contiguous' data in the
1236 /// shape of a full tile, i.e.,
1237 ///
1238 /// xstride = format.size() * spec.nchannels
1239 /// ystride = xstride * spec.tile_width
1240 /// zstride = ystride * spec.tile_height
1241 ///
1242 /// @note This variety of `read_tile` is not re-entrant nor thread-safe.
1243 /// If you require concurrent reads to the same open ImageInput, you
1244 /// should use `read_tiles()` that has the `subimage` and `miplevel`
1245 /// passed explicitly.
1246 ///
1247 /// @param x/y/z The upper left coordinate of the tile being passed.
1248 /// @param format A TypeDesc describing the type of `data`.
1249 /// @param data Pointer to the pixel data.
1250 /// @param xstride/ystride/zstride
1251 /// The distance in bytes between successive pixels,
1252 /// scanlines, and image planes (or `AutoStride` to
1253 /// indicate a "contiguous" single tile).
1254 /// @returns `true` upon success, or `false` upon failure.
1255 ///
1256 /// @note This call will fail if the image is not tiled, or if (x,y,z)
1257 /// is not the upper left corner coordinates of a tile.
1258 virtual bool read_tile (int x, int y, int z, TypeDesc format,
1259 void *data, stride_t xstride=AutoStride,
1260 stride_t ystride=AutoStride,
1261 stride_t zstride=AutoStride);
1262
1263 /// Simple read_tile reads into contiguous float pixels.
read_tile(int x,int y,int z,float * data)1264 bool read_tile (int x, int y, int z, float *data) {
1265 return read_tile (x, y, z, TypeDesc::FLOAT, data,
1266 AutoStride, AutoStride, AutoStride);
1267 }
1268
1269 /// Read the block of multiple tiles that include all pixels in
1270 ///
1271 /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend)
1272 ///
1273 /// This is analogous to calling `read_tile(x,y,z,...)` for each tile
1274 /// in turn (but for some file formats, reading multiple tiles may allow
1275 /// it to read more efficiently or in parallel).
1276 ///
1277 /// The begin/end pairs must correctly delineate tile boundaries, with
1278 /// the exception that it may also be the end of the image data if the
1279 /// image resolution is not a whole multiple of the tile size. The
1280 /// stride values give the data spacing of adjacent pixels, scanlines,
1281 /// and volumetric slices (measured in bytes). Strides set to AutoStride
1282 /// imply contiguous data in the shape of the [begin,end) region, i.e.,
1283 ///
1284 /// xstride = format.size() * spec.nchannels
1285 /// ystride = xstride * (xend-xbegin)
1286 /// zstride = ystride * (yend-ybegin)
1287 ///
1288 /// This version of read_tiles, because it passes explicit subimage and
1289 /// miplevel, does not require a separate call to seek_subimage, and is
1290 /// guaranteed to be thread-safe against other concurrent calls to any
1291 /// of the read_* methods that take an explicit subimage/miplevel (but
1292 /// not against any other ImageInput methods).
1293 ///
1294 /// @param subimage The subimage to read from (starting with 0).
1295 /// @param miplevel The MIP level to read (0 is the highest
1296 /// resolution level).
1297 /// @param xbegin/xend The x range of the pixels covered by the group
1298 /// of tiles being read.
1299 /// @param ybegin/yend The y range of the pixels covered by the tiles.
1300 /// @param zbegin/zend The z range of the pixels covered by the tiles
1301 /// (for a 2D image, zbegin=0 and zend=1).
1302 /// @param chbegin/chend
1303 /// The channel range to read.
1304 /// @param format A TypeDesc describing the type of `data`.
1305 /// @param data Pointer to the pixel data.
1306 /// @param xstride/ystride/zstride
1307 /// The distance in bytes between successive pixels,
1308 /// scanlines, and image planes (or `AutoStride`).
1309 /// @returns `true` upon success, or `false` upon failure.
1310 ///
1311 /// @note The call will fail if the image is not tiled, or if the pixel
1312 /// ranges do not fall along tile (or image) boundaries, or if it is not
1313 /// a valid tile range.
1314 virtual bool read_tiles (int subimage, int miplevel, int xbegin, int xend,
1315 int ybegin, int yend, int zbegin, int zend,
1316 int chbegin, int chend, TypeDesc format, void *data,
1317 stride_t xstride=AutoStride, stride_t ystride=AutoStride,
1318 stride_t zstride=AutoStride);
1319
1320 // DEPRECATED versions of read_tiles (pre-1.9 OIIO). These will
1321 // eventually be removed. Try to replace these calls with ones to the
1322 // new variety of read_tiles that takes an explicit subimage and
1323 // miplevel. These old versions are NOT THREAD-SAFE.
1324 bool read_tiles (int xbegin, int xend, int ybegin, int yend,
1325 int zbegin, int zend, TypeDesc format, void *data,
1326 stride_t xstride=AutoStride, stride_t ystride=AutoStride,
1327 stride_t zstride=AutoStride);
1328 bool read_tiles (int xbegin, int xend, int ybegin, int yend,
1329 int zbegin, int zend, int chbegin, int chend,
1330 TypeDesc format, void *data, stride_t xstride=AutoStride,
1331 stride_t ystride=AutoStride, stride_t zstride=AutoStride);
1332
1333 /// Read the entire image of `spec.width x spec.height x spec.depth`
1334 /// pixels into a buffer with the given strides and in the desired
1335 /// data format.
1336 ///
1337 /// Depending on the spec, this will read either all tiles or all
1338 /// scanlines. Assume that data points to a layout in row-major order.
1339 ///
1340 /// This version of read_image, because it passes explicit subimage and
1341 /// miplevel, does not require a separate call to seek_subimage, and is
1342 /// guaranteed to be thread-safe against other concurrent calls to any
1343 /// of the read_* methods that take an explicit subimage/miplevel (but
1344 /// not against any other ImageInput methods).
1345 ///
1346 /// Because this may be an expensive operation, a progress callback
1347 /// may be passed. Periodically, it will be called as follows:
1348 ///
1349 /// progress_callback (progress_callback_data, float done);
1350 ///
1351 /// where `done` gives the portion of the image (between 0.0 and 1.0)
1352 /// that has been written thus far.
1353 ///
1354 /// @param subimage The subimage to read from (starting with 0).
1355 /// @param miplevel The MIP level to read (0 is the highest
1356 /// resolution level).
1357 /// @param chbegin/chend
1358 /// The channel range to read.
1359 /// @param format A TypeDesc describing the type of `data`.
1360 /// @param data Pointer to the pixel data.
1361 /// @param xstride/ystride/zstride
1362 /// The distance in bytes between successive pixels,
1363 /// scanlines, and image planes (or `AutoStride`).
1364 /// @param progress_callback/progress_callback_data
1365 /// Optional progress callback.
1366 /// @returns `true` upon success, or `false` upon failure.
1367 virtual bool read_image (int subimage, int miplevel,
1368 int chbegin, int chend,
1369 TypeDesc format, void *data,
1370 stride_t xstride=AutoStride,
1371 stride_t ystride=AutoStride,
1372 stride_t zstride=AutoStride,
1373 ProgressCallback progress_callback=NULL,
1374 void *progress_callback_data=NULL);
1375
1376 // DEPRECATED versions of read_image (pre-1.9 OIIO). These will
1377 // eventually be removed. Try to replace these calls with ones to the
1378 // new variety of read_image that takes an explicit subimage and
1379 // miplevel. These old versions are NOT THREAD-SAFE.
1380 virtual bool read_image (TypeDesc format, void *data,
1381 stride_t xstride=AutoStride,
1382 stride_t ystride=AutoStride,
1383 stride_t zstride=AutoStride,
1384 ProgressCallback progress_callback=NULL,
1385 void *progress_callback_data=NULL);
1386 virtual bool read_image (int chbegin, int chend,
1387 TypeDesc format, void *data,
1388 stride_t xstride=AutoStride,
1389 stride_t ystride=AutoStride,
1390 stride_t zstride=AutoStride,
1391 ProgressCallback progress_callback=NULL,
1392 void *progress_callback_data=NULL);
read_image(float * data)1393 bool read_image (float *data) {
1394 return read_image (TypeDesc::FLOAT, data);
1395 }
1396
1397 /// Read deep scanlines containing pixels (*,y,z), for all y in the
1398 /// range [ybegin,yend) into `deepdata`. This will fail if it is not a
1399 /// deep file.
1400 ///
1401 /// @param subimage The subimage to read from (starting with 0).
1402 /// @param miplevel The MIP level to read (0 is the highest
1403 /// resolution level).
1404 /// @param chbegin/chend
1405 /// The channel range to read.
1406 /// @param ybegin/yend The y range of the scanlines being passed.
1407 /// @param z The z coordinate of the scanline.
1408 /// @param deepdata A `DeepData` object into which the data for
1409 /// these scanlines will be placed.
1410 /// @returns `true` upon success, or `false` upon failure.
1411 virtual bool read_native_deep_scanlines (int subimage, int miplevel,
1412 int ybegin, int yend, int z,
1413 int chbegin, int chend,
1414 DeepData &deepdata);
1415
1416 /// Read into `deepdata` the block of native deep data tiles that
1417 /// include all pixels and channels specified by pixel range.
1418 ///
1419 /// @param subimage The subimage to read from (starting with 0).
1420 /// @param miplevel The MIP level to read (0 is the highest
1421 /// resolution level).
1422 /// @param xbegin/xend The x range of the pixels covered by the group
1423 /// of tiles being read.
1424 /// @param ybegin/yend The y range of the pixels covered by the tiles.
1425 /// @param zbegin/zend The z range of the pixels covered by the tiles
1426 /// (for a 2D image, zbegin=0 and zend=1).
1427 /// @param chbegin/chend
1428 /// The channel range to read.
1429 /// @param deepdata A `DeepData` object into which the data for
1430 /// these tiles will be placed.
1431 /// @returns `true` upon success, or `false` upon failure.
1432 ///
1433 /// @note The call will fail if the image is not tiled, or if the pixel
1434 /// ranges do not fall along tile (or image) boundaries, or if it is not
1435 /// a valid tile range.
1436 virtual bool read_native_deep_tiles (int subimage, int miplevel,
1437 int xbegin, int xend,
1438 int ybegin, int yend,
1439 int zbegin, int zend,
1440 int chbegin, int chend,
1441 DeepData &deepdata);
1442
1443 /// Read the entire deep data image of spec.width x spec.height x
1444 /// spec.depth pixels, all channels, into `deepdata`.
1445 ///
1446 /// @param subimage The subimage to read from (starting with 0).
1447 /// @param miplevel The MIP level to read (0 is the highest
1448 /// resolution level).
1449 /// @param deepdata A `DeepData` object into which the data for
1450 /// the image will be placed.
1451 /// @returns `true` upon success, or `false` upon failure.
1452 virtual bool read_native_deep_image (int subimage, int miplevel,
1453 DeepData &deepdata);
1454
1455 // DEPRECATED(1.9), Now just used for back compatibility:
read_native_deep_scanlines(int ybegin,int yend,int z,int chbegin,int chend,DeepData & deepdata)1456 bool read_native_deep_scanlines (int ybegin, int yend, int z,
1457 int chbegin, int chend, DeepData &deepdata) {
1458 return read_native_deep_scanlines (current_subimage(), current_miplevel(),
1459 ybegin, yend, z,
1460 chbegin, chend, deepdata);
1461 }
read_native_deep_tiles(int xbegin,int xend,int ybegin,int yend,int zbegin,int zend,int chbegin,int chend,DeepData & deepdata)1462 bool read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend,
1463 int zbegin, int zend, int chbegin, int chend,
1464 DeepData &deepdata) {
1465 return read_native_deep_tiles (current_subimage(), current_miplevel(),
1466 xbegin, xend, ybegin, yend,
1467 zbegin, zend, chbegin, chend, deepdata);
1468 }
read_native_deep_image(DeepData & deepdata)1469 bool read_native_deep_image (DeepData &deepdata) {
1470 return read_native_deep_image (current_subimage(), current_miplevel(),
1471 deepdata);
1472 }
1473
1474 /// @}
1475
1476 /// @{
1477 /// @name Reading native pixels -- implementation overloads
1478 ///
1479 /// @note read_native_* methods are usually not directly called by user
1480 /// code (except for read_native_deep_* varieties). These are the
1481 /// methods that are overloaded by the ImageInput subclasses that
1482 /// implement the individual file format readers.
1483 //
1484 // The read_native_* methods always read the "native" data types
1485 // (including per-channel data types) and assume that `data` points to
1486 // contiguous memory (no non-default strides). In contrast, the
1487 // read_scanline/scanlines/tile/tiles handle data type translation and
1488 // arbitrary strides.
1489 //
1490 // The read_native_* methods take an explicit subimage and miplevel, and
1491 // thus do not require a prior call to seek_subimage (and therefore no
1492 // saved state). They are all required to be thread-safe when called
1493 // concurrently with any other read_native_* call or with the varieties
1494 // of read_tiles() that also takes an explicit subimage and miplevel
1495 // parameter.
1496 //
1497 // As far as format-reading ImageInput subclasses are concerned, the
1498 // only truly required overloads are read_native_scanline (always) and
1499 // read_native_tile (only for formats that support tiles). The other
1500 // varieties are special cases, for example if the particular format is
1501 // able to efficiently read multiple scanlines or tiles at once, and if
1502 // the subclass does not provide overloads, the base class
1503 // implementaiton will be used instead, which is implemented by reducing
1504 // the operation to multiple calls to read_scanline or read_tile.
1505
1506 /// Read a single scanline (all channels) of native data into contiguous
1507 /// memory.
1508 virtual bool read_native_scanline (int subimage, int miplevel,
1509 int y, int z, void *data) = 0;
1510 /// Read a range of scanlines (all channels) of native data into
1511 /// contiguous memory.
1512 virtual bool read_native_scanlines (int subimage, int miplevel,
1513 int ybegin, int yend, int z,
1514 void *data);
1515 /// Read a range of scanlines (with optionally a subset of channels) of
1516 /// native data into contiguous memory.
1517 virtual bool read_native_scanlines (int subimage, int miplevel,
1518 int ybegin, int yend, int z,
1519 int chbegin, int chend, void *data);
1520
1521 /// Read a single tile (all channels) of native data into contiguous
1522 /// memory. The base class read_native_tile fails. A format reader that
1523 /// supports tiles MUST overload this virtual method that reads a single
1524 /// tile (all channels).
1525 virtual bool read_native_tile (int subimage, int miplevel,
1526 int x, int y, int z, void *data);
1527
1528 /// Read multiple tiles (all channels) of native data into contigious
1529 /// memory. A format reader that supports reading multiple tiles at once
1530 /// (in a way that's more efficient than reading the tiles one at a
1531 /// time) is advised (but not required) to overload this virtual method.
1532 /// If an ImageInput subclass does not overload this, the default
1533 /// implementation here is simply to loop over the tiles, calling the
1534 /// single-tile read_native_tile() for each one.
1535 virtual bool read_native_tiles (int subimage, int miplevel,
1536 int xbegin, int xend, int ybegin, int yend,
1537 int zbegin, int zend, void *data);
1538
1539 /// Read multiple tiles (potentially a subset of channels) of native
1540 /// data into contigious memory. A format reader that supports reading
1541 /// multiple tiles at once, and can handle a channel subset while doing
1542 /// so, is advised (but not required) to overload this virtual method.
1543 /// If an ImageInput subclass does not overload this, the default
1544 /// implementation here is simply to loop over the tiles, calling the
1545 /// single-tile read_native_tile() for each one (and copying carefully
1546 /// to handle the channel subset issues).
1547 virtual bool read_native_tiles (int subimage, int miplevel,
1548 int xbegin, int xend, int ybegin, int yend,
1549 int zbegin, int zend,
1550 int chbegin, int chend, void *data);
1551 /// @}
1552
1553
1554 // General message passing between client and image input server. This
1555 // is currently undefined and is reserved for future use.
1556 virtual int send_to_input (const char *format, ...);
1557 int send_to_client (const char *format, ...);
1558
1559 /// Set an IOProxy for this reader. This must be called prior to
1560 /// `open()`, and only for readers that support them
1561 /// (`supports("ioproxy")`). The caller retains ownership of the proxy.
1562 ///
1563 /// @returns `true` for success, `false` for failure.
set_ioproxy(Filesystem::IOProxy * ioproxy)1564 virtual bool set_ioproxy (Filesystem::IOProxy* ioproxy) {
1565 return (ioproxy == nullptr);
1566 }
1567
1568 /// If any of the API routines returned false indicating an error, this
1569 /// method will return the error string (and clear any error flags). If
1570 /// no error has occurred since the last time `geterror()` was called,
1571 /// it will return an empty string.
geterror()1572 std::string geterror () const {
1573 lock_guard lock (m_mutex);
1574 std::string e = m_errmessage;
1575 m_errmessage.clear ();
1576 return e;
1577 }
1578
1579 /// Error reporting for the plugin implementation: call this with
1580 /// Strutil::format-like arguments.
1581 /// Use with caution! Some day this will change to be fmt-like rather
1582 /// than printf-like.
1583 template<typename... Args>
error(const char * fmt,const Args &...args)1584 void error(const char* fmt, const Args&... args) const {
1585 append_error(Strutil::format (fmt, args...));
1586 }
1587
1588 /// Error reporting for the plugin implementation: call this with
1589 /// printf-like arguments.
1590 template<typename... Args>
errorf(const char * fmt,const Args &...args)1591 void errorf(const char* fmt, const Args&... args) const {
1592 append_error(Strutil::sprintf (fmt, args...));
1593 }
1594
1595 /// Error reporting for the plugin implementation: call this with
1596 /// fmt::format-like arguments.
1597 template<typename... Args>
errorfmt(const char * fmt,const Args &...args)1598 void errorfmt(const char* fmt, const Args&... args) const {
1599 append_error(Strutil::fmt::format (fmt, args...));
1600 }
1601
1602 // Error reporting for the plugin implementation: call this with
1603 // fmt::format-like arguments.
1604 template<typename... Args>
1605 OIIO_DEPRECATED("use `errorfmt` instead")
fmterror(const char * fmt,const Args &...args)1606 void fmterror(const char* fmt, const Args&... args) const {
1607 append_error(Strutil::fmt::format (fmt, args...));
1608 }
1609
1610 /// Set the threading policy for this ImageInput, controlling the
1611 /// maximum amount of parallelizing thread "fan-out" that might occur
1612 /// during large read operations. The default of 0 means that the global
1613 /// `attribute("threads")` value should be used (which itself defaults
1614 /// to using as many threads as cores; see Section `Global Attributes`_).
1615 ///
1616 /// The main reason to change this value is to set it to 1 to indicate
1617 /// that the calling thread should do all the work rather than spawning
1618 /// new threads. That is probably the desired behavior in situations
1619 /// where the calling application has already spawned multiple worker
1620 /// threads.
threads(int n)1621 void threads (int n) { m_threads = n; }
1622
1623 /// Retrieve the current thread-spawning policy.
1624 /// @see `threads(int)`
threads()1625 int threads () const { return m_threads; }
1626
1627 /// Lock the internal mutex, block until the lock is acquired.
lock()1628 void lock () { m_mutex.lock(); }
1629 /// Try to lock the internal mutex, returning true if successful, or
1630 /// false if the lock could not be immediately acquired.
try_lock()1631 bool try_lock () { return m_mutex.try_lock(); }
1632 /// Ulock the internal mutex.
unlock()1633 void unlock () { m_mutex.unlock(); }
1634
1635 // Custom new and delete to ensure that allocations & frees happen in
1636 // the OpenImageIO library, not in the app or plugins (because Windows).
1637 void* operator new (size_t size);
1638 void operator delete (void *ptr);
1639
1640 /// Call signature of a function that creates and returns an
1641 /// `ImageInput*`.
1642 typedef ImageInput* (*Creator)();
1643
1644 protected:
1645 mutable mutex m_mutex; // lock of the thread-safe methods
1646 ImageSpec m_spec; // format spec of the current open subimage/MIPlevel
1647 // BEWARE using m_spec directly -- not thread-safe
1648
1649 private:
1650 mutable std::string m_errmessage; // private storage of error message
1651 int m_threads; // Thread policy
1652 void append_error (const std::string& message) const; // add to m_errmessage
1653 // Deprecated:
1654 static unique_ptr create (const std::string& filename, bool do_open,
1655 const std::string& plugin_searchpath);
1656 };
1657
1658
1659
1660
1661 /// ImageOutput abstracts the writing of an image file in a file
1662 /// format-agnostic manner.
1663 ///
1664 /// Users don't directly declare these. Instead, you call the `create()`
1665 /// static method, which will return a `unique_ptr` holding a subclass of
1666 /// ImageOutput that implements writing the particular format.
1667 ///
1668 class OIIO_API ImageOutput {
1669 public:
1670 /// unique_ptr to an ImageOutput.
1671 using unique_ptr = std::unique_ptr<ImageOutput>;
1672
1673 /// @{
1674 /// @name Creating an ImageOutput
1675
1676 /// Create an `ImageOutput` that can be used to write an image file.
1677 /// The type of image file (and hence, the particular subclass of
1678 /// `ImageOutput` returned, and the plugin that contains its methods) is
1679 /// inferred from the name, if it appears to be a full filename, or it
1680 /// may also name the format.
1681 ///
1682 /// @param filename
1683 /// The name of the file format (e.g., "openexr"), a file
1684 /// extension (e.g., "exr"), or a filename from which the the
1685 /// file format can be inferred from its extension (e.g.,
1686 /// "hawaii.exr").
1687 ///
1688 /// @param plugin_searchpath
1689 /// An optional colon-separated list of directories to search
1690 /// for OpenImageIO plugin DSO/DLL's.
1691 ///
1692 /// @param ioproxy
1693 /// Optional pointer to an IOProxy to use (not supported by all
1694 /// formats, see `supports("ioproxy")`). The caller retains
1695 /// ownership of the proxy.
1696 ///
1697 /// @returns
1698 /// A `unique_ptr` that will close and free the ImageOutput when
1699 /// it exits scope or is reset. The pointer will be empty if the
1700 /// required writer was not able to be created.
1701 static unique_ptr create (string_view filename,
1702 Filesystem::IOProxy* ioproxy = nullptr,
1703 string_view plugin_searchpath = "");
1704
1705 // DEPRECATED(2.2)
1706 static unique_ptr create (const std::string &filename,
1707 const std::string &plugin_searchpath);
1708
1709 /// @}
1710
1711 // @deprecated
1712 static void destroy (ImageOutput *x);
1713
1714 protected:
1715 ImageOutput ();
1716 public:
1717 virtual ~ImageOutput ();
1718
1719 /// Return the name of the format implemented by this class.
1720 virtual const char *format_name (void) const = 0;
1721
1722 // Override these functions in your derived output class
1723 // to inform the client which formats are supported
1724
1725 /// @{
1726 /// @name Opening and closing files for output
1727
1728 /// Given the name of a "feature", return whether this ImageOutput
1729 /// supports output of images with the given properties. Most queries
1730 /// will simply return 0 for "doesn't support" and 1 for "supports it,"
1731 /// but it is acceptable to have queries return other nonzero integers
1732 /// to indicate varying degrees of support or limits (but should be
1733 /// clearly documented as such).
1734 ///
1735 /// Feature names that ImageOutput implementations are expected to
1736 /// recognize include:
1737 ///
1738 /// - `"tiles"` :
1739 /// Is this format writer able to write tiled images?
1740 ///
1741 /// - `"rectangles"` :
1742 /// Does this writer accept arbitrary rectangular pixel regions
1743 /// (via `write_rectangle()`)? Returning 0 indicates that
1744 /// pixels must be transmitted via `write_scanline()` (if
1745 /// scanline-oriented) or `write_tile()` (if tile-oriented, and
1746 /// only if `supports("tiles")` returns true).
1747 ///
1748 /// - `"random_access"` :
1749 /// May tiles or scanlines be written in any order (0 indicates
1750 /// that they *must* be in successive order)?
1751 ///
1752 /// - `"multiimage"` :
1753 /// Does this format support multiple subimages within a file?
1754 ///
1755 /// - `"appendsubimage"` :
1756 /// Does this format support multiple subimages that can be
1757 /// successively appended at will via
1758 /// `open(name,spec,AppendSubimage)`? A value of 0 means that
1759 /// the format requires pre-declaring the number and
1760 /// specifications of the subimages when the file is first
1761 /// opened, with `open(name,subimages,specs)`.
1762 ///
1763 /// - `"mipmap"` :
1764 /// Does this format support multiple resolutions for an
1765 /// image/subimage?
1766 ///
1767 /// - `"volumes"` :
1768 /// Does this format support "3D" pixel arrays (a.k.a. volume
1769 /// images)?
1770 ///
1771 /// - `"alpha"` :
1772 /// Can this format support an alpha channel?
1773 ///
1774 /// - `"nchannels"` :
1775 /// Can this format support arbitrary number of channels (beyond RGBA)?
1776 ///
1777 /// - `"rewrite"` :
1778 /// May the same scanline or tile be sent more than once?
1779 /// Generally, this is true for plugins that implement
1780 /// interactive display, rather than a saved image file.
1781 ///
1782 /// - `"empty"` :
1783 /// Does this plugin support passing a NULL data pointer to the
1784 /// various `write` routines to indicate that the entire data
1785 /// block is composed of pixels with value zero? Plugins that
1786 /// support this achieve a speedup when passing blank scanlines
1787 /// or tiles (since no actual data needs to be transmitted or
1788 /// converted).
1789 ///
1790 /// - `"channelformats"` :
1791 /// Does this format writer support per-channel data formats,
1792 /// respecting the ImageSpec's `channelformats` field? If not,
1793 /// it only accepts a single data format for all channels and
1794 /// will ignore the `channelformats` field of the spec.
1795 ///
1796 /// - `"displaywindow"` :
1797 /// Does the format support display ("full") windows distinct
1798 /// from the pixel data window?
1799 ///
1800 /// - `"origin"` :
1801 /// Does the image format support specifying a pixel window
1802 /// origin (i.e., nonzero ImageSpec `x`, `y`, `z`)?
1803 ///
1804 /// - `"negativeorigin"` :
1805 /// Does the image format allow data and display window origins
1806 /// (i.e., ImageSpec `x`, `y`, `z`, `full_x`, `full_y`, `full_z`)
1807 /// to have negative values?
1808 ///
1809 /// - `"deepdata"` :
1810 /// Does the image format allow "deep" data consisting of
1811 /// multiple values per pixel (and potentially a differing number
1812 /// of values from pixel to pixel)?
1813 ///
1814 /// - `"arbitrary_metadata"` :
1815 /// Does the image file format allow metadata with arbitrary
1816 /// names (and either arbitrary, or a reasonable set of, data
1817 /// types)? (Versus the file format supporting only a fixed list
1818 /// of specific metadata names/values.)
1819 ///
1820 /// - `"exif"`
1821 /// Does the image file format support Exif camera data (either
1822 /// specifically, or via arbitrary named metadata)?
1823 ///
1824 /// - `"iptc"`
1825 /// Does the image file format support IPTC data (either
1826 /// specifically, or via arbitrary named metadata)?
1827 ///
1828 /// - `"ioproxy"`
1829 /// Does the image file format support writing to an `IOProxy`?
1830 ///
1831 /// - `"procedural"` :
1832 /// Is this a purely procedural output that doesn't write an
1833 /// actual file?
1834 ///
1835 /// This list of queries may be extended in future releases. Since this
1836 /// can be done simply by recognizing new query strings, and does not
1837 /// require any new API entry points, addition of support for new
1838 /// queries does not break ``link compatibility'' with
1839 /// previously-compiled plugins.
supports(string_view feature OIIO_MAYBE_UNUSED)1840 virtual int supports (string_view feature OIIO_MAYBE_UNUSED) const {
1841 return false;
1842 }
1843
1844 /// Modes passed to the `open()` call.
1845 enum OpenMode { Create, AppendSubimage, AppendMIPLevel };
1846
1847 /// Open the file with given name, with resolution and other format
1848 /// data as given in newspec. It is legal to call open multiple times
1849 /// on the same file without a call to `close()`, if it supports
1850 /// multiimage and mode is AppendSubimage, or if it supports
1851 /// MIP-maps and mode is AppendMIPLevel -- this is interpreted as
1852 /// appending a subimage, or a MIP level to the current subimage,
1853 /// respectively.
1854 ///
1855 /// @param name The name of the image file to open.
1856 /// @param newspec The ImageSpec describing the resolution, data
1857 /// types, etc.
1858 /// @param mode Specifies whether the purpose of the `open` is
1859 /// to create/truncate the file (default: `Create`),
1860 /// append another subimage (`AppendSubimage`), or
1861 /// append another MIP level (`AppendMIPLevel`).
1862 /// @returns `true` upon success, or `false` upon failure.
1863 virtual bool open (const std::string &name, const ImageSpec &newspec,
1864 OpenMode mode=Create) = 0;
1865
1866 /// Open a multi-subimage file with given name and specifications for
1867 /// each of the subimages. Upon success, the first subimage will be
1868 /// open and ready for transmission of pixels. Subsequent subimages
1869 /// will be denoted with the usual call of
1870 /// `open(name,spec,AppendSubimage)` (and MIP levels by
1871 /// `open(name,spec,AppendMIPLevel)`).
1872 ///
1873 /// The purpose of this call is to accommodate format-writing
1874 /// libraries that must know the number and specifications of the
1875 /// subimages upon first opening the file; such formats can be
1876 /// detected by::
1877 /// supports("multiimage") && !supports("appendsubimage")
1878 /// The individual specs passed to the appending open() calls for
1879 /// subsequent subimages *must* match the ones originally passed.
1880 ///
1881 /// @param name The name of the image file to open.
1882 /// @param subimages The number of subimages (and therefore the
1883 /// length of the `specs[]` array.
1884 /// @param specs[]
1885 /// Pointer to an array of `ImageSpec` objects
1886 /// describing each of the expected subimages.
1887 /// @returns `true` upon success, or `false` upon failure.
open(const std::string & name,int subimages OIIO_MAYBE_UNUSED,const ImageSpec * specs)1888 virtual bool open (const std::string &name,
1889 int subimages OIIO_MAYBE_UNUSED,
1890 const ImageSpec *specs) {
1891 // Default implementation: just a regular open, assume that
1892 // appending will work.
1893 return open (name, specs[0]);
1894 }
1895
1896 /// Return a reference to the image format specification of the current
1897 /// subimage. Note that the contents of the spec are invalid before
1898 /// `open()` or after `close()`.
spec(void)1899 const ImageSpec &spec (void) const { return m_spec; }
1900
1901 /// Closes the currently open file associated with this ImageOutput and
1902 /// frees any memory or resources associated with it.
1903 virtual bool close () = 0;
1904 /// @}
1905
1906 /// @{
1907 /// @name Writing pixels
1908 ///
1909 /// Common features of all the `write` methods:
1910 ///
1911 /// * The `format` parameter describes the data type of the `data[]`. The
1912 /// write methods automatically convert the data from the specified
1913 /// `format` to the actual output data type of the file (as was
1914 /// specified by the ImageSpec passed to `open()`). If `format` is
1915 /// `TypeUnknown`, then rather than converting from `format`, it will
1916 /// just copy pixels assumed to already be in the file's native data
1917 /// layout (including, possibly, per-channel data formats as specified
1918 /// by the ImageSpec's `channelfomats` field).
1919 ///
1920 /// * The `stride` values describe the layout of the `data` buffer:
1921 /// `xstride` is the distance in bytes between successive pixels
1922 /// within each scanline. `ystride` is the distance in bytes between
1923 /// successive scanlines. For volumetric images `zstride` is the
1924 /// distance in bytes between successive "volumetric planes". Strides
1925 /// set to the special value `AutoStride` imply contiguous data, i.e.,
1926 ///
1927 /// xstride = format.size() * nchannels
1928 /// ystride = xstride * width
1929 /// zstride = ystride * height
1930 ///
1931 /// * Any *range* parameters (such as `ybegin` and `yend`) describe a
1932 /// "half open interval", meaning that `begin` is the first item and
1933 /// `end` is *one past the last item*. That means that the number of
1934 /// items is `end - begin`.
1935 ///
1936 /// * For ordinary 2D (non-volumetric) images, any `z` or `zbegin`
1937 /// coordinates should be 0 and any `zend` should be 1, indicating
1938 /// that only a single image "plane" exists.
1939 ///
1940 /// * Scanlines or tiles must be written in successive increasing
1941 /// coordinate order, unless the particular output file driver allows
1942 /// random access (indicated by `supports("random_access")`).
1943 ///
1944 /// * All write functions return `true` for success, `false` for failure
1945 /// (after which a call to `geterror()` may retrieve a specific error
1946 /// message).
1947 ///
1948
1949 /// Write the full scanline that includes pixels (*,y,z). For 2D
1950 /// non-volume images, `z` should be 0. The `xstride` value gives the
1951 /// distance between successive pixels (in bytes). Strides set to
1952 /// `AutoStride` imply "contiguous" data.
1953 ///
1954 /// @param y/z The y & z coordinates of the scanline.
1955 /// @param format A TypeDesc describing the type of `data`.
1956 /// @param data Pointer to the pixel data.
1957 /// @param xstride The distance in bytes between successive
1958 /// pixels in `data` (or `AutoStride`).
1959 /// @returns `true` upon success, or `false` upon failure.
1960 virtual bool write_scanline (int y, int z, TypeDesc format,
1961 const void *data, stride_t xstride=AutoStride);
1962
1963 /// Write multiple scanlines that include pixels (*,y,z) for all ybegin
1964 /// <= y < yend, from data. This is analogous to
1965 /// `write_scanline(y,z,format,data,xstride)` repeatedly for each of the
1966 /// scanlines in turn (the advantage, though, is that some image file
1967 /// types may be able to write multiple scanlines more efficiently or
1968 /// in parallel, than it could with one scanline at a time).
1969 ///
1970 /// @param ybegin/yend The y range of the scanlines being passed.
1971 /// @param z The z coordinate of the scanline.
1972 /// @param format A TypeDesc describing the type of `data`.
1973 /// @param data Pointer to the pixel data.
1974 /// @param xstride/ystride
1975 /// The distance in bytes between successive pixels
1976 /// and scanlines (or `AutoStride`).
1977 /// @returns `true` upon success, or `false` upon failure.
1978 virtual bool write_scanlines (int ybegin, int yend, int z,
1979 TypeDesc format, const void *data,
1980 stride_t xstride=AutoStride,
1981 stride_t ystride=AutoStride);
1982
1983 /// Write the tile with (x,y,z) as the upper left corner. The three
1984 /// stride values give the distance (in bytes) between successive
1985 /// pixels, scanlines, and volumetric slices, respectively. Strides set
1986 /// to AutoStride imply 'contiguous' data in the shape of a full tile,
1987 /// i.e.,
1988 ///
1989 /// xstride = format.size() * spec.nchannels
1990 /// ystride = xstride * spec.tile_width
1991 /// zstride = ystride * spec.tile_height
1992 ///
1993 /// @param x/y/z The upper left coordinate of the tile being passed.
1994 /// @param format A TypeDesc describing the type of `data`.
1995 /// @param data Pointer to the pixel data.
1996 /// @param xstride/ystride/zstride
1997 /// The distance in bytes between successive pixels,
1998 /// scanlines, and image planes (or `AutoStride` to
1999 /// indicate a "contiguous" single tile).
2000 /// @returns `true` upon success, or `false` upon failure.
2001 ///
2002 /// @note This call will fail if the image is not tiled, or if (x,y,z)
2003 /// is not the upper left corner coordinates of a tile.
2004 virtual bool write_tile (int x, int y, int z, TypeDesc format,
2005 const void *data, stride_t xstride=AutoStride,
2006 stride_t ystride=AutoStride,
2007 stride_t zstride=AutoStride);
2008
2009 /// Write the block of multiple tiles that include all pixels in
2010 ///
2011 /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend)
2012 ///
2013 /// This is analogous to calling `write_tile(x,y,z,...)` for each tile
2014 /// in turn (but for some file formats, passing multiple tiles may allow
2015 /// it to write more efficiently or in parallel).
2016 ///
2017 /// The begin/end pairs must correctly delineate tile boundaries, with
2018 /// the exception that it may also be the end of the image data if the
2019 /// image resolution is not a whole multiple of the tile size. The
2020 /// stride values give the data spacing of adjacent pixels, scanlines,
2021 /// and volumetric slices (measured in bytes). Strides set to AutoStride
2022 /// imply contiguous data in the shape of the [begin,end) region, i.e.,
2023 ///
2024 /// xstride = format.size() * spec.nchannels
2025 /// ystride = xstride * (xend-xbegin)
2026 /// zstride = ystride * (yend-ybegin)
2027 ///
2028 /// @param xbegin/xend The x range of the pixels covered by the group
2029 /// of tiles passed.
2030 /// @param ybegin/yend The y range of the pixels covered by the tiles.
2031 /// @param zbegin/zend The z range of the pixels covered by the tiles
2032 /// (for a 2D image, zbegin=0 and zend=1).
2033 /// @param format A TypeDesc describing the type of `data`.
2034 /// @param data Pointer to the pixel data.
2035 /// @param xstride/ystride/zstride
2036 /// The distance in bytes between successive pixels,
2037 /// scanlines, and image planes (or `AutoStride`).
2038 /// @returns `true` upon success, or `false` upon failure.
2039 ///
2040 /// @note The call will fail if the image is not tiled, or if the pixel
2041 /// ranges do not fall along tile (or image) boundaries, or if it is not
2042 /// a valid tile range.
2043 virtual bool write_tiles (int xbegin, int xend, int ybegin, int yend,
2044 int zbegin, int zend, TypeDesc format,
2045 const void *data, stride_t xstride=AutoStride,
2046 stride_t ystride=AutoStride,
2047 stride_t zstride=AutoStride);
2048
2049 /// Write a rectangle of pixels given by the range
2050 ///
2051 /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend)
2052 ///
2053 /// The stride values give the data spacing of adjacent pixels,
2054 /// scanlines, and volumetric slices (measured in bytes). Strides set to
2055 /// AutoStride imply contiguous data in the shape of the [begin,end)
2056 /// region, i.e.,
2057 ///
2058 /// xstride = format.size() * spec.nchannels
2059 /// ystride = xstride * (xend-xbegin)
2060 /// zstride = ystride * (yend-ybegin)
2061 ///
2062 /// @param xbegin/xend The x range of the pixels being passed.
2063 /// @param ybegin/yend The y range of the pixels being passed.
2064 /// @param zbegin/zend The z range of the pixels being passed
2065 /// (for a 2D image, zbegin=0 and zend=1).
2066 /// @param format A TypeDesc describing the type of `data`.
2067 /// @param data Pointer to the pixel data.
2068 /// @param xstride/ystride/zstride
2069 /// The distance in bytes between successive pixels,
2070 /// scanlines, and image planes (or `AutoStride`).
2071 /// @returns `true` upon success, or `false` upon failure.
2072 ///
2073 /// @note The call will fail for a format plugin that does not return
2074 /// true for `supports("rectangles")`.
2075 virtual bool write_rectangle (int xbegin, int xend, int ybegin, int yend,
2076 int zbegin, int zend, TypeDesc format,
2077 const void *data, stride_t xstride=AutoStride,
2078 stride_t ystride=AutoStride,
2079 stride_t zstride=AutoStride);
2080
2081 /// Write the entire image of `spec.width x spec.height x spec.depth`
2082 /// pixels, from a buffer with the given strides and in the desired
2083 /// format.
2084 ///
2085 /// Depending on the spec, this will write either all tiles or all
2086 /// scanlines. Assume that data points to a layout in row-major order.
2087 ///
2088 /// Because this may be an expensive operation, a progress callback
2089 /// may be passed. Periodically, it will be called as follows:
2090 ///
2091 /// progress_callback (progress_callback_data, float done);
2092 ///
2093 /// where `done` gives the portion of the image (between 0.0 and 1.0)
2094 /// that has been written thus far.
2095 ///
2096 /// @param format A TypeDesc describing the type of `data`.
2097 /// @param data Pointer to the pixel data.
2098 /// @param xstride/ystride/zstride
2099 /// The distance in bytes between successive pixels,
2100 /// scanlines, and image planes (or `AutoStride`).
2101 /// @param progress_callback/progress_callback_data
2102 /// Optional progress callback.
2103 /// @returns `true` upon success, or `false` upon failure.
2104 virtual bool write_image (TypeDesc format, const void *data,
2105 stride_t xstride=AutoStride,
2106 stride_t ystride=AutoStride,
2107 stride_t zstride=AutoStride,
2108 ProgressCallback progress_callback=nullptr,
2109 void *progress_callback_data=nullptr);
2110
2111 /// Write deep scanlines containing pixels (*,y,z), for all y in the
2112 /// range [ybegin,yend), to a deep file. This will fail if it is not a
2113 /// deep file.
2114 ///
2115 /// @param ybegin/yend The y range of the scanlines being passed.
2116 /// @param z The z coordinate of the scanline.
2117 /// @param deepdata A `DeepData` object with the data for these
2118 /// scanlines.
2119 /// @returns `true` upon success, or `false` upon failure.
2120 virtual bool write_deep_scanlines (int ybegin, int yend, int z,
2121 const DeepData &deepdata);
2122
2123 /// Write the block of deep tiles that include all pixels in
2124 /// the range
2125 ///
2126 /// [xbegin,xend) X [ybegin,yend) X [zbegin,zend)
2127 ///
2128 /// The begin/end pairs must correctly delineate tile boundaries, with
2129 /// the exception that it may also be the end of the image data if the
2130 /// image resolution is not a whole multiple of the tile size.
2131 ///
2132 /// @param xbegin/xend The x range of the pixels covered by the group
2133 /// of tiles passed.
2134 /// @param ybegin/yend The y range of the pixels covered by the tiles.
2135 /// @param zbegin/zend The z range of the pixels covered by the tiles
2136 /// (for a 2D image, zbegin=0 and zend=1).
2137 /// @param deepdata A `DeepData` object with the data for the tiles.
2138 /// @returns `true` upon success, or `false` upon failure.
2139 ///
2140 /// @note The call will fail if the image is not tiled, or if the pixel
2141 /// ranges do not fall along tile (or image) boundaries, or if it is not
2142 /// a valid tile range.
2143 virtual bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend,
2144 int zbegin, int zend,
2145 const DeepData &deepdata);
2146
2147 /// Write the entire deep image described by `deepdata`. Depending on
2148 /// the spec, this will write either all tiles or all scanlines.
2149 ///
2150 /// @param deepdata A `DeepData` object with the data for the image.
2151 /// @returns `true` upon success, or `false` upon failure.
2152 virtual bool write_deep_image (const DeepData &deepdata);
2153
2154 /// @}
2155
2156 /// Read the current subimage of `in`, and write it as the next
2157 /// subimage of `*this`, in a way that is efficient and does not alter
2158 /// pixel values, if at all possible. Both `in` and `this` must be a
2159 /// properly-opened `ImageInput` and `ImageOutput`, respectively, and
2160 /// their current images must match in size and number of channels.
2161 ///
2162 /// If a particular ImageOutput implementation does not supply a
2163 /// `copy_image` method, it will inherit the default implementation,
2164 /// which is to simply read scanlines or tiles from `in` and write them
2165 /// to `*this`. However, some file format implementations may have a
2166 /// special technique for directly copying raw pixel data from the input
2167 /// to the output, when both are the same file type and the same pixel
2168 /// data type. This can be more efficient than `in->read_image()`
2169 /// followed by `out->write_image()`, and avoids any unintended pixel
2170 /// alterations, especially for formats that use lossy compression.
2171 ///
2172 /// @param in A pointer to the open `ImageInput` to read from.
2173 /// @returns `true` upon success, or `false` upon failure.
2174 virtual bool copy_image (ImageInput *in);
2175
2176 // General message passing between client and image output server. This
2177 // is currently undefined and is reserved for future use.
2178 virtual int send_to_output (const char *format, ...);
2179 int send_to_client (const char *format, ...);
2180
2181 /// Set an IOProxy for this writer. This must be called prior to
2182 /// `open()`, and only for writers that support them
2183 /// (`supports("ioproxy")`). The caller retains ownership of the proxy.
2184 ///
2185 /// @returns `true` for success, `false` for failure.
set_ioproxy(Filesystem::IOProxy * ioproxy)2186 virtual bool set_ioproxy (Filesystem::IOProxy* ioproxy) {
2187 return (ioproxy == nullptr);
2188 }
2189
2190 /// If any of the API routines returned false indicating an error, this
2191 /// method will return the error string (and clear any error flags). If
2192 /// no error has occurred since the last time `geterror()` was called,
2193 /// it will return an empty string.
geterror()2194 std::string geterror () const {
2195 std::string e = m_errmessage;
2196 m_errmessage.clear ();
2197 return e;
2198 }
2199
2200 /// Error reporting for the plugin implementation: call this with
2201 /// `Strutil::format`-like arguments.
2202 /// Use with caution! Some day this will change to be fmt-like rather
2203 /// than printf-like.
2204 template<typename... Args>
error(const char * fmt,const Args &...args)2205 void error(const char* fmt, const Args&... args) const {
2206 append_error(Strutil::format (fmt, args...));
2207 }
2208
2209 /// Error reporting for the plugin implementation: call this with
2210 /// printf-like arguments.
2211 template<typename... Args>
errorf(const char * fmt,const Args &...args)2212 void errorf(const char* fmt, const Args&... args) const {
2213 append_error(Strutil::sprintf (fmt, args...));
2214 }
2215
2216 /// Error reporting for the plugin implementation: call this with
2217 /// fmt::format-like arguments.
2218 template<typename... Args>
errorfmt(const char * fmt,const Args &...args)2219 void errorfmt(const char* fmt, const Args&... args) const {
2220 append_error(Strutil::fmt::format (fmt, args...));
2221 }
2222
2223 // Error reporting for the plugin implementation: call this with
2224 // fmt::format-like arguments.
2225 template<typename... Args>
2226 OIIO_DEPRECATED("use `errorfmt` instead")
fmterror(const char * fmt,const Args &...args)2227 void fmterror(const char* fmt, const Args&... args) const {
2228 append_error(Strutil::fmt::format (fmt, args...));
2229 }
2230
2231 /// Set the threading policy for this ImageOutput, controlling the
2232 /// maximum amount of parallelizing thread "fan-out" that might occur
2233 /// during large write operations. The default of 0 means that the
2234 /// global `attribute("threads")` value should be used (which itself
2235 /// defaults to using as many threads as cores; see Section
2236 /// `Global Attributes`_).
2237 ///
2238 /// The main reason to change this value is to set it to 1 to indicate
2239 /// that the calling thread should do all the work rather than spawning
2240 /// new threads. That is probably the desired behavior in situations
2241 /// where the calling application has already spawned multiple worker
2242 /// threads.
threads(int n)2243 void threads (int n) { m_threads = n; }
2244
2245 /// Retrieve the current thread-spawning policy.
2246 /// @see `threads(int)`
threads()2247 int threads () const { return m_threads; }
2248
2249 // Custom new and delete to ensure that allocations & frees happen in
2250 // the OpenImageIO library, not in the app or plugins (because Windows).
2251 void* operator new (size_t size);
2252 void operator delete (void *ptr);
2253
2254 /// Call signature of a function that creates and returns an
2255 /// `ImageOutput*`.
2256 typedef ImageOutput* (*Creator)();
2257
2258 protected:
2259 /// Helper routines used by write_* implementations: convert data (in
2260 /// the given format and stride) to the "native" format of the file
2261 /// (described by the 'spec' member variable), in contiguous order. This
2262 /// requires a scratch space to be passed in so that there are no memory
2263 /// leaks. Returns a pointer to the native data, which may be the
2264 /// original data if it was already in native format and contiguous, or
2265 /// it may point to the scratch space if it needed to make a copy or do
2266 /// conversions. For float->uint8 conversions only, if dither is
2267 /// nonzero, random dither will be added to reduce quantization banding
2268 /// artifacts; in this case, the specific nonzero dither value is used
2269 /// as a seed for the hash function that produces the per-pixel dither
2270 /// amounts, and the optional [xyz]origin parameters help it to align
2271 /// the pixels to the right position in the dither pattern.
2272 const void *to_native_scanline (TypeDesc format,
2273 const void *data, stride_t xstride,
2274 std::vector<unsigned char> &scratch,
2275 unsigned int dither=0,
2276 int yorigin=0, int zorigin=0);
2277 const void *to_native_tile (TypeDesc format, const void *data,
2278 stride_t xstride, stride_t ystride,
2279 stride_t zstride,
2280 std::vector<unsigned char> &scratch,
2281 unsigned int dither=0,
2282 int xorigin=0, int yorigin=0, int zorigin=0);
2283 const void *to_native_rectangle (int xbegin, int xend, int ybegin, int yend,
2284 int zbegin, int zend,
2285 TypeDesc format, const void *data,
2286 stride_t xstride, stride_t ystride,
2287 stride_t zstride,
2288 std::vector<unsigned char> &scratch,
2289 unsigned int dither=0,
2290 int xorigin=0, int yorigin=0, int zorigin=0);
2291
2292 /// Helper function to copy a rectangle of data into the right spot in
2293 /// an image-sized buffer. In addition to copying to the right place,
2294 /// this handles data format conversion and dither (if the spec's
2295 /// "oiio:dither" is nonzero, and if it's converting from a float-like
2296 /// type to UINT8). The buf_format describes the type of image_buffer,
2297 /// if it's TypeDesc::UNKNOWN it will be assumed to be spec.format.
2298 bool copy_to_image_buffer (int xbegin, int xend, int ybegin, int yend,
2299 int zbegin, int zend, TypeDesc format,
2300 const void *data, stride_t xstride,
2301 stride_t ystride, stride_t zstride,
2302 void *image_buffer,
2303 TypeDesc buf_format = TypeDesc::UNKNOWN);
2304 /// Helper function to copy a tile of data into the right spot in an
2305 /// image-sized buffer. This is really just a wrapper for
2306 /// copy_to_image_buffer, passing all the right parameters to copy
2307 /// exactly one tile.
2308 bool copy_tile_to_image_buffer (int x, int y, int z, TypeDesc format,
2309 const void *data, stride_t xstride,
2310 stride_t ystride, stride_t zstride,
2311 void *image_buffer,
2312 TypeDesc buf_format = TypeDesc::UNKNOWN);
2313
2314 protected:
2315 ImageSpec m_spec; ///< format spec of the currently open image
2316
2317 private:
2318 void append_error (const std::string& message) const; // add to m_errmessage
2319 mutable std::string m_errmessage; ///< private storage of error message
2320 int m_threads; // Thread policy
2321 };
2322
2323
2324
2325 // Utility functions
2326
2327 /// Returns a numeric value for the version of OpenImageIO, 10000 for each
2328 /// major version, 100 for each minor version, 1 for each patch. For
2329 /// example, OpenImageIO 1.2.3 would return a value of 10203. One example of
2330 /// how this is useful is for plugins to query the version to be sure they
2331 /// are linked against an adequate version of the library.
2332 OIIO_API int openimageio_version ();
2333
2334 /// Returns any error string describing what went wrong if
2335 /// `ImageInput::create()` or `ImageOutput::create()` failed (since in such
2336 /// cases, the ImageInput or ImageOutput itself does not exist to have its
2337 /// own `geterror()` function called). This function returns the last error
2338 /// for this particular thread; separate threads will not clobber each
2339 /// other's global error messages.
2340 OIIO_API std::string geterror ();
2341
2342 /// `OIIO::attribute()` sets an global attribute (i.e., a property or
2343 /// option) of OpenImageIO. The `name` designates the name of the attribute,
2344 /// `type` describes the type of data, and `val` is a pointer to memory
2345 /// containing the new value for the attribute.
2346 ///
2347 /// If the name is known, valid attribute that matches the type specified,
2348 /// the attribute will be set to the new value and `attribute()` will return
2349 /// `true`. If `name` is not recognized, or if the types do not match
2350 /// (e.g., `type` is `TypeFloat` but the named attribute is a string), the
2351 /// attribute will not be modified, and `attribute()` will return `false`.
2352 ///
2353 /// The following are the recognized attributes:
2354 ///
2355 /// - `string options`
2356 ///
2357 /// This catch-all is simply a comma-separated list of `name=value`
2358 /// settings of named options, which will be parsed and individually set.
2359 /// For example,
2360 ///
2361 /// OIIO::attribute ("options", "threads=4,log_times=1");
2362 ///
2363 /// Note that if an option takes a string value that must itself contain
2364 /// a comma, it is permissible to enclose the value in either 'single'
2365 /// or "double" quotes.
2366 ///
2367 /// - `int threads`
2368 ///
2369 /// How many threads to use for operations that can be sped up by being
2370 /// multithreaded. (Examples: simultaneous format conversions of multiple
2371 /// scanlines read together, or many ImageBufAlgo operations.) The
2372 /// default is 0, meaning to use the full available hardware concurrency
2373 /// detected.
2374 ///
2375 /// Situations where the main application logic is essentially single
2376 /// threaded (i.e., one top-level call into OIIO at a time) should leave
2377 /// this at the default value, or some reasonable number of cores, thus
2378 /// allowing lots of threads to fill the cores when OIIO has big tasks to
2379 /// complete. But situations where you have many threads at the
2380 /// application level, each of which is expected to be making separate
2381 /// OIIO calls simultaneously, should set this to 1, thus having each
2382 /// calling thread do its own work inside of OIIO rather than spawning
2383 /// new threads with a high overall "fan out.""
2384 ///
2385 /// - `int exr_threads`
2386 ///
2387 /// Sets the internal OpenEXR thread pool size. The default is to use as
2388 /// many threads as the amount of hardware concurrency detected. Note
2389 /// that this is separate from the OIIO `"threads"` attribute.
2390 ///
2391 /// - `string plugin_searchpath`
2392 ///
2393 /// Colon-separated list of directories to search for dynamically-loaded
2394 /// format plugins.
2395 ///
2396 /// - `int read_chunk`
2397 ///
2398 /// When performing a `read_image()`, this is the number of scanlines it
2399 /// will attempt to read at a time (some formats are more efficient when
2400 /// reading and decoding multiple scanlines). The default is 256. The
2401 /// special value of 0 indicates that it should try to read the whole
2402 /// image if possible.
2403 ///
2404 /// - `float[] missingcolor`, `string missingcolor`
2405 ///
2406 /// This attribute may either be an array of float values, or a string
2407 /// containing a comma-separated list of the values. Setting this option
2408 /// globally is equivalent to always passing an `ImageInput`
2409 /// open-with-configuration hint `"oiio:missingcolor"` with the value.
2410 ///
2411 /// When set, it gives some `ImageInput` readers the option of ignoring
2412 /// any *missing* tiles or scanlines in the file, and instead of treating
2413 /// the read failure of an individual tile as a full error, will
2414 /// interpret is as an intentionally missing tile and proceed by simply
2415 /// filling in the missing pixels with the color specified. If the first
2416 /// element is negative, it will use the absolute value, but draw
2417 /// alternating diagonal stripes of the color. For example,
2418 ///
2419 /// float missing[4] = { -1.0, 0.0, 0.0, 0.0 }; // striped red
2420 /// OIIO::attribute ("missingcolor", TypeDesc("float[4]"), &missing);
2421 ///
2422 /// Note that only some file formats support files with missing tiles or
2423 /// scanlines, and this is only taken as a hint. Please see
2424 /// chap-bundledplugins_ for details on which formats accept a
2425 /// `"missingcolor"` configuration hint.
2426 ///
2427 /// - `int debug`
2428 ///
2429 /// When nonzero, various debug messages may be printed. The default is 0
2430 /// for release builds, 1 for DEBUG builds (values > 1 are for OIIO
2431 /// developers to print even more debugging information), This attribute
2432 /// but also may be overridden by the OPENIMAGEIO_DEBUG environment
2433 /// variable.
2434 ///
2435 /// - `int tiff:half`
2436 ///
2437 /// When nonzero, allows TIFF to write `half` pixel data. N.B. Most apps
2438 /// may not read these correctly, but OIIO will. That's why the default
2439 /// is not to support it.
2440 ///
2441 /// - `int log_times`
2442 ///
2443 /// When the `"log_times"` attribute is nonzero, `ImageBufAlgo` functions
2444 /// are instrumented to record the number of times they were called and
2445 /// the total amount of time spent executing them. It can be overridden
2446 /// by environment variable `OPENIMAGEIO_LOG_TIMES`. If the value of
2447 /// `log_times` is 2 or more when the application terminates, the timing
2448 /// report will be printed to `stdout` upon exit.
2449 ///
2450 /// When enabled, there is a slight runtime performance cost due to
2451 /// checking the time at the start and end of each of those function
2452 /// calls, and the locking and recording of the data structure that holds
2453 /// the log information. When the `log_times` attribute is disabled,
2454 /// there is no additional performance cost.
2455 ///
2456 /// The report of totals can be retrieved as the value of the
2457 /// `"timing_report"` attribute, using `OIIO:get_attribute()` call.
2458 ///
2459 ///
2460 ///
2461 OIIO_API bool attribute(string_view name, TypeDesc type, const void* val);
2462
2463 /// Shortcut attribute() for setting a single integer.
attribute(string_view name,int val)2464 inline bool attribute (string_view name, int val) {
2465 return attribute (name, TypeInt, &val);
2466 }
2467 /// Shortcut attribute() for setting a single float.
attribute(string_view name,float val)2468 inline bool attribute (string_view name, float val) {
2469 return attribute (name, TypeFloat, &val);
2470 }
2471 /// Shortcut attribute() for setting a single string.
attribute(string_view name,string_view val)2472 inline bool attribute (string_view name, string_view val) {
2473 const char *s = val.c_str();
2474 return attribute (name, TypeString, &s);
2475 }
2476
2477 /// Get the named global attribute of OpenImageIO, store it in `*val`.
2478 /// Return `true` if found and it was compatible with the type specified,
2479 /// otherwise return `false` and do not modify the contents of `*val`. It
2480 /// is up to the caller to ensure that `val` points to the right kind and
2481 /// size of storage for the given type.
2482 ///
2483 /// In addition to being able to retrieve all the attributes that are
2484 /// documented as settable by the `OIIO::attribute()` call, `getattribute()`
2485 /// can also retrieve the following read-only attributes:
2486 ///
2487 /// - `string format_list`
2488 /// - `string input_format_list`
2489 /// - `string output_format_list`
2490 ///
2491 /// A comma-separated list of all the names of, respectively, all
2492 /// supported image formats, all formats accepted as inputs, and all
2493 /// formats accepted as outputs.
2494 ///
2495 /// - `string extension_list`
2496 ///
2497 /// For each format, the format name, followed by a colon, followed by a
2498 /// comma-separated list of all extensions that are presumed to be used
2499 /// for that format. Semicolons separate the lists for formats. For
2500 /// example,
2501 ///
2502 /// "tiff:tif;jpeg:jpg,jpeg;openexr:exr"
2503 ///
2504 /// - `string library_list`
2505 ///
2506 /// For each format that uses a dependent library, the format name,
2507 /// followed by a colon, followed by the name and version of the
2508 /// dependency. Semicolons separate the lists for formats. For example,
2509 ///
2510 /// "tiff:LIBTIFF 4.0.4;gif:gif_lib 4.2.3;openexr:OpenEXR 2.2.0"
2511 ///
2512 /// - string "timing_report"
2513 /// A string containing the report of all the log_times.
2514 ///
2515 /// - `string hw:simd`
2516 /// - `string oiio:simd` (read-only)
2517 ///
2518 /// A comma-separated list of hardware CPU features for SIMD (and some
2519 /// other things). The `"oiio:simd"` attribute is similarly a list of
2520 /// which features this build of OIIO was compiled to support.
2521 ///
2522 /// This was added in OpenImageIO 1.8.
2523 ///
2524 /// - `float resident_memory_used_MB`
2525 ///
2526 /// This read-only attribute can be used for debugging purposes to report
2527 /// the approximate process memory used (resident) by the application, in
2528 /// MB.
2529 ///
2530 /// - `string timing_report`
2531 ///
2532 /// Retrieving this attribute returns the timing report generated by the
2533 /// `log_timing` attribute (if it was enabled). The report is sorted
2534 /// alphabetically and for each named instrumentation region, prints the
2535 /// number of times it executed, the total runtime, and the average per
2536 /// call, like this:
2537 ///
2538 /// IBA::computePixelStats 2 2.69ms (avg 1.34ms)
2539 /// IBA::make_texture 1 74.05ms (avg 74.05ms)
2540 /// IBA::mul 8 2.42ms (avg 0.30ms)
2541 /// IBA::over 10 23.82ms (avg 2.38ms)
2542 /// IBA::resize 20 0.24s (avg 12.18ms)
2543 /// IBA::zero 8 0.66ms (avg 0.08ms)
2544 ///
2545 OIIO_API bool getattribute(string_view name, TypeDesc type, void* val);
2546
2547 /// Shortcut getattribute() for retrieving a single integer.
2548 /// The value is placed in `val`, and the function returns `true` if the
2549 /// attribute was found and was legally convertible to an int.
getattribute(string_view name,int & val)2550 inline bool getattribute (string_view name, int &val) {
2551 return getattribute (name, TypeInt, &val);
2552 }
2553 /// Shortcut getattribute() for retrieving a single float.
2554 /// The value is placed in `val`, and the function returns `true` if the
2555 /// attribute was found and was legally convertible to a float.
getattribute(string_view name,float & val)2556 inline bool getattribute (string_view name, float &val) {
2557 return getattribute (name, TypeFloat, &val);
2558 }
2559 /// Shortcut getattribute() for retrieving a single string as a
2560 /// `std::string`. The value is placed in `val`, and the function returns
2561 /// `true` if the attribute was found.
getattribute(string_view name,std::string & val)2562 inline bool getattribute (string_view name, std::string &val) {
2563 ustring s;
2564 bool ok = getattribute (name, TypeString, &s);
2565 if (ok)
2566 val = s.string();
2567 return ok;
2568 }
2569 /// Shortcut getattribute() for retrieving a single string as a `char*`.
getattribute(string_view name,char ** val)2570 inline bool getattribute (string_view name, char **val) {
2571 return getattribute (name, TypeString, val);
2572 }
2573 /// Shortcut getattribute() for retrieving a single integer, with a supplied
2574 /// default value that will be returned if the attribute is not found or
2575 /// could not legally be converted to an int.
2576 inline int get_int_attribute (string_view name, int defaultval=0) {
2577 int val;
2578 return getattribute (name, TypeInt, &val) ? val : defaultval;
2579 }
2580 /// Shortcut getattribute() for retrieving a single float, with a supplied
2581 /// default value that will be returned if the attribute is not found or
2582 /// could not legally be converted to a float.
2583 inline float get_float_attribute (string_view name, float defaultval=0) {
2584 float val;
2585 return getattribute (name, TypeFloat, &val) ? val : defaultval;
2586 }
2587 /// Shortcut getattribute() for retrieving a single string, with a supplied
2588 /// default value that will be returned if the attribute is not found.
2589 inline string_view get_string_attribute (string_view name,
2590 string_view defaultval = string_view()) {
2591 ustring val;
2592 return getattribute (name, TypeString, &val) ? string_view(val) : defaultval;
2593 }
2594
2595
2596 /// Register the input and output 'create' routines and list of file
2597 /// extensions for a particular format.
2598 OIIO_API void declare_imageio_format (const std::string &format_name,
2599 ImageInput::Creator input_creator,
2600 const char **input_extensions,
2601 ImageOutput::Creator output_creator,
2602 const char **output_extensions,
2603 const char *lib_version);
2604
2605 /// Is `name` one of the known format names?
2606 OIIO_API bool is_imageio_format_name(string_view name);
2607
2608 /// Helper function: convert contiguous data between two arbitrary pixel
2609 /// data types (specified by TypeDesc's). Return true if ok, false if it
2610 /// didn't know how to do the conversion. If dst_type is UNKNOWN, it will
2611 /// be assumed to be the same as src_type.
2612 ///
2613 /// The conversion is of normalized (pixel-like) values -- for example
2614 /// 'UINT8' 255 will convert to float 1.0 and vice versa, not float 255.0.
2615 /// If you want a straight C-like data cast convertion (e.g., uint8 255 ->
2616 /// float 255.0), then you should prefer the un-normalized convert_type()
2617 /// utility function found in typedesc.h.
2618 OIIO_API bool convert_pixel_values (TypeDesc src_type, const void *src,
2619 TypeDesc dst_type, void *dst, int n = 1);
2620
2621 /// DEPRECATED(2.1): old name
2622 inline bool convert_types (TypeDesc src_type, const void *src,
2623 TypeDesc dst_type, void *dst, int n = 1) {
2624 return convert_pixel_values (src_type, src, dst_type, dst, n);
2625 }
2626
2627
2628 /// Helper routine for data conversion: Convert an image of nchannels x
2629 /// width x height x depth from src to dst. The src and dst may have
2630 /// different data formats and layouts. Clever use of this function can
2631 /// not only exchange data among different formats (e.g., half to 8-bit
2632 /// unsigned), but also can copy selective channels, copy subimages,
2633 /// etc. If you're lazy, it's ok to pass AutoStride for any of the
2634 /// stride values, and they will be auto-computed assuming contiguous
2635 /// data. Return true if ok, false if it didn't know how to do the
2636 /// conversion.
2637 OIIO_API bool convert_image (int nchannels, int width, int height, int depth,
2638 const void *src, TypeDesc src_type,
2639 stride_t src_xstride, stride_t src_ystride,
2640 stride_t src_zstride,
2641 void *dst, TypeDesc dst_type,
2642 stride_t dst_xstride, stride_t dst_ystride,
2643 stride_t dst_zstride);
2644 /// DEPRECATED(2.0) -- the alpha_channel, z_channel were never used
2645 inline bool convert_image(int nchannels, int width, int height, int depth,
2646 const void *src, TypeDesc src_type,
2647 stride_t src_xstride, stride_t src_ystride, stride_t src_zstride,
2648 void *dst, TypeDesc dst_type,
2649 stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride,
2650 int /*alpha_channel*/, int /*z_channel*/ = -1)
2651 {
2652 return convert_image(nchannels, width, height, depth, src, src_type,
2653 src_xstride, src_ystride, src_zstride, dst, dst_type,
2654 dst_xstride, dst_ystride, dst_zstride);
2655 }
2656
2657
2658 /// A version of convert_image that will break up big jobs into multiple
2659 /// threads.
2660 OIIO_API bool parallel_convert_image (
2661 int nchannels, int width, int height, int depth,
2662 const void *src, TypeDesc src_type,
2663 stride_t src_xstride, stride_t src_ystride,
2664 stride_t src_zstride,
2665 void *dst, TypeDesc dst_type,
2666 stride_t dst_xstride, stride_t dst_ystride,
2667 stride_t dst_zstride, int nthreads=0);
2668 /// DEPRECATED(2.0) -- the alpha_channel, z_channel were never used
2669 inline bool parallel_convert_image(
2670 int nchannels, int width, int height, int depth,
2671 const void *src, TypeDesc src_type,
2672 stride_t src_xstride, stride_t src_ystride, stride_t src_zstride,
2673 void *dst, TypeDesc dst_type,
2674 stride_t dst_xstride, stride_t dst_ystride, stride_t dst_zstride,
2675 int /*alpha_channel*/, int /*z_channel*/, int nthreads=0)
2676 {
2677 return parallel_convert_image (nchannels, width, height, depth,
2678 src, src_type, src_xstride, src_ystride, src_zstride,
2679 dst, dst_type, dst_xstride, dst_ystride, dst_zstride, nthreads);
2680 }
2681
2682 /// Add random [-theramplitude,ditheramplitude] dither to the color channels
2683 /// of the image. Dither will not be added to the alpha or z channel. The
2684 /// image origin and dither seed values allow a reproducible (or variable)
2685 /// dither pattern. If the strides are set to AutoStride, they will be
2686 /// assumed to be contiguous floats in data of the given dimensions.
2687 OIIO_API void add_dither (int nchannels, int width, int height, int depth,
2688 float *data,
2689 stride_t xstride, stride_t ystride, stride_t zstride,
2690 float ditheramplitude,
2691 int alpha_channel = -1, int z_channel = -1,
2692 unsigned int ditherseed = 1,
2693 int chorigin=0, int xorigin=0,
2694 int yorigin=0, int zorigin=0);
2695
2696 /// Convert unassociated to associated alpha by premultiplying all color
2697 /// (non-alpha, non-z) channels by alpha. The nchannels, width, height, and
2698 /// depth parameters describe the "shape" of the image data (along with
2699 /// optional stride overrides). The chbegin/chend describe which range of
2700 /// channels to actually premultiply.
2701 OIIO_API void premult (int nchannels, int width, int height, int depth,
2702 int chbegin, int chend,
2703 TypeDesc datatype, void *data, stride_t xstride,
2704 stride_t ystride, stride_t zstride,
2705 int alpha_channel = -1, int z_channel = -1);
2706
2707 /// Helper routine for data conversion: Copy an image of nchannels x
2708 /// width x height x depth from src to dst. The src and dst may have
2709 /// different data layouts, but must have the same data type. Clever
2710 /// use of this function can change layouts or strides, copy selective
2711 /// channels, copy subimages, etc. If you're lazy, it's ok to pass
2712 /// AutoStride for any of the stride values, and they will be
2713 /// auto-computed assuming contiguous data. Return true if ok, false if
2714 /// it didn't know how to do the conversion.
2715 OIIO_API bool copy_image (int nchannels, int width, int height, int depth,
2716 const void *src, stride_t pixelsize,
2717 stride_t src_xstride, stride_t src_ystride,
2718 stride_t src_zstride,
2719 void *dst, stride_t dst_xstride,
2720 stride_t dst_ystride, stride_t dst_zstride);
2721
2722
2723 // All the wrap_foo functions implement a wrap mode, wherein coord is
2724 // altered to be origin <= coord < origin+width. The return value
2725 // indicates if the resulting wrapped value is valid (example, for
2726 // wrap_black, values outside the region are invalid and do not modify
2727 // the coord parameter).
2728 OIIO_API bool wrap_black (int &coord, int origin, int width);
2729 OIIO_API bool wrap_clamp (int &coord, int origin, int width);
2730 OIIO_API bool wrap_periodic (int &coord, int origin, int width);
2731 OIIO_API bool wrap_periodic_pow2 (int &coord, int origin, int width);
2732 OIIO_API bool wrap_mirror (int &coord, int origin, int width);
2733
2734 // Typedef for the function signature of a wrap implementation.
2735 typedef bool (*wrap_impl) (int &coord, int origin, int width);
2736
2737
2738 /// `debug(format, ...)` prints debugging message when attribute "debug" is
2739 /// nonzero, which it is by default for DEBUG compiles or when the
2740 /// environment variable OPENIMAGEIO_DEBUG is set. This is preferred to raw
2741 /// output to stderr for debugging statements.
2742 OIIO_API void debug (string_view str);
2743
2744 /// debug output with `std::format` conventions.
2745 template<typename T1, typename... Args>
debugfmt(const char * fmt,const T1 & v1,const Args &...args)2746 void debugfmt (const char* fmt, const T1& v1, const Args&... args)
2747 {
2748 debug (Strutil::fmt::format(fmt, v1, args...));
2749 }
2750
2751 // (Unfortunate old synonym)
2752 template<typename T1, typename... Args>
2753 OIIO_DEPRECATED("use `debugfmt` instead")
fmtdebug(const char * fmt,const T1 & v1,const Args &...args)2754 void fmtdebug (const char* fmt, const T1& v1, const Args&... args)
2755 {
2756 debug (Strutil::fmt::format(fmt, v1, args...));
2757 }
2758
2759 /// debug output with printf conventions.
2760 template<typename T1, typename... Args>
debugf(const char * fmt,const T1 & v1,const Args &...args)2761 void debugf (const char* fmt, const T1& v1, const Args&... args)
2762 {
2763 debug (Strutil::sprintf(fmt, v1, args...));
2764 }
2765
2766 /// debug output with the same conventions as Strutil::format. Beware, this
2767 /// will change one day!
2768 template<typename T1, typename... Args>
debug(const char * fmt,const T1 & v1,const Args &...args)2769 void debug (const char* fmt, const T1& v1, const Args&... args)
2770 {
2771 debug (Strutil::format(fmt, v1, args...));
2772 }
2773
2774
2775 // to force correct linkage on some systems
2776 OIIO_API void _ImageIO_force_link ();
2777
2778 OIIO_NAMESPACE_END
2779