HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
imagebuf.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause and Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 
6 #pragma once
7 #define OPENIMAGEIO_IMAGEBUF_H
8 
9 #if defined(_MSC_VER)
10 // Ignore warnings about DLL exported classes with member variables that are template classes.
11 // This happens with the std::vector and std::string protected members of ImageBuf below.
12 # pragma warning(disable : 4251)
13 #endif
14 
15 #include <OpenImageIO/dassert.h>
16 #include <OpenImageIO/fmath.h>
17 #include <OpenImageIO/imageio.h>
18 
19 #include <limits>
20 #include <memory>
21 
22 
24 
25 class ImageBuf;
26 class ImageBufImpl; // Opaque type for the unique_ptr.
27 class ImageCache;
28 
29 namespace pvt {
30 class ImageCacheTile;
31 }; // namespace pvt
32 
33 
34 
35 /// Return pixel data window for this ImageSpec as a ROI.
37 get_roi(const ImageSpec& spec);
38 
39 /// Return full/display window for this ImageSpec as a ROI.
41 get_roi_full(const ImageSpec& spec);
42 
43 /// Set pixel data window for this ImageSpec to a ROI.
44 /// Does NOT change the channels of the spec, regardless of newroi.
45 OIIO_API void
46 set_roi(ImageSpec& spec, const ROI& newroi);
47 
48 /// Set full/display window for this ImageSpec to a ROI.
49 /// Does NOT change the channels of the spec, regardless of newroi.
50 OIIO_API void
51 set_roi_full(ImageSpec& spec, const ROI& newroi);
52 
53 
54 enum class InitializePixels { No = 0, Yes = 1 };
55 
56 
57 
58 /// An ImageBuf is a simple in-memory representation of a 2D image. It uses
59 /// ImageInput and ImageOutput underneath for its file I/O, and has simple
60 /// routines for setting and getting individual pixels, that hides most of
61 /// the details of memory layout and data representation (translating
62 /// to/from float automatically).
63 ///
64 /// ImageBuf makes an important simplification: all channels are the same
65 /// data type. For example, if an image file on disk has a mix of `half` and
66 /// `float` channels, the in-memory ImageBuf representation will be entirely
67 /// `float` (for mixed data types, it will try to pick one that can best
68 /// represent all channels without a loss of precision or range). However,
69 /// by using the `set_write_format()` method, it is still possible to write
70 /// an ImageBuf to a file with mixed channel types.
71 ///
72 /// Most of the time, ImageBuf data is read lazily (I/O only happens when
73 /// you first call methods that actually need metadata or pixel data).
74 /// Explicit calls to `read()` are therefore optional and are only needed
75 /// if you want to specify non-default arguments (such as choosing something
76 /// other than the first subimage of the file, or forcing the read to
77 /// translate into a different data format than appears in the file).
78 ///
79 /// ImageBuf data coming from disk files may optionally be backed by
80 /// ImageCache, by explicitly passing an `ImageCache*` to the ImageBuf
81 /// constructor or `reset()` method (pass `ImageCache::create()` to get a
82 /// pointer to the default global ImageCache), or by having previously set the
83 /// global OIIO attribute `"imagebuf:use_imagecache"` to a nonzero value. When
84 /// an ImageBuf is backed by ImageCache in this way, specific regions of the
85 /// image will only be read if and when they are needed, and if there are many
86 /// large ImageBuf's, memory holding pixels not recently accessed will be
87 /// automatically freed if the cache size limit is reached.
88 ///
89 /// Writable ImageBufs are always stored entirely in memory, and do not use
90 /// the ImageCache or any other clever schemes to limit memory. If you have
91 /// enough simultaneous writeable large ImageBuf's, you can run out of RAM.
92 /// Note that if an ImageBuf starts as readable (backed by ImageCache), any
93 /// alterations to its pixels (for example, via `setpixel()` or traversing
94 /// it with a non-const `Iterator`) will cause it to be read entirely into
95 /// memory and remain in memory thereafter for the rest of the life of that
96 /// ImageBuf.
97 ///
98 /// Notes about ImageBuf thread safety:
99 ///
100 /// * The various read-only methods for accessing the spec or the pixels,
101 /// including `init_spec()`, `read()`, `spec()`, all the getpixel flavors
102 /// and `ConstIterator` over the pixels, and other informational methods
103 /// such as `roi()`, all are thread-safe and may be called concurrently
104 /// with any of the other thread-safe methods.
105 /// * Methods that alter pixel values, such as all the setpixel flavors,
106 /// and (non-const) `Iterator` over the pixels, and the `write()` method
107 /// are "thread safe" in the sense that you won't crash your app by doing
108 /// these concurrently with each other or with the reading functionality,
109 /// but on the other hand, if two threads are changing the same pixels
110 /// simultaneously or one is writing while others are reading, you may end
111 /// up with an inconsistent resulting image.
112 /// * Construction and destruction, `reset()`, and anything that alters
113 /// image metadata (such as writes through `specmod()`) are NOT THREAD
114 /// SAFE and you should ensure that you are not doing any of these calls
115 /// simultaneously with any other operations on the same ImageBuf.
116 ///
118 public:
119  /// An ImageBuf can store its pixels in one of several ways (each
120  /// identified by an `IBStorage` enumerated value):
121  enum IBStorage {
122  // clang-format off
123  UNINITIALIZED,
124  ///< An ImageBuf that doesn't represent any image at all
125  /// (either because it is newly constructed with the default
126  /// constructor, or had an error during construction).
127  LOCALBUFFER,
128  ///< "Local storage" is allocated to hold the image pixels
129  /// internal to the ImageBuf. This memory will be freed when
130  /// the ImageBuf is destroyed.
131  APPBUFFER,
132  ///< The ImageBuf "wraps" pixel memory already allocated and
133  /// owned by the calling application. The caller will continue
134  /// to own that memory and be responsible for freeing it after
135  /// the ImageBuf is destroyed.
136  IMAGECACHE
137  ///< The ImageBuf is "backed" by an ImageCache, which will
138  /// automatically be used to retrieve pixels when requested, but
139  /// the ImageBuf will not allocate separate storage for it.
140  /// This brings all the advantages of the ImageCache, but can
141  /// only be used for read-only ImageBuf's that reference a
142  /// stored image file.
143  // clang-format on
144  };
145 
146  /// @{
147  /// @name Constructing and destructing an ImageBuf.
148 
149  /// Default constructor makes an empty/uninitialized ImageBuf. There
150  /// isn't much you can do with an uninitialized buffer until you call
151  /// `reset()`. The storage type of a default-constructed ImageBuf is
152  /// `IBStorage::UNINITIALIZED`.
153  ImageBuf();
154 
155  /// Destructor for an ImageBuf.
156  ~ImageBuf();
157 
158  /// Construct a read-only ImageBuf that will be used to read the named
159  /// file (at the given subimage and MIP-level, defaulting to the first
160  /// in the file). But don't read it yet! The image will actually be
161  /// read lazily, only when other methods need to access the spec and/or
162  /// pixels, or when an explicit call to `init_spec()` or `read()` is
163  /// made, whichever comes first.
164  ///
165  /// The implementation may end up either reading the entire image
166  /// internally owned memory (if so, the storage will be `LOCALBUFFER`),
167  /// or it may rely on being backed by an ImageCache (in this case, the
168  /// storage will be `IMAGECACHE`) -- depending on the image size and
169  /// other factors.
170  ///
171  /// @param name
172  /// The image to read.
173  /// @param subimage/miplevel
174  /// The subimage and MIP level to read (defaults to the
175  /// first subimage of the file, highest-res MIP level).
176  /// @param imagecache
177  /// Optionally, an ImageCache to use, if possible, rather
178  /// than reading the entire image file into memory.
179  /// @param config
180  /// Optionally, a pointer to an ImageSpec whose metadata
181  /// contains configuration hints that set options related
182  /// to the opening and reading of the file.
183  /// @param ioproxy
184  /// Optional pointer to an IOProxy to use when reading from the
185  /// file. The caller retains ownership of the proxy, and must
186  /// ensure that it remains valid for the lifetime of the ImageBuf.
187  ///
188  explicit ImageBuf(string_view name, int subimage = 0, int miplevel = 0,
189  ImageCache* imagecache = nullptr,
190  const ImageSpec* config = nullptr,
191  Filesystem::IOProxy* ioproxy = nullptr);
192 
193  // Deprecated synonym for `ImageBuf(name, 0, 0, imagecache, nullptr)`.
194  ImageBuf(string_view name, ImageCache* imagecache);
195 
196  /// Construct a writable ImageBuf with the given specification
197  /// (including resolution, data type, metadata, etc.). The ImageBuf will
198  /// allocate and own its own pixel memory and will free that memory
199  /// automatically upon destruction, clear(), or reset(). Upon successful
200  /// initialization, the storage will be reported as `LOCALBUFFER`.
201  ///
202  /// @param spec
203  /// An ImageSpec describing the image and its metadata. If
204  /// not enough information is given to know how much memory
205  /// to allocate (width, height, depth, channels, and data
206  /// format), the ImageBuf will remain in an UNINITIALIZED
207  /// state and will have no local pixel storage.
208  /// @param zero
209  /// After a successful allocation of the local pixel
210  /// storage, this parameter controls whether the pixels
211  /// will be initialized to hold zero (black) values
212  /// (`InitializePixels::Yes`) or if the pixel memory will
213  /// remain uninitialized (`InitializePixels::No`) and thus
214  /// may hold nonsensical values. Choosing `No` may save the
215  /// time of writing to the pixel memory if you know for sure
216  /// that you are about to overwrite it completely before you
217  /// will need to read any pixel values.
218  ///
219  explicit ImageBuf(const ImageSpec& spec,
221 
222  // Deprecated/useless synonym for `ImageBuf(spec,zero)` but also gives
223  // it an internal name.
224  ImageBuf(string_view name, const ImageSpec& spec,
226 
227  /// Construct a writable ImageBuf that "wraps" existing pixel memory
228  /// owned by the calling application. The ImageBuf does not own the
229  /// pixel storage and will will not free/delete that memory, even when
230  /// the ImageBuf is destroyed. Upon successful initialization, the
231  /// storage will be reported as `APPBUFFER`.
232  ///
233  /// @param spec
234  /// An ImageSpec describing the image and its metadata. If
235  /// not enough information is given to know the "shape" of
236  /// the image (width, height, depth, channels, and data
237  /// format), the ImageBuf will remain in an UNINITIALIZED
238  /// state.
239  /// @param buffer
240  /// A pointer to the caller-owned memory containing the
241  /// storage for the pixels. It must be already allocated
242  /// with enough space to hold a full image as described by
243  /// `spec`.
244  /// @param xstride/ystride/zstride
245  /// The distance in bytes between successive pixels,
246  /// scanlines, and image planes in the buffer (or
247  /// `AutoStride` to indicate "contiguous" data in any of
248  /// those dimensions).
249  ///
250  ImageBuf(const ImageSpec& spec, void* buffer, stride_t xstride = AutoStride,
251  stride_t ystride = AutoStride, stride_t zstride = AutoStride);
252 
253  // Deprecated/useless synonym for `ImageBuf(spec,buffer)` but also gives
254  // it an internal name.
255  ImageBuf(string_view name, const ImageSpec& spec, void* buffer);
256 
257  /// Construct a copy of an ImageBuf.
258  ImageBuf(const ImageBuf& src);
259 
260  /// Move the contents of an ImageBuf to another ImageBuf.
261  ImageBuf(ImageBuf&& src);
262 
263  // Old name for reset().
264  void clear();
265 
266  /// Destroy any previous contents of the ImageBuf and re-initialize it
267  /// to resemble a freshly constructed ImageBuf using the default
268  /// constructor (holding no image, with storage
269  /// `IBStorage::UNINITIALIZED`).
270  void reset() { clear(); }
271 
272  // Deprecated/useless synonym for `reset(name, 0, 0, imagecache, nullptr)`
273  void reset(string_view name, ImageCache* imagecache);
274 
275  /// Destroy any previous contents of the ImageBuf and re-initialize it
276  /// as if newly constructed with the same arguments, as a read-only
277  /// representation of an existing image file.
278  void reset(string_view name, int subimage = 0, int miplevel = 0,
279  ImageCache* imagecache = nullptr,
280  const ImageSpec* config = nullptr,
281  Filesystem::IOProxy* ioproxy = nullptr);
282 
283  /// Destroy any previous contents of the ImageBuf and re-initialize it
284  /// as if newly constructed with the same arguments, as a read/write
285  /// image with locally allocated storage that can hold an image as
286  /// described by `spec`. The optional `zero` parameter controls whether
287  /// the pixel values are filled with black/empty, or are left
288  /// uninitialized after being allocated.
289  ///
290  /// Note that if the ImageSpec does not contain enough information to
291  /// specify how much memory to allocate (width, height, channels, and
292  /// data format), the ImageBuf will remain uninitialized (regardless of
293  /// how `zero` is set).
294  void reset(const ImageSpec& spec,
296 
297  // Deprecated/useless synonym for `reset(spec, zero)` and also give it an
298  // internal name.
299  void reset(string_view name, const ImageSpec& spec,
301 
302  /// Destroy any previous contents of the ImageBuf and re-initialize it
303  /// as if newly constructed with the same arguments, to "wrap" existing
304  /// pixel memory owned by the calling application.
305  void reset(const ImageSpec& spec, void* buffer,
306  stride_t xstride = AutoStride, stride_t ystride = AutoStride,
307  stride_t zstride = AutoStride);
308 
309  /// Make the ImageBuf be writable. That means that if it was previously
310  /// backed by an ImageCache (storage was `IMAGECACHE`), it will force a
311  /// full read so that the whole image is in local memory. This will
312  /// invalidate any current iterators on the image. It has no effect if
313  /// the image storage is not `IMAGECACHE`.
314  ///
315  /// @param keep_cache_type
316  /// If true, preserve any ImageCache-forced data types (you
317  /// might want to do this if it is critical that the
318  /// apparent data type doesn't change, for example if you
319  /// are calling `make_writable()` from within a
320  /// type-specialized function).
321  /// @returns
322  /// Return `true` if it works (including if no read was
323  /// necessary), `false` if something went horribly wrong.
324  bool make_writable(bool keep_cache_type = false);
325 
326  // DEPRECATED(2.2): This is an alternate, and less common, spelling.
327  // Let's standardize on "writable". We will eventually remove this.
328  bool make_writeable(bool keep_cache_type = false);
329 
330  /// @}
331 
332 
333  /// Wrap mode describes what happens when an iterator points to
334  /// a value outside the usual data range of an image.
335  enum WrapMode {
341  _WrapLast
342  };
343 
344 
345  /// @{
346  /// @name Reading and Writing disk images
347 
348  /// Read the particular subimage and MIP level of the image. Generally,
349  /// this will skip the expensive read if the file has already been read
350  /// into the ImageBuf (at the specified subimage and MIP level). It
351  /// will clear and re-allocate memory if the previously allocated space
352  /// was not appropriate for the size or data type of the image being
353  /// read.
354  ///
355  /// In general, `read()` will try not to do any I/O at the time of the
356  /// `read()` call, but rather to have the ImageBuf "backed" by an
357  /// ImageCache, which will do the file I/O on demand, as pixel values
358  /// are needed, and in that case the ImageBuf doesn't actually allocate
359  /// memory for the pixels (the data lives in the ImageCache). However,
360  /// there are several conditions for which the ImageCache will be
361  /// bypassed, the ImageBuf will allocate "local" memory, and the disk
362  /// file will be read directly into allocated buffer at the time of the
363  /// `read()` call: (a) if the `force` parameter is `true`; (b) if the
364  /// `convert` parameter requests a data format conversion to a type that
365  /// is not the native file type and also is not one of the internal
366  /// types supported by the ImageCache (specifically, `float` and
367  /// `UINT8`); (c) if the ImageBuf already has local pixel memory
368  /// allocated, or "wraps" an application buffer.
369  ///
370  /// Note that `read()` is not strictly necessary. If you are happy with
371  /// the filename, subimage and MIP level specified by the ImageBuf
372  /// constructor (or the last call to `reset()`), and you want the
373  /// storage to be backed by the ImageCache (including storing the
374  /// pixels in whatever data format that implies), then the file contents
375  /// will be automatically read the first time you make any other
376  /// ImageBuf API call that requires the spec or pixel values. The only
377  /// reason to call `read()` yourself is if you are changing the
378  /// filename, subimage, or MIP level, or if you want to use `force =
379  /// true` or a specific `convert` value to force data format conversion.
380  ///
381  /// @param subimage/miplevel
382  /// The subimage and MIP level to read.
383  /// @param force
384  /// If `true`, will force an immediate full read into
385  /// ImageBuf-owned local pixel memory (yielding a
386  /// `LOCALPIXELS` storage buffer). Otherwise, it is up to
387  /// the implementation whether to immediately read or have
388  /// the image backed by an ImageCache (storage
389  /// `IMAGECACHE`, if the ImageBuf was originall constructed
390  /// or reset with an ImageCache specified).
391  /// @param convert
392  /// If set to a specific type (not`UNKNOWN`), the ImageBuf
393  /// memory will be allocated for that type specifically and
394  /// converted upon read.
395  /// @param progress_callback/progress_callback_data
396  /// If `progress_callback` is non-NULL, the underlying
397  /// read, if expensive, may make several calls to
398  /// `progress_callback(progress_callback_data, portion_done)`
399  /// which allows you to implement some sort of progress
400  /// meter. Note that if the ImageBuf is backed by an
401  /// ImageCache, the progress callback will never be called,
402  /// since no actual file I/O will occur at this time
403  /// (ImageCache will load tiles or scanlines on demand, as
404  /// individual pixel values are needed).
405  ///
406  /// @returns
407  /// `true` upon success, or `false` if the read failed (in
408  /// which case, you should be able to retrieve an error
409  /// message via `geterror()`).
410  ///
411  bool read(int subimage = 0, int miplevel = 0, bool force = false,
413  ProgressCallback progress_callback = nullptr,
414  void* progress_callback_data = nullptr);
415 
416  /// Read the file, if possible only allocating and reading a subset of
417  /// channels, `[chbegin..chend-1]`. This can be a performance and memory
418  /// improvement for some image file formats, if you know that any use of
419  /// the ImageBuf will only access a subset of channels from a
420  /// many-channel file.
421  ///
422  /// Additional parameters:
423  ///
424  /// @param chbegin/chend
425  /// The subset (a range with "exclusive end") of channels to
426  /// read, if the implementation is able to read only a
427  /// subset of channels and have a performance advantage by
428  /// doing so. If `chbegin` is 0 and `chend` is either
429  /// negative or greater than the number of channels in the
430  /// file, all channels will be read. Please note that it is
431  /// "advisory" and not guaranteed to be honored by the
432  /// underlying implementation.
433  bool read(int subimage, int miplevel, int chbegin, int chend, bool force,
434  TypeDesc convert, ProgressCallback progress_callback = nullptr,
435  void* progress_callback_data = nullptr);
436 
437  /// Read the ImageSpec for the given file, subimage, and MIP level into
438  /// the ImageBuf, but will not read the pixels or allocate any local
439  /// storage (until a subsequent call to `read()`). This is helpful if
440  /// you have an ImageBuf and you need to know information about the
441  /// image, but don't want to do a full read yet, and maybe won't need to
442  /// do the full read, depending on what's found in the spec.
443  ///
444  /// Note that `init_spec()` is not strictly necessary. If you are happy
445  /// with the filename, subimage and MIP level specified by the ImageBuf
446  /// constructor (or the last call to `reset()`), then the spec will be
447  /// automatically read the first time you make any other ImageBuf API
448  /// call that requires it. The only reason to call `read()` yourself is
449  /// if you are changing the filename, subimage, or MIP level, or if you
450  /// want to use `force=true` or a specific `convert` value to force
451  /// data format conversion.
452  ///
453  /// @param filename
454  /// The filename to read from (should be the same as the
455  /// filename used when the ImageBuf was constructed or
456  /// reset.)
457  /// @param subimage/miplevel
458  /// The subimage and MIP level to read.
459  ///
460  /// @returns
461  /// `true` upon success, or `false` if the read failed (in
462  /// which case, you should be able to retrieve an error
463  /// message via `geterror()`).
464  ///
465  bool init_spec(string_view filename, int subimage, int miplevel);
466 
467  /// Write the image to the named file, converted to the specified pixel
468  /// data type `dtype` (`TypeUnknown` signifies to use the data type of
469  /// the buffer), and file format (an empty `fileformat` means to infer
470  /// the type from the filename extension).
471  ///
472  /// By default, it will always try to write a scanline-oriented file,
473  /// unless the `set_write_tiles()` method has been used to override
474  /// this.
475  ///
476  /// @param filename
477  /// The filename to write to.
478  /// @param dtype
479  /// Optional override of the pixel data format to use in the
480  /// file being written. The default (`UNKNOWN`) means to try
481  /// writing the same data format that as pixels are stored
482  /// within the ImageBuf memory (or whatever type was
483  /// specified by a prior call to `set_write_format()`). In
484  /// either case, if the file format does not support that
485  /// data type, another will be automatically chosen that is
486  /// supported by the file type and loses as little precision
487  /// as possible.
488  /// @param fileformat
489  /// Optional override of the file format to write. The
490  /// default (empty string) means to infer the file format
491  /// from the extension of the `filename` (for
492  /// example, "foo.tif" will write a TIFF file).
493  /// @param progress_callback/progress_callback_data
494  /// If `progress_callback` is non-NULL, the underlying
495  /// write, if expensive, may make several calls to
496  /// `progress_callback(progress_callback_data, portion_done)`
497  /// which allows you to implement some sort of progress
498  /// meter.
499  ///
500  /// @returns
501  /// `true` upon success, or `false` if the write failed (in
502  /// which case, you should be able to retrieve an error
503  /// message via `geterror()`).
504  ///
505 
506  bool write(string_view filename, TypeDesc dtype = TypeUnknown,
507  string_view fileformat = string_view(),
508  ProgressCallback progress_callback = nullptr,
509  void* progress_callback_data = nullptr) const;
510 
511 #ifndef DOXYGEN_SHOULD_SKIP_THIS
512  // DEPRECATED(1.9): old version did not have the data type
513  OIIO_DEPRECATED("use other write() that takes the dtype argument (1.9)")
514  bool write(string_view filename, string_view fileformat,
515  ProgressCallback progress_callback = nullptr,
516  void* progress_callback_data = nullptr) const
517  {
518  return write(filename, TypeUnknown, fileformat, progress_callback,
519  progress_callback_data);
520  }
521 #endif // DOXYGEN_SHOULD_SKIP_THIS
522 
523  /// Set the pixel data format that will be used for subsequent `write()`
524  /// calls that do not themselves request a specific data type request.
525  ///
526  /// Note that this does not affect the variety of `write()` that takes
527  /// an open `ImageOutput*` as a parameter.
528  ///
529  /// @param format
530  /// The data type to be used for all channels.
531  void set_write_format(TypeDesc format);
532 
533  /// Set the per-channel pixel data format that will be used for
534  /// subsequent `write()` calls that do not themselves request a specific
535  /// data type request.
536  ///
537  /// @param format
538  /// The type of each channel (in order). Any channel's
539  /// format specified as `TypeUnknown` will default to be
540  /// whatever type is described in the ImageSpec of the
541  /// buffer.
542  void set_write_format(cspan<TypeDesc> format);
543 
544  /// Override the tile sizing for subsequent calls to the `write()`
545  /// method (the variety that does not take an open `ImageOutput*`).
546  /// Setting all three dimensions to 0 indicates that the output should
547  /// be a scanline-oriented file.
548  ///
549  /// This lets you write a tiled file from an ImageBuf that may have been
550  /// read originally from a scanline file, or change the dimensions of a
551  /// tiled file, or to force the file written to be scanline even if it
552  /// was originally read from a tiled file.
553  ///
554  /// In all cases, if the file format ultimately written does not support
555  /// tiling, or the tile dimensions requested, a suitable supported
556  /// tiling choice will be made automatically.
557  void set_write_tiles(int width = 0, int height = 0, int depth = 0);
558 
559  /// Supply an IOProxy to use for a subsequent call to `write()`.
560  ///
561  /// If a proxy is set but it later turns out that the file format
562  /// selected does not support write proxies, then `write()` will fail
563  /// with an error.
564  void set_write_ioproxy(Filesystem::IOProxy* ioproxy);
565 
566  /// Write the pixels of the ImageBuf to an open ImageOutput. The
567  /// ImageOutput must have already been opened with a spec that indicates
568  /// a resolution identical to that of this ImageBuf (but it may have
569  /// specified a different pixel data type, in which case data
570  /// conversions will happen automatically). This method does NOT close
571  /// the file when it's done (and so may be called in a loop to write a
572  /// multi-image file).
573  ///
574  /// Note that since this uses an already-opened `ImageOutput`, which is
575  /// too late to change how it was opened, it does not honor any prior
576  /// calls to `set_write_format` or `set_write_tiles`.
577  ///
578  /// The main application of this method is to allow an ImageBuf (which
579  /// by design may hold only a *single* image) to be used for the output
580  /// of one image of a multi-subimage and/or MIP-mapped image file.
581  ///
582  /// @param out
583  /// A pointer to an already-opened `ImageOutput` to which
584  /// the pixels of the ImageBuf will be written.
585  /// @param progress_callback/progress_callback_data
586  /// If `progress_callback` is non-NULL, the underlying
587  /// write, if expensive, may make several calls to
588  /// `progress_callback(progress_callback_data, portion_done)`
589  /// which allows you to implement some sort of progress
590  /// meter.
591  /// @returns `true` if all went ok, `false` if there were errors
592  /// writing.
593  bool write(ImageOutput* out, ProgressCallback progress_callback = nullptr,
594  void* progress_callback_data = nullptr) const;
595 
596  /// @}
597 
598  /// @{
599  /// @name Copying ImageBuf's and blocks of pixels
600 
601  /// Copy assignment.
602  const ImageBuf& operator=(const ImageBuf& src);
603 
604  /// Move assignment.
605  const ImageBuf& operator=(ImageBuf&& src);
606 
607  /// Copy all the metadata from `src` to `*this` (except for pixel data
608  /// resolution, channel types and names, and data format).
609  void copy_metadata(const ImageBuf& src);
610 
611  /// Copy the pixel data from `src` to `*this`, automatically converting
612  /// to the existing data format of `*this`. It only copies pixels in
613  /// the overlap regions (and channels) of the two images; pixel data in
614  /// `*this` that do exist in `src` will be set to 0, and pixel data in
615  /// `src` that do not exist in `*this` will not be copied.
616  bool copy_pixels(const ImageBuf& src);
617 
618  /// Try to copy the pixels and metadata from `src` to `*this`
619  /// (optionally with an explicit data format conversion).
620  ///
621  /// If the previous state of `*this` was uninitialized, owning its own
622  /// local pixel memory, or referring to a read-only image backed by
623  /// ImageCache, then local pixel memory will be allocated to hold the
624  /// new pixels and the call always succeeds unless the memory cannot be
625  /// allocated. In this case, the `format` parameter may request a pixel
626  /// data type that is different from that of the source buffer.
627  ///
628  /// If `*this` previously referred to an app-owned memory buffer, the
629  /// memory cannot be re-allocated, so the call will only succeed if the
630  /// app-owned buffer is already the correct resolution and number of
631  /// channels. The data type of the pixels will be converted
632  /// automatically to the data type of the app buffer.
633  ///
634  /// @param src
635  /// Another ImageBuf from which to copy the pixels and
636  /// metadata.
637  /// @param format
638  /// Optionally request the pixel data type to be used. The
639  /// default of `TypeUnknown` means to use whatever data type
640  /// is used by the `src`. If `*this` is already initialized
641  /// and has `APPBUFFER` storage ("wrapping" an application
642  /// buffer), this parameter is ignored.
643  /// @returns
644  /// `true` upon success or `false` upon error/failure.
645  bool copy(const ImageBuf& src, TypeDesc format = TypeUnknown);
646 
647  /// Return a full copy of `this` ImageBuf (optionally with an explicit
648  /// data format conversion).
649  ImageBuf copy(TypeDesc format /*= TypeDesc::UNKNOWN*/) const;
650 
651  /// Swap the entire contents with another ImageBuf.
652  void swap(ImageBuf& other) { std::swap(m_impl, other.m_impl); }
653 
654  /// @}
655 
656 
657  /// @{
658  /// @name Getting and setting pixel values
659 
660  /// Retrieve a single channel of one pixel.
661  ///
662  /// @param x/y/z
663  /// The pixel coordinates.
664  /// @param c
665  /// The channel index to retrieve.
666  /// @param wrap
667  /// WrapMode that determines the behavior if the pixel
668  /// coordinates are outside the data window: `WrapBlack`,
669  /// `WrapClamp`, `WrapPeriodic`, `WrapMirror`.
670  /// @returns
671  /// The data value, converted to a `float`.
672  float getchannel(int x, int y, int z, int c,
673  WrapMode wrap = WrapBlack) const;
674 
675  /// Retrieve the pixel value by x, y, z pixel indices, placing its
676  /// contents in `pixel[0..n-1]` where *n* is the smaller of
677  /// `maxchannels` the actual number of channels stored in the buffer.
678  ///
679  /// @param x/y/z
680  /// The pixel coordinates.
681  /// @param pixel
682  /// The results are stored in `pixel[0..nchannels-1]`. It is
683  /// up to the caller to ensure that `pixel` points to enough
684  /// memory to hold the required number of channels.
685  /// @param maxchannels
686  /// Optional clamp to the number of channels retrieved.
687  /// @param wrap
688  /// WrapMode that determines the behavior if the pixel
689  /// coordinates are outside the data window: `WrapBlack`,
690  /// `WrapClamp`, `WrapPeriodic`, `WrapMirror`.
691  void getpixel(int x, int y, int z, float* pixel, int maxchannels = 1000,
692  WrapMode wrap = WrapBlack) const;
693 
694  // Simplified version: 2D, black wrap.
695  void getpixel(int x, int y, float* pixel, int maxchannels = 1000) const
696  {
697  getpixel(x, y, 0, pixel, maxchannels);
698  }
699 
700  /// Sample the image plane at pixel coordinates (x,y), using linear
701  /// interpolation between pixels, placing the result in `pixel[]`.
702  ///
703  /// @param x/y
704  /// The pixel coordinates. Note that pixel data values
705  /// themselves are at the pixel centers, so pixel (i,j) is
706  /// at image plane coordinate (i+0.5, j+0.5).
707  /// @param pixel
708  /// The results are stored in `pixel[0..nchannels-1]`. It is
709  /// up to the caller to ensure that `pixel` points to enough
710  /// memory to hold the number of channels in the image.
711  /// @param wrap
712  /// WrapMode that determines the behavior if the pixel
713  /// coordinates are outside the data window: `WrapBlack`,
714  /// `WrapClamp`, `WrapPeriodic`, `WrapMirror`.
715  void interppixel(float x, float y, float* pixel,
716  WrapMode wrap = WrapBlack) const;
717 
718  /// Linearly interpolate at NDC coordinates (s,t), where (0,0) is
719  /// the upper left corner of the display window, (1,1) the lower
720  /// right corner of the display window.
721  ///
722  /// @note `interppixel()` uses pixel coordinates (ranging 0..resolution)
723  /// whereas `interppixel_NDC()` uses NDC coordinates (ranging 0..1).
724  void interppixel_NDC(float s, float t, float* pixel,
725  WrapMode wrap = WrapBlack) const;
726 
727 #ifndef DOXYGEN_SHOULD_SKIP_THIS
728  // DEPRECATED (1.5) synonym for interppixel_NDC.
729  OIIO_DEPRECATED("use interppixel_NDC (1.5)")
730  void interppixel_NDC_full(float s, float t, float* pixel,
731  WrapMode wrap = WrapBlack) const;
732 #endif
733 
734  /// Bicubic interpolation at pixel coordinates (x,y).
735  void interppixel_bicubic(float x, float y, float* pixel,
736  WrapMode wrap = WrapBlack) const;
737 
738  /// Bicubic interpolation at NDC space coordinates (s,t), where (0,0)
739  /// is the upper left corner of the display (a.k.a. "full") window,
740  /// (1,1) the lower right corner of the display window.
741  void interppixel_bicubic_NDC(float s, float t, float* pixel,
742  WrapMode wrap = WrapBlack) const;
743 
744 
745  /// Set the pixel with coordinates (x,y,0) to have the values in span
746  /// `pixel[]`. The number of channels copied is the minimum of the span
747  /// length and the actual number of channels in the image.
748  void setpixel(int x, int y, cspan<float> pixel)
749  {
750  setpixel(x, y, 0, pixel);
751  }
752 
753  /// Set the pixel with coordinates (x,y,z) to have the values in span
754  /// `pixel[]`. The number of channels copied is the minimum of the span
755  /// length and the actual number of channels in the image.
756  void setpixel(int x, int y, int z, cspan<float> pixel)
757  {
758  setpixel(x, y, z, pixel.data(), int(pixel.size()));
759  }
760 
761  /// Set the `i`-th pixel value of the image (out of width*height*depth),
762  /// from floating-point values in span `pixel[]`. The number of
763  /// channels copied is the minimum of the span length and the actual
764  /// number of channels in the image.
765  void setpixel(int i, cspan<float> pixel)
766  {
767  setpixel(i, pixel.data(), int(pixel.size()));
768  }
769 
770  /// Set the pixel with coordinates (x,y,0) to have the values in
771  /// pixel[0..n-1]. The number of channels copied, n, is the minimum
772  /// of maxchannels and the actual number of channels in the image.
773  void setpixel(int x, int y, const float* pixel, int maxchannels = 1000)
774  {
775  setpixel(x, y, 0, pixel, maxchannels);
776  }
777 
778  /// Set the pixel with coordinates (x,y,z) to have the values in
779  /// `pixel[0..n-1]`. The number of channels copied, n, is the minimum
780  /// of `maxchannels` and the actual number of channels in the image.
781  void setpixel(int x, int y, int z, const float* pixel,
782  int maxchannels = 1000);
783 
784  /// Set the `i`-th pixel value of the image (out of width*height*depth),
785  /// from floating-point values in `pixel[]`. Set at most
786  /// `maxchannels` (will be clamped to the actual number of channels).
787  void setpixel(int i, const float* pixel, int maxchannels = 1000);
788 
789  /// Retrieve the rectangle of pixels spanning the ROI (including
790  /// channels) at the current subimage and MIP-map level, storing the
791  /// pixel values beginning at the address specified by result and with
792  /// the given strides (by default, AutoStride means the usual contiguous
793  /// packing of pixels) and converting into the data type described by
794  /// `format`. It is up to the caller to ensure that result points to an
795  /// area of memory big enough to accommodate the requested rectangle.
796  /// Return true if the operation could be completed, otherwise return
797  /// false.
798  bool get_pixels(ROI roi, TypeDesc format, void* result,
799  stride_t xstride = AutoStride,
800  stride_t ystride = AutoStride,
801  stride_t zstride = AutoStride) const;
802 
803  /// Copy the data into the given ROI of the ImageBuf. The data points to
804  /// values specified by `format`, with layout detailed by the stride
805  /// values (in bytes, with AutoStride indicating "contiguous" layout). It
806  /// is up to the caller to ensure that data points to an area of memory
807  /// big enough to account for the ROI. If `roi` is set to `ROI::all()`,
808  /// the data buffer is assumed to have the same resolution as the ImageBuf
809  /// itself. Return true if the operation could be completed, otherwise
810  /// return false.
811  bool set_pixels(ROI roi, TypeDesc format, const void* data,
812  stride_t xstride = AutoStride,
813  stride_t ystride = AutoStride,
814  stride_t zstride = AutoStride);
815 
816  /// @}
817 
818  /// @{
819  /// @name Getting and setting information about an ImageBuf
820 
821  /// Returns `true` if the ImageBuf is initialized, `false` if not yet
822  /// initialized.
823  bool initialized() const;
824 
825  /// Which type of storage is being used for the pixels? Returns an
826  /// enumerated type describing the type of storage currently employed by
827  /// the ImageBuf: `UNINITIALIZED` (no storage), `LOCALBUFFER` (the
828  /// ImageBuf has allocated and owns the pixel memory), `APPBUFFER` (the
829  /// ImageBuf "wraps" memory owned by the calling application), or
830  /// `IMAGECACHE` (the image is backed by an ImageCache).
831  IBStorage storage() const;
832 
833  /// Return a read-only (const) reference to the image spec that
834  /// describes the buffer.
835  const ImageSpec& spec() const;
836 
837  /// Return a writable reference to the ImageSpec that describes the
838  /// buffer. It's ok to modify most of the metadata, but if you modify
839  /// the spec's `format`, `width`, `height`, or `depth` fields, you get
840  /// the pain you deserve, as the ImageBuf will no longer have correct
841  /// knowledge of its pixel memory layout. USE WITH EXTREME CAUTION.
842  ImageSpec& specmod();
843 
844  /// Return a read-only (const) reference to the "native" image spec
845  /// (that describes the file, which may be slightly different than
846  /// the spec of the ImageBuf, particularly if the IB is backed by an
847  /// ImageCache that is imposing some particular data format or tile
848  /// size).
849  ///
850  /// This may differ from `spec()` --- for example, if a data format
851  /// conversion was requested, if the buffer is backed by an ImageCache
852  /// which stores the pixels internally in a different data format than
853  /// that of the file, or if the file had differing per-channel data
854  /// formats (ImageBuf must contain a single data format for all
855  /// channels).
856  const ImageSpec& nativespec() const;
857 
858  /// Does this ImageBuf have an associated thumbnail?
859  bool has_thumbnail() const;
860 
861  /// Return a shared pointer to an ImageBuf containing a thumbnail of the
862  /// image (if it existed in the file), which may be empty if there is no
863  /// thumbnail.
864  std::shared_ptr<ImageBuf> get_thumbnail() const;
865 
866  /// Reset the thumbnail image associated with this ImageBuf to `thumb`.
867  /// This call will invalidate any references previously returned by
868  /// `thumbnail()`.
869  void set_thumbnail(const ImageBuf& thumb);
870 
871  /// Clear any thumbnail associated with this ImageBuf. This call will
872  /// invalidate any references previously returned by `thumbnail()`.
873  void clear_thumbnail();
874 
875  /// Returns the name of the buffer (name of the file, for an ImageBuf
876  /// read from disk).
877  string_view name(void) const;
878 
879  /// Return the name of the buffer as a ustring.
880  ustring uname(void) const;
881 
882  /// Return the name of the image file format of the file this ImageBuf
883  /// refers to (for example `"openexr"`). Returns an empty string for an
884  /// ImageBuf that was not constructed as a direct reference to a file.
885  string_view file_format_name(void) const;
886 
887  /// Return the index of the subimage within the file that the ImageBuf
888  /// refers to. This will always be 0 for an ImageBuf that was not
889  /// constructed as a direct reference to a file, or if the file
890  /// contained only one image.
891  int subimage() const;
892 
893  /// Return the number of subimages in the file this ImageBuf refers to, if
894  /// it can be determined efficiently. This will always be 1 for an
895  /// ImageBuf that was not constructed as a direct reference to a file, or
896  /// for an ImageBuf that refers to a file type that is not capable of
897  /// containing multiple subimages.
898  ///
899  /// Note that a return value of 0 indicates that the number of subimages
900  /// cannot easily be known without reading the entire image file to
901  /// discover the total. To compute this yourself, you would need check
902  /// every subimage successively until you get an error.
903  int nsubimages() const;
904 
905  /// Return the index of the miplevel with a file's subimage that the
906  /// ImageBuf is currently holding. This will always be 0 for an ImageBuf
907  /// that was not constructed as a direct reference to a file, or if the
908  /// subimage within that file was not MIP-mapped.
909  int miplevel() const;
910 
911  /// Return the number of MIP levels of the current subimage within the
912  /// file this ImageBuf refers to. This will always be 1 for an ImageBuf
913  /// that was not constructed as a direct reference to a file, or if this
914  /// subimage within the file was not MIP-mapped.
915  int nmiplevels() const;
916 
917  /// Return the number of color channels in the image. This is equivalent
918  /// to `spec().nchannels`.
919  int nchannels() const;
920 
921  /// Return the beginning (minimum) x coordinate of the defined image.
922  int xbegin() const;
923  /// Return the end (one past maximum) x coordinate of the defined image.
924  int xend() const;
925  /// Return the beginning (minimum) y coordinate of the defined image.
926  int ybegin() const;
927  /// Return the end (one past maximum) y coordinate of the defined image.
928  int yend() const;
929  /// Return the beginning (minimum) z coordinate of the defined image.
930  int zbegin() const;
931  /// Return the end (one past maximum) z coordinate of the defined image.
932  int zend() const;
933  /// Return the minimum x coordinate of the defined image.
934  int xmin() const;
935  /// Return the maximum x coordinate of the defined image.
936  int xmax() const;
937  /// Return the minimum y coordinate of the defined image.
938  int ymin() const;
939  /// Return the maximum y coordinate of the defined image.
940  int ymax() const;
941  /// Return the minimum z coordinate of the defined image.
942  int zmin() const;
943  /// Return the maximum z coordinate of the defined image.
944  int zmax() const;
945 
946  /// Return the current `"Orientation"` metadata for the image, per the
947  /// table in `sec-metadata-orientation`_
948  int orientation() const;
949 
950  /// Set the `"Orientation"` metadata for the image.
951  void set_orientation(int orient);
952 
953  // Return the width, height, or full versions, if the image were
954  // positioned for display in its designated orientation.
955  int oriented_width() const;
956  int oriented_height() const;
957  int oriented_x() const;
958  int oriented_y() const;
959  int oriented_full_width() const;
960  int oriented_full_height() const;
961  int oriented_full_x() const;
962  int oriented_full_y() const;
963 
964  /// Alters the metadata of the spec in the ImageBuf to reset the
965  /// "origin" of the pixel data window to be the specified coordinates.
966  /// This does not affect the size of the pixel data window, only its
967  /// position.
968  void set_origin(int x, int y, int z = 0);
969 
970  /// Set the "full" (a.k.a. display) window to Alters the metadata of the
971  /// spec in the ImageBuf to reset the "full" image size (a.k.a.
972  /// "display window") to
973  ///
974  /// [xbegin,xend) x [ybegin,yend) x [zbegin,zend)`
975  ///
976  /// This does not affect the size of the pixel data window.
977  void set_full(int xbegin, int xend, int ybegin, int yend, int zbegin,
978  int zend);
979 
980  /// Return pixel data window for this ImageBuf as a ROI.
981  ROI roi() const;
982 
983  /// Return full/display window for this ImageBuf as a ROI.
984  ROI roi_full() const;
985 
986  /// Set full/display window for this ImageBuf to a ROI.
987  /// Does NOT change the channels of the spec, regardless of `newroi`.
988  void set_roi_full(const ROI& newroi);
989 
990  /// Is the specified roi completely contained in the data window of
991  /// this ImageBuf?
992  bool contains_roi(ROI roi) const;
993 
994  bool pixels_valid(void) const;
995 
996  /// The data type of the pixels stored in the buffer (equivalent to
997  /// `spec().format`).
998  TypeDesc pixeltype() const;
999 
1000  /// Return a raw pointer to "local" pixel memory, if they are fully in
1001  /// RAM and not backed by an ImageCache, or `nullptr` otherwise. You
1002  /// can also test it like a bool to find out if pixels are local.
1003  ///
1004  /// Note that the data are not necessarily contiguous; use the
1005  /// `pixel_stride()`, `scanline_stride()`, and `z_stride()` methods
1006  /// to find out the spacing between pixels, scanlines, and volumetric
1007  /// planes, respectively.
1008  void* localpixels();
1009  const void* localpixels() const;
1010 
1011  /// Pixel-to-pixel stride within the localpixels memory.
1012  stride_t pixel_stride() const;
1013  /// Scanline-to-scanline stride within the localpixels memory.
1014  stride_t scanline_stride() const;
1015  /// Z plane stride within the localpixels memory.
1016  stride_t z_stride() const;
1017 
1018  /// Is the data layout "contiguous", i.e.,
1019  /// ```
1020  /// pixel_stride == nchannels * pixeltype().size()
1021  /// scanline_stride == pixel_stride * spec().width
1022  /// z_stride == scanline_stride * spec().height
1023  /// ```
1024  bool contiguous() const;
1025 
1026  /// Are the pixels backed by an ImageCache, rather than the whole
1027  /// image being in RAM somewhere?
1028  bool cachedpixels() const;
1029 
1030  /// A pointer to the underlying ImageCache, or nullptr if this ImageBuf
1031  /// is not backed by an ImageCache.
1032  ImageCache* imagecache() const;
1033 
1034  /// Return the address where pixel `(x,y,z)`, channel `ch`, is stored in
1035  /// the image buffer. Use with extreme caution! Will return `nullptr`
1036  /// if the pixel values aren't local in RAM.
1037  const void* pixeladdr(int x, int y, int z = 0, int ch = 0) const;
1038  void* pixeladdr(int x, int y, int z = 0, int ch = 0);
1039 
1040  /// Return the index of pixel (x,y,z). If check_range is true, return
1041  /// -1 for an invalid coordinate that is not within the data window.
1042  int pixelindex(int x, int y, int z, bool check_range = false) const;
1043 
1044  /// Set the threading policy for this ImageBuf, controlling the maximum
1045  /// amount of parallelizing thread "fan-out" that might occur during
1046  /// expensive operations. The default of 0 means that the global
1047  /// `attribute("threads")` value should be used (which itself defaults
1048  /// to using as many threads as cores).
1049  ///
1050  /// The main reason to change this value is to set it to 1 to indicate
1051  /// that the calling thread should do all the work rather than spawning
1052  /// new threads. That is probably the desired behavior in situations
1053  /// where the calling application has already spawned multiple worker
1054  /// threads.
1055  void threads(int n) const;
1056 
1057  /// Retrieve the current thread-spawning policy of this ImageBuf.
1058  int threads() const;
1059 
1060  /// @}
1061 
1062  /// @{
1063  /// @name Error handling
1064 
1065  /// Add simple string to the error message list for this IB. It is not
1066  /// necessary to have the error message contain a trailing newline.
1067  void error(string_view message) const;
1068 
1069  /// Error reporting for ImageBuf: call this with std::format style
1070  /// formatting specification. It is not necessary to have the error
1071  /// message contain a trailing newline.
1072  template<typename... Args>
1073  void errorfmt(const char* fmt, const Args&... args) const
1074  {
1075  error(Strutil::fmt::format(fmt, args...));
1076  }
1077 
1078  /// Error reporting for ImageBuf: call this with printf-like arguments
1079  /// to report an error. It is not necessary to have the error message
1080  /// contain a trailing newline.
1081  template<typename... Args>
1082  void errorf(const char* fmt, const Args&... args) const
1083  {
1084  error(Strutil::sprintf(fmt, args...));
1085  }
1086 
1087  /// Error reporting for ImageBuf: call this with Strutil::format
1088  /// formatting conventions. It is not necessary to have the error
1089  /// message contain a trailing newline. Beware, this is in transition,
1090  /// is currently printf-like but will someday change to python-like!
1091  template<typename... Args>
1092  OIIO_FORMAT_DEPRECATED void error(const char* fmt,
1093  const Args&... args) const
1094  {
1095  error(Strutil::format(fmt, args...));
1096  }
1097 
1098  // Error reporting for ImageBuf: call this with Python / {fmt} /
1099  // std::format style formatting specification.
1100  template<typename... Args>
1101  OIIO_DEPRECATED("use `errorfmt` instead")
1102  void fmterror(const char* fmt, const Args&... args) const
1103  {
1104  error(Strutil::fmt::format(fmt, args...));
1105  }
1106 
1107  /// Returns `true` if the ImageBuf has had an error and has an error
1108  /// message ready to retrieve via `geterror()`.
1109  bool has_error(void) const;
1110 
1111  /// Return the text of all pending error messages issued against this
1112  /// ImageBuf, and clear the pending error message unless `clear` is
1113  /// false. If no error message is pending, it will return an empty
1114  /// string.
1115  std::string geterror(bool clear = true) const;
1116 
1117  /// @}
1118 
1119  /// @{
1120  /// @name Deep data in an ImageBuf
1121 
1122  /// Does this ImageBuf store deep data? Returns `true` if the ImageBuf
1123  /// holds a "deep" image, `false` if the ImageBuf holds an ordinary
1124  /// pixel-based image.
1125  bool deep() const;
1126 
1127  /// Retrieve the number of deep data samples corresponding to pixel
1128  /// (x,y,z). Return 0 if not a deep image, or if the pixel is outside
1129  /// of the data window, or if the designated pixel has no deep samples.
1130  int deep_samples(int x, int y, int z = 0) const;
1131 
1132  /// Return a pointer to the raw data of pixel `(x,y,z)`, channel `c`,
1133  /// sample `s`. Return `nullptr` if the pixel coordinates or channel
1134  /// number are out of range, if the pixel/channel has no deep samples,
1135  /// or if the image is not deep. Use with caution --- these pointers may
1136  /// be invalidated by calls that adjust the number of samples in any
1137  /// pixel.
1138  const void* deep_pixel_ptr(int x, int y, int z, int c, int s = 0) const;
1139 
1140  /// Return the value (as a `float`) of sample `s` of channel `c` of
1141  /// pixel `(x,y,z)`. Return 0 if not a deep image or if the pixel
1142  /// coordinates or channel number are out of range or if that pixel has
1143  /// no deep samples.
1144  float deep_value(int x, int y, int z, int c, int s) const;
1145 
1146  /// Return the value (as a `uint32_t`) of sample `s` of channel `c` of
1147  /// pixel `(x,y,z)`. Return 0 if not a deep image or if the pixel
1148  /// coordinates or channel number are out of range or if that pixel has
1149  /// no deep samples.
1150  uint32_t deep_value_uint(int x, int y, int z, int c, int s) const;
1151 
1152  /// Set the number of deep samples for pixel (x,y,z). If data has
1153  /// already been allocated, this is equivalent to inserting or erasing
1154  /// samples.
1155  void set_deep_samples(int x, int y, int z, int nsamples);
1156 
1157  /// Insert `nsamples` new samples, starting at position `samplepos` of
1158  /// pixel (x,y,z).
1159  void deep_insert_samples(int x, int y, int z, int samplepos, int nsamples);
1160 
1161  /// Remove `nsamples` samples, starting at position `samplepos` of pixel
1162  /// (x,y,z).
1163  void deep_erase_samples(int x, int y, int z, int samplepos, int nsamples);
1164 
1165  /// Set the value of sample `s` of channel `c` of pixel `(x,y,z)` to a
1166  /// `float` value (it is expected that channel `c` is a floating point
1167  /// type).
1168  void set_deep_value(int x, int y, int z, int c, int s, float value);
1169 
1170  /// Set the value of sample `s` of channel `c` of pixel `(x,y,z)` to a
1171  /// `uint32_t` value (it is expected that channel `c` is an integer
1172  /// type).
1173  void set_deep_value(int x, int y, int z, int c, int s, uint32_t value);
1174 
1175  /// Copy a deep pixel from another ImageBuf -- it is required to have
1176  /// the same channels.
1177  bool copy_deep_pixel(int x, int y, int z, const ImageBuf& src, int srcx,
1178  int srcy, int srcz);
1179 
1180  /// Retrieve the "deep" data.
1181  DeepData* deepdata();
1182  const DeepData* deepdata() const;
1183 
1184  /// @}
1185 
1186  /// Return the `WrapMode` corresponding to the name (`"default"`,
1187  /// `"black"`, `"clamp"`, `"periodic"`, `"mirror"`). For an unknown
1188  /// name, this will return `WrapDefault`.
1189  static WrapMode WrapMode_from_string(string_view name);
1190 
1191 
1192  friend class IteratorBase;
1193 
1194  /// Base class for Iterator and ConstIterator -- this contains all the
1195  /// common functionality.
1197  protected:
1198  OIIO_API IteratorBase(const ImageBuf& ib, WrapMode wrap,
1199  bool write = false);
1200 
1201  OIIO_API IteratorBase(const ImageBuf& ib, int x, int y, int z,
1202  WrapMode wrap, bool write = false);
1203 
1204  /// Construct valid iteration region from ImageBuf and ROI.
1205  OIIO_API IteratorBase(const ImageBuf& ib, const ROI& roi, WrapMode wrap,
1206  bool write = false);
1207 
1208  /// Construct from an ImageBuf and designated region -- iterate
1209  /// over region, starting with the upper left pixel.
1210  OIIO_API IteratorBase(const ImageBuf& ib, int xbegin, int xend,
1211  int ybegin, int yend, int zbegin, int zend,
1212  WrapMode wrap, bool write = false);
1213 
1214  /// Copy constructor
1215  OIIO_API IteratorBase(const IteratorBase& i);
1216 
1217  /// Assign one IteratorBase to another
1218  OIIO_API const IteratorBase& operator=(const IteratorBase& i);
1219 
1221  {
1222  if (m_tile)
1223  release_tile();
1224  }
1225 
1226  public:
1227  /// Retrieve the current x location of the iterator.
1228  int x() const { return m_x; }
1229  /// Retrieve the current y location of the iterator.
1230  int y() const { return m_y; }
1231  /// Retrieve the current z location of the iterator.
1232  int z() const { return m_z; }
1233 
1234  /// Is the current location within the designated iteration range?
1235  bool valid() const { return m_valid; }
1236 
1237  /// Is the location (x,y[,z]) within the designated iteration
1238  /// range?
1239  bool valid(int x_, int y_, int z_ = 0) const
1240  {
1241  return (x_ >= m_rng_xbegin && x_ < m_rng_xend && y_ >= m_rng_ybegin
1242  && y_ < m_rng_yend && z_ >= m_rng_zbegin
1243  && z_ < m_rng_zend);
1244  }
1245 
1246  /// Is the location (x,y[,z]) within the region of the ImageBuf
1247  /// that contains pixel values (sometimes called the "data window")?
1248  bool exists(int x_, int y_, int z_ = 0) const
1249  {
1250  return (x_ >= m_img_xbegin && x_ < m_img_xend && y_ >= m_img_ybegin
1251  && y_ < m_img_yend && z_ >= m_img_zbegin
1252  && z_ < m_img_zend);
1253  }
1254  /// Does the current location exist within the ImageBuf's
1255  /// data window?
1256  bool exists() const { return m_exists; }
1257 
1258  /// Are we finished iterating over the region?
1259  bool done() const
1260  {
1261  // We're "done" if we are both invalid and in exactly the
1262  // spot that we would end up after iterating off of the last
1263  // pixel in the range. (The m_valid test is just a quick
1264  // early-out for when we're in the correct pixel range.)
1265  return (m_valid == false && m_x == m_rng_xbegin
1266  && m_y == m_rng_ybegin && m_z == m_rng_zend);
1267  }
1268 
1269  /// Retrieve the number of deep data samples at this pixel.
1270  int deep_samples() const { return m_ib->deep_samples(m_x, m_y, m_z); }
1271 
1272  /// Return the wrap mode
1273  WrapMode wrap() const { return m_wrap; }
1274 
1275  /// Explicitly point the iterator. This results in an invalid
1276  /// iterator if outside the previously-designated region.
1277  void OIIO_API pos(int x_, int y_, int z_ = 0);
1278 
1279  /// Increment to the next pixel in the region.
1280  ///
1281  inline void operator++()
1282  {
1283  if (++m_x < m_rng_xend) {
1284  // Special case: we only incremented x, didn't change y
1285  // or z, and the previous position was within the data
1286  // window. Call a shortcut version of pos.
1287  if (m_exists) {
1288  pos_xincr();
1289  return;
1290  }
1291  } else {
1292  // Wrap to the next scanline
1293  m_x = m_rng_xbegin;
1294  if (++m_y >= m_rng_yend) {
1295  m_y = m_rng_ybegin;
1296  if (++m_z >= m_rng_zend) {
1297  m_valid = false; // shortcut -- finished iterating
1298  return;
1299  }
1300  }
1301  }
1302  pos(m_x, m_y, m_z);
1303  }
1304  /// Increment to the next pixel in the region.
1305  void operator++(int) { ++(*this); }
1306 
1307  /// Return the iteration range
1308  ROI range() const
1309  {
1310  return ROI(m_rng_xbegin, m_rng_xend, m_rng_ybegin, m_rng_yend,
1311  m_rng_zbegin, m_rng_zend, 0, m_ib->nchannels());
1312  }
1313 
1314  /// Reset the iteration range for this iterator and reposition to
1315  /// the beginning of the range, but keep referring to the same
1316  /// image.
1317  void OIIO_API rerange(int xbegin, int xend, int ybegin, int yend,
1318  int zbegin, int zend,
1319  WrapMode wrap = WrapDefault);
1320 
1321  const void* rawptr() const { return m_proxydata; }
1322 
1323  /// Retrieve the deep data value of sample s of channel c.
1324  float deep_value(int c, int s) const
1325  {
1326  return m_ib->deep_value(m_x, m_y, m_z, c, s);
1327  }
1328 
1329  uint32_t deep_value_uint(int c, int s) const
1330  {
1331  return m_ib->deep_value_uint(m_x, m_y, m_z, c, s);
1332  }
1333 
1334  bool localpixels() const { return m_localpixels; }
1335 
1336  // Did we encounter an error while we iterated?
1337  bool has_error() const { return m_readerror; }
1338 
1339  // Clear the error flag
1340  void clear_error() { m_readerror = false; }
1341 
1342  protected:
1343  friend class ImageBuf;
1344  friend class ImageBufImpl;
1345  const ImageBuf* m_ib = nullptr;
1346  bool m_valid = false, m_exists = false;
1347  bool m_deep = false;
1348  bool m_localpixels = false;
1349  // Image boundaries
1350  int m_img_xbegin, m_img_xend, m_img_ybegin, m_img_yend, m_img_zbegin,
1351  m_img_zend;
1352  // Iteration range
1353  int m_rng_xbegin, m_rng_xend, m_rng_ybegin, m_rng_yend, m_rng_zbegin,
1354  m_rng_zend;
1355  int m_x, m_y, m_z;
1356  pvt::ImageCacheTile* m_tile = nullptr;
1357  int m_tilexbegin, m_tileybegin, m_tilezbegin;
1361  char* m_proxydata = nullptr;
1362  WrapMode m_wrap = WrapBlack;
1363  bool m_readerror = false;
1364 
1365  // Helper called by ctrs -- set up some locally cached values
1366  // that are copied or derived from the ImageBuf.
1367  void OIIO_API init_ib(WrapMode wrap, bool write);
1368 
1369  // Helper called by ctrs -- make the iteration range the full
1370  // image data window.
1371  void OIIO_API range_is_image();
1372 
1373  // Helper called by pos(), but ONLY for the case where we are
1374  // moving from an existing pixel to the next spot in +x.
1375  // Note: called *after* m_x was incremented!
1376  inline void pos_xincr()
1377  {
1378  OIIO_DASSERT(m_exists && m_valid); // precondition
1379  OIIO_DASSERT(valid(m_x, m_y, m_z)); // should be true by definition
1380  if (m_localpixels) {
1381  OIIO_DASSERT(m_proxydata != nullptr);
1382  m_proxydata += m_pixel_stride;
1383  if (OIIO_UNLIKELY(m_x >= m_img_xend))
1384  pos_xincr_local_past_end();
1385  } else if (!m_deep) {
1386  // Cached image
1387  m_proxydata += m_pixel_stride;
1388  bool e = m_x < m_img_xend;
1389  if (OIIO_UNLIKELY(!(e && m_x < m_tilexend && m_tile))) {
1390  // Crossed a tile boundary
1391  m_proxydata = (char*)m_ib->retile(m_x, m_y, m_z, m_tile,
1392  m_tilexbegin,
1393  m_tileybegin,
1394  m_tilezbegin, m_tilexend,
1395  m_readerror, e, m_wrap);
1396  m_exists = e;
1397  }
1398  }
1399  }
1400 
1401  // Helper for pos_xincr for when we go off the end of the row
1402  void OIIO_API pos_xincr_local_past_end();
1403 
1404  // Set to the "done" position
1405  void OIIO_API pos_done();
1406 
1407  // Helper to release the IC tile held by m_tile. This is implemented
1408  // elsewhere to prevent imagebuf.h needing to know anything more
1409  // about ImageCache.
1410  void OIIO_API release_tile();
1411  };
1412 
1413  /// Templated class for referring to an individual pixel in an
1414  /// ImageBuf, iterating over the pixels of an ImageBuf, or iterating
1415  /// over the pixels of a specified region of the ImageBuf
1416  /// [xbegin..xend) X [ybegin..yend). It is templated on BUFT, the
1417  /// type known to be in the internal representation of the ImageBuf,
1418  /// and USERT, the type that the user wants to retrieve or set the
1419  /// data (defaulting to float). the whole idea is to allow this:
1420  /// \code
1421  /// ImageBuf img (...);
1422  /// ImageBuf::Iterator<float> pixel (img, 0, 512, 0, 512);
1423  /// for ( ; ! pixel.done(); ++pixel) {
1424  /// for (int c = 0; c < img.nchannels(); ++c) {
1425  /// float x = pixel[c];
1426  /// pixel[c] = ...;
1427  /// }
1428  /// }
1429  /// \endcode
1430  ///
1431  template<typename BUFT, typename USERT = float>
1432  class Iterator : public IteratorBase {
1433  public:
1434  /// Construct from just an ImageBuf -- iterate over the whole
1435  /// region, starting with the upper left pixel of the region.
1436  Iterator(ImageBuf& ib, WrapMode wrap = WrapDefault)
1437  : IteratorBase(ib, wrap, true)
1438  {
1439  }
1440  /// Construct from an ImageBuf and a specific pixel index.
1441  /// The iteration range is the full image.
1442  Iterator(ImageBuf& ib, int x, int y, int z = 0,
1443  WrapMode wrap = WrapDefault)
1444  : IteratorBase(ib, x, y, z, wrap, true)
1445  {
1446  }
1447  /// Construct read-write iteration region from ImageBuf and ROI.
1448  Iterator(ImageBuf& ib, const ROI& roi, WrapMode wrap = WrapDefault)
1449  : IteratorBase(ib, roi, wrap, true)
1450  {
1451  }
1452  /// Construct from an ImageBuf and designated region -- iterate
1453  /// over region, starting with the upper left pixel.
1454  Iterator(ImageBuf& ib, int xbegin, int xend, int ybegin, int yend,
1455  int zbegin = 0, int zend = 1, WrapMode wrap = WrapDefault)
1456  : IteratorBase(ib, xbegin, xend, ybegin, yend, zbegin, zend, wrap,
1457  true)
1458  {
1459  }
1460  /// Copy constructor.
1461  ///
1463  : IteratorBase(i.m_ib, i.m_wrap, true)
1464  {
1465  }
1466 
1468 
1469  /// Dereferencing the iterator gives us a proxy for the pixel,
1470  /// which we can index for reading or assignment.
1472  {
1473  return *(DataArrayProxy<BUFT, USERT>*)(void*)&m_proxydata;
1474  }
1475 
1476  /// Array indexing retrieves the value of the i-th channel of
1477  /// the current pixel.
1478  USERT operator[](int i) const
1479  {
1480  DataArrayProxy<BUFT, USERT> proxy((BUFT*)m_proxydata);
1481  return proxy[i];
1482  }
1483 
1484  /// Array referencing retrieve a proxy (which may be "assigned
1485  /// to") of i-th channel of the current pixel, so that this
1486  /// works: me[i] = val;
1488  {
1489  DataArrayProxy<BUFT, USERT> proxy((BUFT*)m_proxydata);
1490  return proxy[i];
1491  }
1492 
1493  void* rawptr() const { return m_proxydata; }
1494 
1495  /// Set the number of deep data samples at this pixel. (Only use
1496  /// this if deep_alloc() has not yet been called on the buffer.)
1498  {
1499  return const_cast<ImageBuf*>(m_ib)->set_deep_samples(m_x, m_y, m_z,
1500  n);
1501  }
1502 
1503  /// Set the deep data value of sample s of channel c. (Only use this
1504  /// if deep_alloc() has been called.)
1505  void set_deep_value(int c, int s, float value)
1506  {
1507  return const_cast<ImageBuf*>(m_ib)->set_deep_value(m_x, m_y, m_z, c,
1508  s, value);
1509  }
1510  void set_deep_value(int c, int s, uint32_t value)
1511  {
1512  return const_cast<ImageBuf*>(m_ib)->set_deep_value(m_x, m_y, m_z, c,
1513  s, value);
1514  }
1515  };
1516 
1517 
1518  /// Just like an ImageBuf::Iterator, except that it refers to a
1519  /// const ImageBuf.
1520  template<typename BUFT, typename USERT = float>
1521  class ConstIterator : public IteratorBase {
1522  public:
1523  /// Construct from just an ImageBuf -- iterate over the whole
1524  /// region, starting with the upper left pixel of the region.
1525  ConstIterator(const ImageBuf& ib, WrapMode wrap = WrapDefault)
1526  : IteratorBase(ib, wrap)
1527  {
1528  }
1529  /// Construct from an ImageBuf and a specific pixel index.
1530  /// The iteration range is the full image.
1531  ConstIterator(const ImageBuf& ib, int x_, int y_, int z_ = 0,
1532  WrapMode wrap = WrapDefault)
1533  : IteratorBase(ib, x_, y_, z_, wrap)
1534  {
1535  }
1536  /// Construct read-only iteration region from ImageBuf and ROI.
1537  ConstIterator(const ImageBuf& ib, const ROI& roi,
1538  WrapMode wrap = WrapDefault)
1539  : IteratorBase(ib, roi, wrap)
1540  {
1541  }
1542  /// Construct from an ImageBuf and designated region -- iterate
1543  /// over region, starting with the upper left pixel.
1544  ConstIterator(const ImageBuf& ib, int xbegin, int xend, int ybegin,
1545  int yend, int zbegin = 0, int zend = 1,
1546  WrapMode wrap = WrapDefault)
1547  : IteratorBase(ib, xbegin, xend, ybegin, yend, zbegin, zend, wrap)
1548  {
1549  }
1550 
1552 
1553  /// Dereferencing the iterator gives us a proxy for the pixel,
1554  /// which we can index for reading or assignment.
1556  {
1557  return *(ConstDataArrayProxy<BUFT, USERT>*)&m_proxydata;
1558  }
1559 
1560  /// Array indexing retrieves the value of the i-th channel of
1561  /// the current pixel.
1562  USERT operator[](int i) const
1563  {
1564  ConstDataArrayProxy<BUFT, USERT> proxy((BUFT*)m_proxydata);
1565  return proxy[i];
1566  }
1567  };
1568 
1569 
1570 protected:
1571  // PIMPL idiom
1572  static void impl_deleter(ImageBufImpl*);
1573  std::unique_ptr<ImageBufImpl, decltype(&impl_deleter)> m_impl;
1574 
1575  // Reset the ImageCacheTile* to reserve and point to the correct
1576  // tile for the given pixel, and return the ptr to the actual pixel
1577  // within the tile. If any read errors occur, set haderror=true (but
1578  // if there are no errors, do not modify haderror).
1579  const void* retile(int x, int y, int z, pvt::ImageCacheTile*& tile,
1580  int& tilexbegin, int& tileybegin, int& tilezbegin,
1581  int& tilexend, bool& haderr, bool exists,
1582  WrapMode wrap) const;
1583 
1584  // DEPRECATED(2.4)
1585  const void* retile(int x, int y, int z, pvt::ImageCacheTile*& tile,
1586  int& tilexbegin, int& tileybegin, int& tilezbegin,
1587  int& tilexend, bool exists, WrapMode wrap) const;
1588 
1589  const void* blackpixel() const;
1590 
1591  // Given x,y,z known to be outside the pixel data range, and a wrap
1592  // mode, alter xyz to implement the wrap. Return true if the resulting
1593  // x,y,z is within the valid pixel data window, false if it still is
1594  // not.
1595  bool do_wrap(int& x, int& y, int& z, WrapMode wrap) const;
1596 };
1597 
1598 
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
OIIO_API std::string geterror(bool clear=true)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
OIIO_API bool has_error()
Is there a pending global error message waiting to be retrieved?
int64_t stride_t
Definition: imageio.h:48
GT_API const UT_StringHolder filename
void swap(ImageBuf &other)
Swap the entire contents with another ImageBuf.
Definition: imagebuf.h:652
uint32_t deep_value_uint(int c, int s) const
Definition: imagebuf.h:1329
void setpixel(int i, cspan< float > pixel)
Definition: imagebuf.h:765
ConstIterator(const ImageBuf &ib, const ROI &roi, WrapMode wrap=WrapDefault)
Construct read-only iteration region from ImageBuf and ROI.
Definition: imagebuf.h:1537
void
Definition: png.h:1083
void getpixel(int x, int y, float *pixel, int maxchannels=1000) const
Definition: imagebuf.h:695
OIIO_API void set_roi(ImageSpec &spec, const ROI &newroi)
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1699
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
OIIO_FORMAT_DEPRECATED void error(const char *fmt, const Args &...args) const
Definition: imagebuf.h:1092
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
Definition: span.h:74
Iterator(ImageBuf &ib, const ROI &roi, WrapMode wrap=WrapDefault)
Construct read-write iteration region from ImageBuf and ROI.
Definition: imagebuf.h:1448
USERT operator[](int i) const
Definition: imagebuf.h:1562
int x() const
Retrieve the current x location of the iterator.
Definition: imagebuf.h:1228
OIIO_NODISCARD std::string format(const Str &fmt, Args &&...args)
Definition: strutil.h:128
DataArrayProxy< BUFT, USERT > & operator*()
Definition: imagebuf.h:1471
unknown type
Definition: typedesc.h:57
GLdouble s
Definition: glad.h:3009
bool valid(int x_, int y_, int z_=0) const
Definition: imagebuf.h:1239
ROI range() const
Return the iteration range.
Definition: imagebuf.h:1308
void set_deep_value(int c, int s, float value)
Definition: imagebuf.h:1505
std::unique_ptr< ImageBufImpl, decltype(&impl_deleter)> m_impl
Definition: imagebuf.h:1573
#define OIIO_DEPRECATED(msg)
Definition: platform.h:466
GLint y
Definition: glcorearb.h:103
Tto convert(const Tfrom &source)
**But if you need a result
Definition: thread.h:622
OIIO_API ROI get_roi(const ImageSpec &spec)
Return pixel data window for this ImageSpec as a ROI.
ConstIterator(const ImageBuf &ib, int x_, int y_, int z_=0, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1531
GLuint buffer
Definition: glcorearb.h:660
void setpixel(int x, int y, const float *pixel, int maxchannels=1000)
Definition: imagebuf.h:773
OutGridT const XformOp bool bool
basic_string_view< char > string_view
Definition: core.h:501
< returns > If no error
Definition: snippets.dox:2
OIIO_INLINE_CONSTEXPR TypeDesc TypeUnknown(TypeDesc::UNKNOWN)
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLdouble n
Definition: glcorearb.h:2008
void setpixel(int x, int y, cspan< float > pixel)
Definition: imagebuf.h:748
const void * rawptr() const
Definition: imagebuf.h:1321
OIIO_API ROI get_roi_full(const ImageSpec &spec)
Return full/display window for this ImageSpec as a ROI.
bool(* ProgressCallback)(void *opaque_data, float portion_done)
Definition: imageio.h:65
GLboolean reset
Definition: glad.h:5138
int z() const
Retrieve the current z location of the iterator.
Definition: imagebuf.h:1232
Iterator(Iterator &i)
Definition: imagebuf.h:1462
#define OIIO_DASSERT
Definition: dassert.h:55
void errorf(const char *fmt, const Args &...args) const
Definition: imagebuf.h:1082
void reset()
Definition: imagebuf.h:270
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
float deep_value(int c, int s) const
Retrieve the deep data value of sample s of channel c.
Definition: imagebuf.h:1324
bool valid() const
Is the current location within the designated iteration range?
Definition: imagebuf.h:1235
constexpr size_type size() const noexcept
Definition: span.h:186
OIIO_UTIL_API bool exists(string_view path) noexcept
GLuint const GLchar * name
Definition: glcorearb.h:786
int y() const
Retrieve the current y location of the iterator.
Definition: imagebuf.h:1230
ConstDataArrayProxy< BUFT, USERT > & operator*() const
Definition: imagebuf.h:1555
GLint GLenum GLint x
Definition: glcorearb.h:409
Iterator(ImageBuf &ib, int x, int y, int z=0, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1442
GA_API const UT_StringHolder orient
void operator++(int)
Increment to the next pixel in the region.
Definition: imagebuf.h:1305
void errorfmt(const char *fmt, const Args &...args) const
Definition: imagebuf.h:1073
GLdouble t
Definition: glad.h:2397
void set_deep_value(int c, int s, uint32_t value)
Definition: imagebuf.h:1510
bool has_error() const
Definition: imagebuf.h:1337
Iterator(ImageBuf &ib, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1436
ConstIterator(const ImageBuf &ib, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1525
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:476
bool exists(int x_, int y_, int z_=0) const
Definition: imagebuf.h:1248
Definition: imageio.h:85
#define OIIO_UNLIKELY(x)
Definition: platform.h:388
SIM_API const UT_StringHolder force
const stride_t AutoStride
Definition: imageio.h:56
int deep_samples() const
Retrieve the number of deep data samples at this pixel.
Definition: imagebuf.h:1270
USERT operator[](int i) const
Definition: imagebuf.h:1478
LeafData & operator=(const LeafData &)=delete
ConstIterator(const ImageBuf &ib, int xbegin, int xend, int ybegin, int yend, int zbegin=0, int zend=1, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1544
Iterator(ImageBuf &ib, int xbegin, int xend, int ybegin, int yend, int zbegin=0, int zend=1, WrapMode wrap=WrapDefault)
Definition: imagebuf.h:1454
**If you just want to fire and args
Definition: thread.h:618
GLint GLsizei width
Definition: glcorearb.h:103
#define OIIO_FORMAT_DEPRECATED
Definition: strutil.h:50
bool done() const
Are we finished iterating over the region?
Definition: imagebuf.h:1259
void set_deep_samples(int n)
Definition: imagebuf.h:1497
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
auto sprintf(const S &fmt, const T &...args) -> std::basic_string< Char >
Definition: printf.h:617
WrapMode wrap() const
Return the wrap mode.
Definition: imagebuf.h:1273
InitializePixels
Definition: imagebuf.h:54
void * rawptr() const
Definition: imagebuf.h:1493
constexpr pointer data() const noexcept
Definition: span.h:190
DataProxy< BUFT, USERT > operator[](int i)
Definition: imagebuf.h:1487
Definition: format.h:1821
OIIO_API void set_roi_full(ImageSpec &spec, const ROI &newroi)
bool exists() const
Definition: imagebuf.h:1256
void setpixel(int x, int y, int z, cspan< float > pixel)
Definition: imagebuf.h:756
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126
#define OIIO_API
Definition: export.h:65
GLenum src
Definition: glcorearb.h:1793
bool localpixels() const
Definition: imagebuf.h:1334