HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
texture.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 // clang-format off
6 
7 /// \file
8 /// An API for accessing filtered texture lookups via a system that
9 /// automatically manages a cache of resident texture.
10 
11 #pragma once
12 
13 #include <OpenImageIO/imageio.h>
14 #include <OpenImageIO/simd.h>
15 #include <OpenImageIO/ustring.h>
16 #include <OpenImageIO/varyingref.h>
17 #include <OpenImageIO/vecparam.h>
18 
19 
20 // Define symbols that let client applications determine if newly added
21 // features are supported.
22 #define OIIO_TEXTURESYSTEM_SUPPORTS_CLOSE 1
23 #define OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE 1
24 
25 // Is the getattributetype() method present? (Added in 2.5)
26 #define OIIO_TEXTURESYSTEM_SUPPORTS_GETATTRIBUTETYPE 1
27 
28 #define OIIO_TEXTURESYSTEM_SUPPORTS_STOCHASTIC 1
29 #define OIIO_TEXTURESYSTEM_SUPPORTS_DECODE_BY_USTRINGHASH 1
30 
31 #ifndef INCLUDED_IMATHVEC_H
32 // Placeholder declaration for Imath::V3f if no Imath headers have been
33 // included.
34 namespace Imath {
35 template <class T> class Vec3;
36 using V3f = Vec3<float>;
37 }
38 #endif
39 
40 
42 
43 // Forward declarations
44 
45 class ImageCache;
46 
47 
48 namespace pvt {
49 
50 class TextureSystemImpl;
51 
52 // Used internally by TextureSystem. Unfortunately, this is the only
53 // clean place to store it. Sorry, users, this isn't really for you.
54 enum TexFormat {
64 };
65 
66 enum EnvLayout {
67  LayoutTexture = 0 /* ordinary texture - no special env wrap */,
72 };
73 
74 } // namespace pvt
75 
76 
77 
78 namespace Tex {
79 
80 /// Wrap mode describes what happens when texture coordinates describe
81 /// a value outside the usual [0,1] range where a texture is defined.
82 enum class Wrap {
83  Default, ///< Use the default found in the file
84  Black, ///< Black outside [0..1]
85  Clamp, ///< Clamp to [0..1]
86  Periodic, ///< Periodic mod 1
87  Mirror, ///< Mirror the image
88  PeriodicPow2, ///< Periodic, but only for powers of 2!!!
89  PeriodicSharedBorder, ///< Periodic with shared border (env)
90  Last ///< Mark the end -- don't use this!
91 };
92 
93 /// Utility: Return the Wrap enum corresponding to a wrap name:
94 /// "default", "black", "clamp", "periodic", "mirror".
95 OIIO_API Wrap decode_wrapmode (const char *name);
98 
99 /// Utility: Parse a single wrap mode (e.g., "periodic") or a
100 /// comma-separated wrap modes string (e.g., "black,clamp") into
101 /// separate Wrap enums for s and t.
102 OIIO_API void parse_wrapmodes (const char *wrapmodes,
103  Wrap &swrapcode, Wrap &twrapcode);
104 
105 
106 /// Mip mode determines if/how we use mipmaps
107 ///
108 enum class MipMode {
109  Default, ///< Default high-quality lookup
110  NoMIP, ///< Just use highest-res image, no MIP mapping
111  OneLevel, ///< Use just one mipmap level
112  Trilinear, ///< Use two MIPmap levels (trilinear)
113  Aniso, ///< Use two MIPmap levels w/ anisotropic
114  StochasticTrilinear, ///< DEPRECATED Stochastic trilinear
115  StochasticAniso, ///< DEPRECATED Stochastic anisotropic
116 };
117 
118 /// Interp mode determines how we sample within a mipmap level
119 ///
120 enum class InterpMode {
121  Closest, ///< Force closest texel
122  Bilinear, ///< Force bilinear lookup within a mip level
123  Bicubic, ///< Force cubic lookup within a mip level
124  SmartBicubic ///< Bicubic when magnifying, else bilinear
125 };
126 
127 
128 /// Fixed width for SIMD batching texture lookups.
129 /// May be changed for experimentation or future expansion.
130 #ifndef OIIO_TEXTURE_SIMD_BATCH_WIDTH
131 # define OIIO_TEXTURE_SIMD_BATCH_WIDTH 16
132 #endif
133 
134 /// The SIMD width for batched texturing operations. This is fixed within
135 /// any release of OpenImageIO, but may change from release to release and
136 /// also may be overridden at build time. A typical batch size is 16.
137 OIIO_INLINE_CONSTEXPR int BatchWidth = OIIO_TEXTURE_SIMD_BATCH_WIDTH;
138 OIIO_INLINE_CONSTEXPR int BatchAlign = BatchWidth * sizeof(float);
139 
140 /// A type alias for a SIMD vector of floats with the batch width.
142 
143 /// A type alias for a SIMD vector of ints with the batch width.
145 
146 /// `RunMask` is defined to be an integer large enough to hold at least
147 /// `BatchWidth` bits. The least significant bit corresponds to the first
148 /// (i.e., `[0]`) position of all batch arrays. For each position `i` in the
149 /// batch, the bit identified by `(1 << i)` controls whether that position
150 /// will be computed.
151 typedef uint64_t RunMask;
152 
153 
154 // The defined constant `RunMaskOn` contains the value with all bits
155 // `0..BatchWidth-1` set to 1.
156 #if OIIO_TEXTURE_SIMD_BATCH_WIDTH == 4
157 OIIO_INLINE_CONSTEXPR RunMask RunMaskOn = 0xf;
158 #elif OIIO_TEXTURE_SIMD_BATCH_WIDTH == 8
159 OIIO_INLINE_CONSTEXPR RunMask RunMaskOn = 0xff;
160 #elif OIIO_TEXTURE_SIMD_BATCH_WIDTH == 16
161 OIIO_INLINE_CONSTEXPR RunMask RunMaskOn = 0xffff;
162 #elif OIIO_TEXTURE_SIMD_BATCH_WIDTH == 32
163 OIIO_INLINE_CONSTEXPR RunMask RunMaskOn = 0xffffffff;
164 #elif OIIO_TEXTURE_SIMD_BATCH_WIDTH == 64
165 OIIO_INLINE_CONSTEXPR RunMask RunMaskOn = 0xffffffffffffffffULL;
166 #else
167 # error "Not a valid OIIO_TEXTURE_SIMD_BATCH_WIDTH choice"
168 #endif
169 
170 } // namespace Tex
171 
172 
173 /// Data type for flags that indicate on a point-by-point basis whether
174 /// we want computations to be performed.
175 typedef unsigned char Runflag;
176 
177 /// Pre-defined values for Runflag's.
178 ///
179 enum RunFlagVal { RunFlagOff = 0, RunFlagOn = 255 };
180 
181 class TextureOptions; // forward declaration
182 
183 
184 
185 /// TextureOpt is a structure that holds many options controlling
186 /// single-point texture lookups. Because each texture lookup API call
187 /// takes a reference to a TextureOpt, the call signatures remain
188 /// uncluttered rather than having an ever-growing list of parameters, most
189 /// of which will never vary from their defaults.
191 public:
192  /// Wrap mode describes what happens when texture coordinates describe
193  /// a value outside the usual [0,1] range where a texture is defined.
194  enum Wrap {
195  WrapDefault, ///< Use the default found in the file
196  WrapBlack, ///< Black outside [0..1]
197  WrapClamp, ///< Clamp to [0..1]
198  WrapPeriodic, ///< Periodic mod 1
199  WrapMirror, ///< Mirror the image
200  WrapPeriodicPow2, // Periodic, but only for powers of 2!!!
201  WrapPeriodicSharedBorder, // Periodic with shared border (env)
202  WrapLast // Mark the end -- don't use this!
203  };
204 
205  /// Mip mode determines if/how we use mipmaps
206  ///
207  enum MipMode {
208  MipModeDefault, ///< Default high-quality lookup
209  MipModeNoMIP, ///< Just use highest-res image, no MIP mapping
210  MipModeOneLevel, ///< Use just one mipmap level
211  MipModeTrilinear, ///< Use two MIPmap levels (trilinear)
212  MipModeAniso, ///< Use two MIPmap levels w/ anisotropic
213  MipModeStochasticTrilinear, ///< DEPRECATED Stochastic trilinear
214  MipModeStochasticAniso, ///< DEPRECATED Stochastic anisotropic
215  };
216 
217  /// Interp mode determines how we sample within a mipmap level
218  ///
219  enum InterpMode {
220  InterpClosest, ///< Force closest texel
221  InterpBilinear, ///< Force bilinear lookup within a mip level
222  InterpBicubic, ///< Force cubic lookup within a mip level
223  InterpSmartBicubic ///< Bicubic when magnifying, else bilinear
224  };
225 
226 
227  /// Create a TextureOpt with all fields initialized to reasonable
228  /// defaults.
230  : firstchannel(0), subimage(0),
231  swrap(WrapDefault), twrap(WrapDefault),
232  mipmode(MipModeDefault), interpmode(InterpSmartBicubic),
233  anisotropic(32), conservative_filter(true),
234  sblur(0.0f), tblur(0.0f), swidth(1.0f), twidth(1.0f),
235  fill(0.0f), missingcolor(nullptr),
236  time(0.0f), rnd(-1.0f), samples(1),
237  rwrap(WrapDefault), rblur(0.0f), rwidth(1.0f),
238  colortransformid(0),
239  envlayout(0)
240  { }
241 
242  /// Convert a TextureOptions for one index into a TextureOpt.
243  ///
244  TextureOpt(const TextureOptions& opt, int index);
245 
246  int firstchannel; ///< First channel of the lookup
247  int subimage; ///< Subimage or face ID
248  ustring subimagename; ///< Subimage name
249  Wrap swrap; ///< Wrap mode in the s direction
250  Wrap twrap; ///< Wrap mode in the t direction
251  MipMode mipmode; ///< Mip mode
252  InterpMode interpmode; ///< Interpolation mode
253  int anisotropic; ///< Maximum anisotropic ratio
254  bool conservative_filter; ///< True == over-blur rather than alias
255  float sblur, tblur; ///< Blur amount
256  float swidth, twidth; ///< Multiplier for derivatives
257  float fill; ///< Fill value for missing channels
258  const float* missingcolor; ///< Color for missing texture
259  float time; ///< Time (for time-dependent texture lookups)
260  union {
261  float bias; ///< Bias for shadows (DEPRECATED)
262  float rnd; ///< Stratified sample value
263  };
264  int samples; ///< Number of samples for shadows
265 
266  // For 3D volume texture lookups only:
267  Wrap rwrap; ///< Wrap mode in the r direction
268  float rblur; ///< Blur amount in the r direction
269  float rwidth; ///< Multiplier for derivatives in r direction
270 
271  int colortransformid; ///< Color space id of the texture
272 
273  /// Utility: Return the Wrap enum corresponding to a wrap name:
274  /// "default", "black", "clamp", "periodic", "mirror".
275  static Wrap decode_wrapmode(const char* name)
276  {
277  return (Wrap)Tex::decode_wrapmode(name);
278  }
280  {
281  return (Wrap)Tex::decode_wrapmode(name);
282  }
284  {
285  return (Wrap)Tex::decode_wrapmode(name);
286  }
287 
288  /// Utility: Parse a single wrap mode (e.g., "periodic") or a
289  /// comma-separated wrap modes string (e.g., "black,clamp") into
290  /// separate Wrap enums for s and t.
291  static void parse_wrapmodes(const char* wrapmodes,
292  TextureOpt::Wrap& swrapcode,
293  TextureOpt::Wrap& twrapcode)
294  {
295  Tex::parse_wrapmodes(wrapmodes, *(Tex::Wrap*)&swrapcode,
296  *(Tex::Wrap*)&twrapcode);
297  }
298 
299 private:
300  // Options set INTERNALLY by libtexture after the options are passed
301  // by the user. Users should not attempt to alter these!
302  int envlayout; // Layout for environment wrap
303  friend class pvt::TextureSystemImpl;
304 };
305 
306 
307 
308 /// Texture options for a batch of Tex::BatchWidth points and run mask.
310 public:
311  /// Create a TextureOptBatch with all fields initialized to reasonable
312  /// defaults.
314  for (int i = 0; i < Tex::BatchWidth; ++i)
315  rnd[i] = -1.0f;
316  }
317 
318  // Options that may be different for each point we're texturing
319  alignas(Tex::BatchAlign) float sblur[Tex::BatchWidth]; ///< Blur amount
320  alignas(Tex::BatchAlign) float tblur[Tex::BatchWidth];
321  alignas(Tex::BatchAlign) float rblur[Tex::BatchWidth];
322  alignas(Tex::BatchAlign) float swidth[Tex::BatchWidth]; ///< Multiplier for derivatives
323  alignas(Tex::BatchAlign) float twidth[Tex::BatchWidth];
324  alignas(Tex::BatchAlign) float rwidth[Tex::BatchWidth];
325  // Note: rblur,rwidth only used for volumetric lookups
326  alignas(Tex::BatchAlign) float rnd[Tex::BatchWidth];
327 
328  // Options that must be the same for all points we're texturing at once
329  int firstchannel = 0; ///< First channel of the lookup
330  int subimage = 0; ///< Subimage or face ID
331  ustring subimagename; ///< Subimage name
332  Tex::Wrap swrap = Tex::Wrap::Default; ///< Wrap mode in the s direction
333  Tex::Wrap twrap = Tex::Wrap::Default; ///< Wrap mode in the t direction
334  Tex::Wrap rwrap = Tex::Wrap::Default; ///< Wrap mode in the r direction (volumetric)
335  Tex::MipMode mipmode = Tex::MipMode::Default; ///< Mip mode
336  Tex::InterpMode interpmode = Tex::InterpMode::SmartBicubic; ///< Interpolation mode
337  int anisotropic = 32; ///< Maximum anisotropic ratio
338  int conservative_filter = 1; ///< True: over-blur rather than alias
339  float fill = 0.0f; ///< Fill value for missing channels
340  const float *missingcolor = nullptr; ///< Color for missing texture
341  int colortransformid = 0; ///< Color space id of the texture
342 
343 private:
344  // Options set INTERNALLY by libtexture after the options are passed
345  // by the user. Users should not attempt to alter these!
346  int envlayout = 0; // Layout for environment wrap
347 
348  friend class pvt::TextureSystemImpl;
349 };
350 
351 
352 
353 // DEPRECATED(1.8)
354 // Encapsulate all the options needed for texture lookups. Making
355 // these options all separate parameters to the texture API routines is
356 // very ugly and also a big pain whenever we think of new options to
357 // add. So instead we collect all those little options into one
358 // structure that can just be passed by reference to the texture API
359 // routines.
361 public:
362  /// Wrap mode describes what happens when texture coordinates describe
363  /// a value outside the usual [0,1] range where a texture is defined.
364  enum Wrap {
365  WrapDefault, ///< Use the default found in the file
366  WrapBlack, ///< Black outside [0..1]
367  WrapClamp, ///< Clamp to [0..1]
368  WrapPeriodic, ///< Periodic mod 1
369  WrapMirror, ///< Mirror the image
370  WrapPeriodicPow2, ///< Periodic, but only for powers of 2!!!
371  WrapPeriodicSharedBorder, ///< Periodic with shared border (env)
372  WrapLast ///< Mark the end -- don't use this!
373  };
374 
375  /// Mip mode determines if/how we use mipmaps
376  ///
377  enum MipMode {
378  MipModeDefault, ///< Default high-quality lookup
379  MipModeNoMIP, ///< Just use highest-res image, no MIP mapping
380  MipModeOneLevel, ///< Use just one mipmap level
381  MipModeTrilinear, ///< Use two MIPmap levels (trilinear)
382  MipModeAniso ///< Use two MIPmap levels w/ anisotropic
383  };
384 
385  /// Interp mode determines how we sample within a mipmap level
386  ///
387  enum InterpMode {
388  InterpClosest, ///< Force closest texel
389  InterpBilinear, ///< Force bilinear lookup within a mip level
390  InterpBicubic, ///< Force cubic lookup within a mip level
391  InterpSmartBicubic ///< Bicubic when magnifying, else bilinear
392  };
393 
394  /// Create a TextureOptions with all fields initialized to reasonable
395  /// defaults.
396  OIIO_DEPRECATED("no longer used since OIIO 1.8")
397  TextureOptions();
398 
399  /// Convert a TextureOpt for one point into a TextureOptions with
400  /// uniform values.
401  OIIO_DEPRECATED("no longer used since OIIO 1.8")
402  TextureOptions(const TextureOpt& opt);
403 
404  // Options that must be the same for all points we're texturing at once
405  int firstchannel; ///< First channel of the lookup
406  int subimage; ///< Subimage or face ID
407  ustring subimagename; ///< Subimage name
408  Wrap swrap; ///< Wrap mode in the s direction
409  Wrap twrap; ///< Wrap mode in the t direction
410  MipMode mipmode; ///< Mip mode
411  InterpMode interpmode; ///< Interpolation mode
412  int anisotropic; ///< Maximum anisotropic ratio
413  bool conservative_filter; ///< True == over-blur rather than alias
414 
415  // Options that may be different for each point we're texturing
416  VaryingRef<float> sblur, tblur; ///< Blur amount
417  VaryingRef<float> swidth, twidth; ///< Multiplier for derivatives
418  VaryingRef<float> time; ///< Time
419  VaryingRef<float> bias; ///< Bias
420  VaryingRef<float> fill; ///< Fill value for missing channels
421  VaryingRef<float> missingcolor; ///< Color for missing texture
422  VaryingRef<int> samples; ///< Number of samples
423 
424  // For 3D volume texture lookups only:
425  Wrap rwrap; ///< Wrap mode in the r direction
426  VaryingRef<float> rblur; ///< Blur amount in the r direction
427  VaryingRef<float> rwidth; ///< Multiplier for derivatives in r direction
428 
429  /// Utility: Return the Wrap enum corresponding to a wrap name:
430  /// "default", "black", "clamp", "periodic", "mirror".
431  static Wrap decode_wrapmode(const char* name)
432  {
433  return (Wrap)Tex::decode_wrapmode(name);
434  }
436  {
437  return (Wrap)Tex::decode_wrapmode(name);
438  }
440  {
441  return (Wrap)Tex::decode_wrapmode(name);
442  }
443 
444  /// Utility: Parse a single wrap mode (e.g., "periodic") or a
445  /// comma-separated wrap modes string (e.g., "black,clamp") into
446  /// separate Wrap enums for s and t.
447  static void parse_wrapmodes(const char* wrapmodes,
448  TextureOptions::Wrap& swrapcode,
449  TextureOptions::Wrap& twrapcode)
450  {
451  Tex::parse_wrapmodes(wrapmodes, *(Tex::Wrap*)&swrapcode,
452  *(Tex::Wrap*)&twrapcode);
453  }
454 
455 private:
456  // Options set INTERNALLY by libtexture after the options are passed
457  // by the user. Users should not attempt to alter these!
458  friend class pvt::TextureSystemImpl;
459  friend class TextureOpt;
460 };
461 
462 
463 
464 
465 /// Define an API to an abstract class that that manages texture files,
466 /// caches of open file handles as well as tiles of texels so that truly
467 /// huge amounts of texture may be accessed by an application with low
468 /// memory footprint, and ways to perform antialiased texture, shadow
469 /// map, and environment map lookups.
471 public:
472  /// @{
473  /// @name Creating and destroying a texture system
474  ///
475  /// TextureSystem is an abstract API described as a pure virtual class.
476  /// The actual internal implementation is not exposed through the
477  /// external API of OpenImageIO. Because of this, you cannot construct
478  /// or destroy the concrete implementation, so two static methods of
479  /// TextureSystem are provided:
480 
481  /// Create a TextureSystem and return a pointer to it. This should only
482  /// be freed by passing it to TextureSystem::destroy()!
483  ///
484  /// @param shared
485  /// If `shared` is `true`, the pointer returned will be a shared
486  /// TextureSystem, (so that multiple parts of an application that
487  /// request a TextureSystem will all end up with the same one, and
488  /// the same underlying ImageCache). If `shared` is `false`, a
489  /// completely unique TextureCache will be created and returned.
490  ///
491  /// @param imagecache
492  /// If `shared` is `false` and `imagecache` is not `nullptr`, the
493  /// TextureSystem will use this as its underlying ImageCache. In
494  /// that case, it is the caller who is responsible for eventually
495  /// freeing the ImageCache after the TextureSystem is destroyed. If
496  /// `shared` is `false` and `imagecache` is `nullptr`, then a custom
497  /// ImageCache will be created, owned by the TextureSystem, and
498  /// automatically freed when the TS destroys. If `shared` is true,
499  /// this parameter will not be used, since the global shared
500  /// TextureSystem uses the global shared ImageCache.
501  ///
502  /// @returns
503  /// A raw pointer to a TextureSystem, which can only be freed with
504  /// `TextureSystem::destroy()`.
505  ///
506  /// @see TextureSystem::destroy
507  static TextureSystem *create (bool shared=true,
508  ImageCache *imagecache=nullptr);
509 
510  /// Destroy an allocated TextureSystem, including freeing all system
511  /// resources that it holds.
512  ///
513  /// It is safe to destroy even a shared TextureSystem, as the
514  /// implementation of `destroy()` will recognize a shared one and only
515  /// truly release its resources if it has been requested to be destroyed
516  /// as many times as shared TextureSystem's were created.
517  ///
518  /// @param ts
519  /// Raw pointer to the TextureSystem to destroy.
520  ///
521  /// @param teardown_imagecache
522  /// For a shared TextureSystem, if the `teardown_imagecache`
523  /// parameter is `true`, it will try to truly destroy the shared
524  /// cache if nobody else is still holding a reference (otherwise, it
525  /// will leave it intact). This parameter has no effect if `ts` was
526  /// not the single globally shared TextureSystem.
527  static void destroy (TextureSystem *ts,
528  bool teardown_imagecache = false);
529 
530  /// @}
531 
532 
533  /// @{
534  /// @name Setting options and limits for the texture system
535  ///
536  /// These are the list of attributes that can bet set or queried by
537  /// attribute/getattribute:
538  ///
539  /// All attributes ordinarily recognized by ImageCache are accepted and
540  /// passed through to the underlying ImageCache. These include:
541  /// - `int max_open_files` :
542  /// Maximum number of file handles held open.
543  /// - `float max_memory_MB` :
544  /// Maximum tile cache size, in MB.
545  /// - `string searchpath` :
546  /// Colon-separated search path for texture files.
547  /// - `string plugin_searchpath` :
548  /// Colon-separated search path for plugins.
549  /// - `int autotile` :
550  /// If >0, tile size to emulate for non-tiled images.
551  /// - `int autoscanline` :
552  /// If nonzero, autotile using full width tiles.
553  /// - `int automip` :
554  /// If nonzero, emulate mipmap on the fly.
555  /// - `int accept_untiled` :
556  /// If nonzero, accept untiled images.
557  /// - `int accept_unmipped` :
558  /// If nonzero, accept unmipped images.
559  /// - `int failure_retries` :
560  /// How many times to retry a read failure.
561  /// - `int deduplicate` :
562  /// If nonzero, detect duplicate textures (default=1).
563  /// - `int max_open_files_strict` :
564  /// If nonzero, work harder to make sure that we have
565  /// smaller possible overages to the max open files limit.
566  /// - `string substitute_image` :
567  /// If supplied, an image to substatute for all texture
568  /// references.
569  /// - `int max_errors_per_file` :
570  /// Limits how many errors to issue for each file. (default:
571  /// 100)
572  /// - `string colorspace` :
573  /// The working colorspace of the texture system.
574  /// - `string colorconfig` :
575  /// Name of the OCIO config to use (default: "").
576  ///
577  /// Texture-specific settings:
578  /// - `matrix44 worldtocommon` / `matrix44 commontoworld` :
579  /// The 4x4 matrices that provide the spatial transformation
580  /// from "world" to a "common" coordinate system and back.
581  /// This is mainly used for shadow map lookups, in which the
582  /// shadow map itself encodes the world coordinate system,
583  /// but positions passed to `shadow()` are expressed in
584  /// "common" coordinates. You do not need to set
585  /// `commontoworld` and `worldtocommon` separately; just
586  /// setting either one will implicitly set the other, since
587  /// each is the inverse of the other.
588  /// - `int gray_to_rgb` :
589  /// If set to nonzero, texture lookups of single-channel
590  /// (grayscale) images will replicate the sole channel's
591  /// values into the next two channels, making it behave like
592  /// an RGB image that happens to have all three channels
593  /// with identical pixel values. (Channels beyond the third
594  /// will get the "fill" value.) The default value of zero
595  /// means that all missing channels will get the "fill"
596  /// color.
597  /// - `int max_tile_channels` :
598  /// The maximum number of color channels in a texture file
599  /// for which all channels will be loaded as a single cached
600  /// tile. Files with more than this number of color channels
601  /// will have only the requested subset loaded, in order to
602  /// save cache space (but at the possible wasted expense of
603  /// separate tiles that overlap their channel ranges). The
604  /// default is 5.
605  /// - `int max_mip_res` :
606  /// **NEW 2.1** Sets the maximum MIP-map resolution for
607  /// filtered texture lookups. The MIP levels used will be
608  /// clamped to those having fewer than this number of pixels
609  /// in each dimension. This can be helpful as a way to limit
610  /// disk I/O when doing fast preview renders (with the
611  /// tradeoff that you may see some texture more blurry than
612  /// they would ideally be). The default is `1 << 30`, a
613  /// value so large that no such clamping will be performed.
614  /// - `string latlong_up` :
615  /// The default "up" direction for latlong environment maps
616  /// (only applies if the map itself doesn't specify a format
617  /// or is in a format that explicitly requires a particular
618  /// orientation). The default is `"y"`. (Currently any
619  /// other value will result in *z* being "up.")
620  /// - `int flip_t` :
621  /// If nonzero, `t` coordinates will be flipped `1-t` for
622  /// all texture lookups. The default is 0.
623  /// - `int stochastic` :
624  /// Bit field determining how to use stochastic sampling for
625  /// MipModeStochasticAniso and/or MipModeStochasticTrilinear.
626  /// Bit 1 = sample MIP level, bit 2 = sample anisotropy
627  /// (default=0).
628  ///
629  /// - `string options`
630  /// This catch-all is simply a comma-separated list of
631  /// `name=value` settings of named options, which will be
632  /// parsed and individually set.
633  ///
634  /// ic->attribute ("options", "max_memory_MB=512.0,autotile=1");
635  ///
636  /// Note that if an option takes a string value that must
637  /// itself contain a comma, it is permissible to enclose the
638  /// value in either single `\'` or double `"` quotes.
639  ///
640  /// **Read-only attributes**
641  ///
642  /// Additionally, there are some read-only attributes that can be
643  /// queried with `getattribute()` even though they cannot be set via
644  /// `attribute()`:
645  ///
646  ///
647  /// The following member functions of TextureSystem allow you to set
648  /// (and in some cases retrieve) options that control the overall
649  /// behavior of the texture system:
650 
651  /// Set a named attribute (i.e., a property or option) of the
652  /// TextureSystem.
653  ///
654  /// Example:
655  ///
656  /// TextureSystem *ts;
657  /// ...
658  /// int maxfiles = 50;
659  /// ts->attribute ("max_open_files", TypeDesc::INT, &maxfiles);
660  ///
661  /// const char *path = "/my/path";
662  /// ts->attribute ("searchpath", TypeDesc::STRING, &path);
663  ///
664  /// // There are specialized versions for retrieving a single int,
665  /// // float, or string without needing types or pointers:
666  /// ts->getattribute ("max_open_files", 50);
667  /// ic->attribute ("max_memory_MB", 4000.0f);
668  /// ic->attribute ("searchpath", "/my/path");
669  ///
670  /// Note: When passing a string, you need to pass a pointer to the
671  /// `char*`, not a pointer to the first character. (Rationale: for an
672  /// `int` attribute, you pass the address of the `int`. So for a
673  /// string, which is a `char*`, you need to pass the address of the
674  /// string, i.e., a `char**`).
675  ///
676  /// @param name Name of the attribute to set.
677  /// @param type TypeDesc describing the type of the attribute.
678  /// @param val Pointer to the value data.
679  /// @returns `true` if the name and type were recognized and the
680  /// attribute was set, or `false` upon failure
681  /// (including it being an unrecognized attribute or not
682  /// of the correct type).
683  ///
684  virtual bool attribute (string_view name, TypeDesc type, const void *val) = 0;
685 
686  /// Specialized `attribute()` for setting a single `int` value.
687  virtual bool attribute (string_view name, int val) = 0;
688  /// Specialized `attribute()` for setting a single `float` value.
689  virtual bool attribute (string_view name, float val) = 0;
690  virtual bool attribute (string_view name, double val) = 0;
691  /// Specialized `attribute()` for setting a single string value.
692  virtual bool attribute (string_view name, string_view val) = 0;
693 
694  /// Get the named attribute of the texture system, store it in `*val`.
695  /// All of the attributes that may be set with the `attribute() call`
696  /// may also be queried with `getattribute()`.
697  ///
698  /// Examples:
699  ///
700  /// TextureSystem *ic;
701  /// ...
702  /// int maxfiles;
703  /// ts->getattribute ("max_open_files", TypeDesc::INT, &maxfiles);
704  ///
705  /// const char *path;
706  /// ts->getattribute ("searchpath", TypeDesc::STRING, &path);
707  ///
708  /// // There are specialized versions for retrieving a single int,
709  /// // float, or string without needing types or pointers:
710  /// int maxfiles;
711  /// ts->getattribute ("max_open_files", maxfiles);
712  /// const char *path;
713  /// ts->getattribute ("searchpath", &path);
714  ///
715  /// Note: When retrieving a string, you need to pass a pointer to the
716  /// `char*`, not a pointer to the first character. Also, the `char*`
717  /// will end up pointing to characters owned by the ImageCache; the
718  /// caller does not need to ever free the memory that contains the
719  /// characters.
720  ///
721  /// @param name Name of the attribute to retrieve.
722  /// @param type TypeDesc describing the type of the attribute.
723  /// @param val Pointer where the attribute value should be stored.
724  /// @returns `true` if the name and type were recognized and the
725  /// attribute was retrieved, or `false` upon failure
726  /// (including it being an unrecognized attribute or not
727  /// of the correct type).
728  virtual bool getattribute (string_view name,
729  TypeDesc type, void *val) const = 0;
730 
731  /// Specialized `attribute()` for retrieving a single `int` value.
732  virtual bool getattribute(string_view name, int& val) const = 0;
733  /// Specialized `attribute()` for retrieving a single `float` value.
734  virtual bool getattribute(string_view name, float& val) const = 0;
735  virtual bool getattribute(string_view name, double& val) const = 0;
736  /// Specialized `attribute()` for retrieving a single `string` value
737  /// as a `char*`.
738  virtual bool getattribute(string_view name, char** val) const = 0;
739  /// Specialized `attribute()` for retrieving a single `string` value
740  /// as a `std::string`.
741  virtual bool getattribute(string_view name, std::string& val) const = 0;
742 
743  /// If the named attribute is known, return its data type. If no such
744  /// attribute exists, return `TypeUnknown`.
745  ///
746  /// This was added in version 2.5.
747  virtual TypeDesc getattributetype (string_view name) const = 0;
748 
749  /// @}
750 
751  /// @{
752  /// @name Opaque data for performance lookups
753  ///
754  /// The TextureSystem implementation needs to maintain certain
755  /// per-thread state, and some methods take an opaque `Perthread`
756  /// pointer to this record. There are three options for how to deal with
757  /// it:
758  ///
759  /// 1. Don't worry about it at all: don't use the methods that want
760  /// `Perthread` pointers, or always pass `nullptr` for any
761  /// `Perthread*1 arguments, and ImageCache will do
762  /// thread-specific-pointer retrieval as necessary (though at some
763  /// small cost).
764  ///
765  /// 2. If your app already stores per-thread information of its own, you
766  /// may call `get_perthread_info(nullptr)` to retrieve it for that
767  /// thread, and then pass it into the functions that allow it (thus
768  /// sparing them the need and expense of retrieving the
769  /// thread-specific pointer). However, it is crucial that this
770  /// pointer not be shared between multiple threads. In this case, the
771  /// ImageCache manages the storage, which will automatically be
772  /// released when the thread terminates.
773  ///
774  /// 3. If your app also wants to manage the storage of the `Perthread`,
775  /// it can explicitly create one with `create_perthread_info()`, pass
776  /// it around, and eventually be responsible for destroying it with
777  /// `destroy_perthread_info()`. When managing the storage, the app
778  /// may reuse the `Perthread` for another thread after the first is
779  /// terminated, but still may not use the same `Perthread` for two
780  /// threads running concurrently.
781 
782  /// Define an opaque data type that allows us to have a pointer to
783  /// certain per-thread information that the TextureSystem maintains. Any
784  /// given one of these should NEVER be shared between running threads.
785  class Perthread;
786 
787  /// Retrieve a Perthread, unique to the calling thread. This is a
788  /// thread-specific pointer that will always return the Perthread for a
789  /// thread, which will also be automatically destroyed when the thread
790  /// terminates.
791  ///
792  /// Applications that want to manage their own Perthread pointers (with
793  /// `create_thread_info` and `destroy_thread_info`) should still call
794  /// this, but passing in their managed pointer. If the passed-in
795  /// thread_info is not nullptr, it won't create a new one or retrieve a
796  /// TSP, but it will do other necessary housekeeping on the Perthread
797  /// information.
798  virtual Perthread* get_perthread_info(Perthread* thread_info = nullptr) = 0;
799 
800  /// Create a new Perthread. It is the caller's responsibility to
801  /// eventually destroy it using `destroy_thread_info()`.
802  virtual Perthread* create_thread_info() = 0;
803 
804  /// Destroy a Perthread that was allocated by `create_thread_info()`.
805  virtual void destroy_thread_info(Perthread* threadinfo) = 0;
806 
807  /// Define an opaque data type that allows us to have a handle to a
808  /// texture (already having its name resolved) but without exposing
809  /// any internals.
810  class TextureHandle;
811 
812  /// Retrieve an opaque handle for fast texture lookups. The filename is
813  /// presumed to be UTF-8 encoded. The `options`, if not null, may be used
814  /// to create a separate handle for certain texture option choices
815  /// (currently: the colorspace). The opaque pointer `thread_info` is
816  /// thread-specific information returned by `get_perthread_info()`. Return
817  /// nullptr if something has gone horribly wrong.
818  virtual TextureHandle* get_texture_handle(ustring filename,
819  Perthread* thread_info = nullptr,
820  const TextureOpt* options = nullptr) = 0;
821  /// Get a TextureHandle using a UTF-16 encoded wstring filename.
822  TextureHandle* get_texture_handle(const std::wstring& filename,
823  Perthread* thread_info = nullptr,
824  const TextureOpt* options = nullptr) {
825  return get_texture_handle(ustring(Strutil::utf16_to_utf8(filename)),
826  thread_info, options);
827  }
828 
829  /// Return true if the texture handle (previously returned by
830  /// `get_image_handle()`) is a valid texture that can be subsequently
831  /// read.
832  virtual bool good(TextureHandle* texture_handle) = 0;
833 
834  /// Given a handle, return the UTF-8 encoded filename for that texture.
835  ///
836  /// This method was added in OpenImageIO 2.3.
837  virtual ustring filename_from_handle(TextureHandle* handle) = 0;
838 
839  /// Retrieve an id for a color transformation by name. This ID can be used
840  /// as the value for TextureOpt::colortransformid. The returned value will
841  /// be -1 if either color space is unknown, and 0 for a null
842  /// transformation.
843  virtual int get_colortransform_id(ustring fromspace,
844  ustring tospace) const = 0;
845  virtual int get_colortransform_id(ustringhash fromspace,
846  ustringhash tospace) const = 0;
847  /// @}
848 
849  /// @{
850  /// @name Texture lookups
851  ///
852 
853  /// Perform a filtered 2D texture lookup on a position centered at 2D
854  /// coordinates (`s`, `t`) from the texture identified by `filename`,
855  /// and using relevant texture `options`. The `nchannels` parameter
856  /// determines the number of channels to retrieve (e.g., 1 for a single
857  /// value, 3 for an RGB triple, etc.). The filtered results will be
858  /// stored in `result[0..nchannels-1]`.
859  ///
860  /// We assume that this lookup will be part of an image that has pixel
861  /// coordinates `x` and `y`. By knowing how `s` and `t` change from
862  /// pixel to pixel in the final image, we can properly *filter* or
863  /// antialias the texture lookups. This information is given via
864  /// derivatives `dsdx` and `dtdx` that define the change in `s` and `t`
865  /// per unit of `x`, and `dsdy` and `dtdy` that define the change in `s`
866  /// and `t` per unit of `y`. If it is impossible to know the
867  /// derivatives, you may pass 0 for them, but in that case you will not
868  /// receive an antialiased texture lookup.
869  ///
870  /// @param filename
871  /// The name of the texture, as a UTF-8 encoded ustring.
872  /// @param options
873  /// Fields within `options` that are honored for 2D texture lookups
874  /// include the following:
875  /// - `int firstchannel` :
876  /// The index of the first channel to look up from the texture.
877  /// - `int subimage / ustring subimagename` :
878  /// The subimage or face within the file, specified by
879  /// either by name (if non-empty) or index. This will be
880  /// ignored if the file does not have multiple subimages or
881  /// separate per-face textures.
882  /// - `Wrap swrap, twrap` :
883  /// Specify the *wrap mode* for each direction, one of:
884  /// `WrapBlack`, `WrapClamp`, `WrapPeriodic`, `WrapMirror`,
885  /// or `WrapDefault`.
886  /// - `float swidth, twidth` :
887  /// For each direction, gives a multiplier for the derivatives.
888  /// - `float sblur, tblur` :
889  /// For each direction, specifies an additional amount of
890  /// pre-blur to apply to the texture (*after* derivatives
891  /// are taken into account), expressed as a portion of the
892  /// width of the texture.
893  /// - `float fill` :
894  /// Specifies the value that will be used for any color
895  /// channels that are requested but not found in the file.
896  /// For example, if you perform a 4-channel lookup on a
897  /// 3-channel texture, the last channel will get the fill
898  /// value. (Note: this behavior is affected by the
899  /// `"gray_to_rgb"` TextureSystem attribute.
900  /// - `const float *missingcolor` :
901  /// If not `nullptr`, specifies the color that will be
902  /// returned for missing or broken textures (rather than
903  /// being an error).
904  /// @param s/t
905  /// The 2D texture coordinates.
906  /// @param dsdx,dtdx,dsdy,dtdy
907  /// The differentials of s and t relative to canonical
908  /// directions x and y. The choice of x and y are not
909  /// important to the implementation; it can be any imposed
910  /// 2D coordinates, such as pixels in screen space, adjacent
911  /// samples in parameter space on a surface, etc. The st
912  /// derivatives determine the size and shape of the
913  /// ellipsoid over which the texture lookup is filtered.
914  /// @param nchannels
915  /// The number of channels of data to retrieve into `result`
916  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
917  /// @param result[]
918  /// The result of the filtered texture lookup will be placed
919  /// into `result[0..nchannels-1]`.
920  /// @param dresultds/dresultdt
921  /// If non-null, these designate storage locations for the
922  /// derivatives of result, i.e., the rate of change per unit
923  /// s and t, respectively, of the filtered texture. If
924  /// supplied, they must allow for `nchannels` of storage.
925  /// @returns
926  /// `true` upon success, or `false` if the file was not
927  /// found or could not be opened by any available ImageIO
928  /// plugin.
929  ///
930  virtual bool texture (ustring filename, TextureOpt &options,
931  float s, float t, float dsdx, float dtdx,
932  float dsdy, float dtdy,
933  int nchannels, float *result,
934  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
935 
936  /// Slightly faster version of texture() lookup if the app already has a
937  /// texture handle and per-thread info.
938  virtual bool texture (TextureHandle *texture_handle,
939  Perthread *thread_info, TextureOpt &options,
940  float s, float t, float dsdx, float dtdx,
941  float dsdy, float dtdy,
942  int nchannels, float *result,
943  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
944 
945 
946  /// Perform a filtered 3D volumetric texture lookup on a position
947  /// centered at 3D position `P` (with given differentials) from the
948  /// texture identified by `filename`, and using relevant texture
949  /// `options`. The filtered results will be stored in
950  /// `result[0..nchannels-1]`.
951  ///
952  /// The `P` coordinate and `dPdx`, `dPdy`, and `dPdz` derivatives are
953  /// assumed to be in some kind of common global coordinate system
954  /// (usually "world" space) and will be automatically transformed into
955  /// volume local coordinates, if such a transformation is specified in
956  /// the volume file itself.
957  ///
958  /// @param filename
959  /// The name of the texture, as a UTF-8 encoded ustring.
960  /// @param options
961  /// Fields within `options` that are honored for 3D texture lookups
962  /// include the following:
963  /// - `int firstchannel` :
964  /// The index of the first channel to look up from the texture.
965  /// - `int subimage / ustring subimagename` :
966  /// The subimage or field within the volume, specified by
967  /// either by name (if non-empty) or index. This will be
968  /// ignored if the file does not have multiple subimages or
969  /// separate per-face textures.
970  /// - `Wrap swrap, twrap, rwrap` :
971  /// Specify the *wrap mode* for each direction, one of:
972  /// `WrapBlack`, `WrapClamp`, `WrapPeriodic`, `WrapMirror`,
973  /// or `WrapDefault`.
974  /// - `float swidth, twidth, rwidth` :
975  /// For each direction, gives a multiplier for the derivatives.
976  /// - `float sblur, tblur, rblur` :
977  /// For each direction, specifies an additional amount of
978  /// pre-blur to apply to the texture (*after* derivatives
979  /// are taken into account), expressed as a portion of the
980  /// width of the texture.
981  /// - `float fill` :
982  /// Specifies the value that will be used for any color
983  /// channels that are requested but not found in the file.
984  /// For example, if you perform a 4-channel lookup on a
985  /// 3-channel texture, the last channel will get the fill
986  /// value. (Note: this behavior is affected by the
987  /// `"gray_to_rgb"` TextureSystem attribute.
988  /// - `const float *missingcolor` :
989  /// If not `nullptr`, specifies the color that will be
990  /// returned for missing or broken textures (rather than
991  /// being an error).
992  /// - `float time` :
993  /// A time value to use if the volume texture specifies a
994  /// time-varying local transformation (default: 0).
995  /// @param P
996  /// The 2D texture coordinates.
997  /// @param dPdx/dPdy/dPdz
998  /// The differentials of `P`. We assume that this lookup
999  /// will be part of an image that has pixel coordinates `x`
1000  /// and `y` and depth `z`. By knowing how `P` changes from
1001  /// pixel to pixel in the final image, and as we step in *z*
1002  /// depth, we can properly *filter* or antialias the texture
1003  /// lookups. This information is given via derivatives
1004  /// `dPdx`, `dPdy`, and `dPdz` that define the changes in
1005  /// `P` per unit of `x`, `y`, and `z`, respectively. If it
1006  /// is impossible to know the derivatives, you may pass 0
1007  /// for them, but in that case you will not receive an
1008  /// antialiased texture lookup.
1009  /// @param nchannels
1010  /// The number of channels of data to retrieve into `result`
1011  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
1012  /// @param result[]
1013  /// The result of the filtered texture lookup will be placed
1014  /// into `result[0..nchannels-1]`.
1015  /// @param dresultds/dresultdt/dresultdr
1016  /// If non-null, these designate storage locations for the
1017  /// derivatives of result, i.e., the rate of change per unit
1018  /// s, t, and r, respectively, of the filtered texture. If
1019  /// supplied, they must allow for `nchannels` of storage.
1020  /// @returns
1021  /// `true` upon success, or `false` if the file was not
1022  /// found or could not be opened by any available ImageIO
1023  /// plugin.
1024  ///
1025  virtual bool texture3d (ustring filename, TextureOpt &options,
1026  V3fParam P, V3fParam dPdx,
1027  V3fParam dPdy, V3fParam dPdz,
1028  int nchannels, float *result,
1029  float *dresultds=nullptr, float *dresultdt=nullptr,
1030  float *dresultdr=nullptr) = 0;
1031 
1032  /// Slightly faster version of texture3d() lookup if the app already has
1033  /// a texture handle and per-thread info.
1034  virtual bool texture3d (TextureHandle *texture_handle,
1035  Perthread *thread_info, TextureOpt &options,
1036  V3fParam P, V3fParam dPdx,
1037  V3fParam dPdy, V3fParam dPdz,
1038  int nchannels, float *result,
1039  float *dresultds=nullptr, float *dresultdt=nullptr,
1040  float *dresultdr=nullptr) = 0;
1041 
1042 
1043  // Retrieve a shadow lookup for a single position P.
1044  //
1045  // Return true if the file is found and could be opened by an
1046  // available ImageIO plugin, otherwise return false.
1047  virtual bool shadow (ustring filename, TextureOpt &options,
1048  V3fParam P, V3fParam dPdx,
1049  V3fParam dPdy, float *result,
1050  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1051 
1052  // Slightly faster version of texture3d() lookup if the app already
1053  // has a texture handle and per-thread info.
1054  virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info,
1055  TextureOpt &options,
1056  V3fParam P, V3fParam dPdx,
1057  V3fParam dPdy, float *result,
1058  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1059 
1060  /// Perform a filtered directional environment map lookup in the
1061  /// direction of vector `R`, from the texture identified by `filename`,
1062  /// and using relevant texture `options`. The filtered results will be
1063  /// stored in `result[]`.
1064  ///
1065  /// @param filename
1066  /// The name of the texture, as a UTF-8 encode ustring.
1067  /// @param options
1068  /// Fields within `options` that are honored for environment lookups
1069  /// include the following:
1070  /// - `int firstchannel` :
1071  /// The index of the first channel to look up from the texture.
1072  /// - `int subimage / ustring subimagename` :
1073  /// The subimage or face within the file, specified by
1074  /// either by name (if non-empty) or index. This will be
1075  /// ignored if the file does not have multiple subimages or
1076  /// separate per-face textures.
1077  /// - `float swidth, twidth` :
1078  /// For each direction, gives a multiplier for the
1079  /// derivatives.
1080  /// - `float sblur, tblur` :
1081  /// For each direction, specifies an additional amount of
1082  /// pre-blur to apply to the texture (*after* derivatives
1083  /// are taken into account), expressed as a portion of the
1084  /// width of the texture.
1085  /// - `float fill` :
1086  /// Specifies the value that will be used for any color
1087  /// channels that are requested but not found in the file.
1088  /// For example, if you perform a 4-channel lookup on a
1089  /// 3-channel texture, the last channel will get the fill
1090  /// value. (Note: this behavior is affected by the
1091  /// `"gray_to_rgb"` TextureSystem attribute.
1092  /// - `const float *missingcolor` :
1093  /// If not `nullptr`, specifies the color that will be
1094  /// returned for missing or broken textures (rather than
1095  /// being an error).
1096  /// @param R
1097  /// The direction vector to look up.
1098  /// @param dRdx/dRdy
1099  /// The differentials of `R` with respect to image
1100  /// coordinates x and y.
1101  /// @param nchannels
1102  /// The number of channels of data to retrieve into `result`
1103  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
1104  /// @param result[]
1105  /// The result of the filtered texture lookup will be placed
1106  /// into `result[0..nchannels-1]`.
1107  /// @param dresultds/dresultdt
1108  /// If non-null, these designate storage locations for the
1109  /// derivatives of result, i.e., the rate of change per unit
1110  /// s and t, respectively, of the filtered texture. If
1111  /// supplied, they must allow for `nchannels` of storage.
1112  /// @returns
1113  /// `true` upon success, or `false` if the file was not
1114  /// found or could not be opened by any available ImageIO
1115  /// plugin.
1116  virtual bool environment (ustring filename, TextureOpt &options,
1117  V3fParam R, V3fParam dRdx,
1118  V3fParam dRdy, int nchannels, float *result,
1119  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1120 
1121  /// Slightly faster version of environment() if the app already has a
1122  /// texture handle and per-thread info.
1123  virtual bool environment (TextureHandle *texture_handle,
1124  Perthread *thread_info, TextureOpt &options,
1125  V3fParam R, V3fParam dRdx,
1126  V3fParam dRdy, int nchannels, float *result,
1127  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1128 
1129  /// @}
1130 
1131  /// @{
1132  /// @name Batched texture lookups
1133  ///
1134 
1135  /// Perform filtered 2D texture lookups on a batch of positions from the
1136  /// same texture, all at once. The parameters `s`, `t`, `dsdx`, `dtdx`,
1137  /// and `dsdy`, `dtdy` are each a pointer to `[BatchWidth]` values. The
1138  /// `mask` determines which of those array elements to actually compute.
1139  ///
1140  /// The float* results act like `float[nchannels][BatchWidth]`, so that
1141  /// effectively `result[0..BatchWidth-1]` are the "red" result for each
1142  /// lane, `result[BatchWidth..2*BatchWidth-1]` are the "green" results,
1143  /// etc. The `dresultds` and `dresultdt` should either both be provided,
1144  /// or else both be nullptr (meaning no derivative results are
1145  /// required).
1146  ///
1147  /// @param filename
1148  /// The name of the texture, as a UTF-8 encode ustring.
1149  /// @param options
1150  /// A TextureOptBatch containing texture lookup options.
1151  /// This is conceptually the same as a TextureOpt, but the
1152  /// following fields are arrays of `[BatchWidth]` elements:
1153  /// sblur, tblur, swidth, twidth. The other fields are, as
1154  /// with TextureOpt, ordinary scalar values.
1155  /// @param mask
1156  /// A bit-field designating which "lanes" should be
1157  /// computed: if `mask & (1<<i)` is nonzero, then results
1158  /// should be computed and stored for `result[...][i]`.
1159  /// @param s/t
1160  /// Pointers to the 2D texture coordinates, each as a
1161  /// `float[BatchWidth]`.
1162  /// @param dsdx/dtdx/dsdy/dtdy
1163  /// The differentials of s and t relative to canonical
1164  /// directions x and y, each as a `float[BatchWidth]`.
1165  /// @param nchannels
1166  /// The number of channels of data to retrieve into `result`
1167  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
1168  /// @param result[]
1169  /// The result of the filtered texture lookup will be placed
1170  /// here, as `float [nchannels][BatchWidth]`. (Note the
1171  /// "SOA" data layout.)
1172  /// @param dresultds/dresultdt
1173  /// If non-null, these designate storage locations for the
1174  /// derivatives of result, and like `result` are in SOA
1175  /// layout: `float [nchannels][BatchWidth]`
1176  /// @returns
1177  /// `true` upon success, or `false` if the file was not
1178  /// found or could not be opened by any available ImageIO
1179  /// plugin.
1180  ///
1181  virtual bool texture (ustring filename, TextureOptBatch &options,
1182  Tex::RunMask mask, const float *s, const float *t,
1183  const float *dsdx, const float *dtdx,
1184  const float *dsdy, const float *dtdy,
1185  int nchannels, float *result,
1186  float *dresultds=nullptr,
1187  float *dresultdt=nullptr) = 0;
1188  /// Slightly faster version of texture() lookup if the app already has a
1189  /// texture handle and per-thread info.
1190  virtual bool texture (TextureHandle *texture_handle,
1191  Perthread *thread_info, TextureOptBatch &options,
1192  Tex::RunMask mask, const float *s, const float *t,
1193  const float *dsdx, const float *dtdx,
1194  const float *dsdy, const float *dtdy,
1195  int nchannels, float *result,
1196  float *dresultds=nullptr,
1197  float *dresultdt=nullptr) = 0;
1198 
1199 #ifndef OIIO_DOXYGEN
1200  // Old multi-point API call.
1201  // DEPRECATED (1.8)
1202  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1203  virtual bool texture (ustring filename, TextureOptions &options,
1204  Runflag *runflags, int beginactive, int endactive,
1205  VaryingRef<float> s, VaryingRef<float> t,
1206  VaryingRef<float> dsdx, VaryingRef<float> dtdx,
1207  VaryingRef<float> dsdy, VaryingRef<float> dtdy,
1208  int nchannels, float *result,
1209  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1210  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1211  virtual bool texture (TextureHandle *texture_handle,
1212  Perthread *thread_info, TextureOptions &options,
1213  Runflag *runflags, int beginactive, int endactive,
1214  VaryingRef<float> s, VaryingRef<float> t,
1215  VaryingRef<float> dsdx, VaryingRef<float> dtdx,
1216  VaryingRef<float> dsdy, VaryingRef<float> dtdy,
1217  int nchannels, float *result,
1218  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1219 #endif
1220 
1221  /// Perform filtered 3D volumetric texture lookups on a batch of
1222  /// positions from the same texture, all at once. The "point-like"
1223  /// parameters `P`, `dPdx`, `dPdy`, and `dPdz` are each a pointers to
1224  /// arrays of `float value[3][BatchWidth]` (or alternately like
1225  /// `Imath::Vec3<FloatWide>`). That is, each one points to all the *x*
1226  /// values for the batch, immediately followed by all the *y* values,
1227  /// followed by the *z* values. The `mask` determines which of those
1228  /// array elements to actually compute.
1229  ///
1230  /// The various results arrays are also arranged as arrays that behave
1231  /// as if they were declared `float result[channels][BatchWidth]`, where
1232  /// all the batch values for channel 0 are adjacent, followed by all the
1233  /// batch values for channel 1, etc.
1234  ///
1235  /// @param filename
1236  /// The name of the texture, as a UTF-8 encode ustring.
1237  /// @param options
1238  /// A TextureOptBatch containing texture lookup options.
1239  /// This is conceptually the same as a TextureOpt, but the
1240  /// following fields are arrays of `[BatchWidth]` elements:
1241  /// sblur, tblur, swidth, twidth. The other fields are, as
1242  /// with TextureOpt, ordinary scalar values.
1243  /// @param mask
1244  /// A bit-field designating which "lanes" should be
1245  /// computed: if `mask & (1<<i)` is nonzero, then results
1246  /// should be computed and stored for `result[...][i]`.
1247  /// @param P
1248  /// Pointers to the 3D texture coordinates, each as a
1249  /// `float[3][BatchWidth]`.
1250  /// @param dPdx/dPdy/dPdz
1251  /// The differentials of P relative to canonical directions
1252  /// x, y, and z, each as a `float[3][BatchWidth]`.
1253  /// @param nchannels
1254  /// The number of channels of data to retrieve into `result`
1255  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
1256  /// @param result[]
1257  /// The result of the filtered texture lookup will be placed
1258  /// here, as `float [nchannels][BatchWidth]`. (Note the
1259  /// "SOA" data layout.)
1260  /// @param dresultds/dresultdt/dresultdr
1261  /// If non-null, these designate storage locations for the
1262  /// derivatives of result, and like `result` are in SOA
1263  /// layout: `float [nchannels][BatchWidth]`
1264  /// @returns
1265  /// `true` upon success, or `false` if the file was not
1266  /// found or could not be opened by any available ImageIO
1267  /// plugin.
1268  ///
1269  virtual bool texture3d (ustring filename,
1270  TextureOptBatch &options, Tex::RunMask mask,
1271  const float *P, const float *dPdx,
1272  const float *dPdy, const float *dPdz,
1273  int nchannels, float *result,
1274  float *dresultds=nullptr, float *dresultdt=nullptr,
1275  float *dresultdr=nullptr) = 0;
1276  /// Slightly faster version of texture3d() lookup if the app already
1277  /// has a texture handle and per-thread info.
1278  virtual bool texture3d (TextureHandle *texture_handle,
1279  Perthread *thread_info,
1280  TextureOptBatch &options, Tex::RunMask mask,
1281  const float *P, const float *dPdx,
1282  const float *dPdy, const float *dPdz,
1283  int nchannels, float *result,
1284  float *dresultds=nullptr, float *dresultdt=nullptr,
1285  float *dresultdr=nullptr) = 0;
1286 
1287 #ifndef OIIO_DOXYGEN
1288  // Retrieve a 3D texture lookup at many points at once.
1289  // DEPRECATED(1.8)
1290  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1291  virtual bool texture3d (ustring filename, TextureOptions &options,
1292  Runflag *runflags, int beginactive, int endactive,
1293  VaryingRef<Imath::V3f> P,
1294  VaryingRef<Imath::V3f> dPdx,
1295  VaryingRef<Imath::V3f> dPdy,
1296  VaryingRef<Imath::V3f> dPdz,
1297  int nchannels, float *result,
1298  float *dresultds=nullptr, float *dresultdt=nullptr,
1299  float *dresultdr=nullptr) = 0;
1300  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1301  virtual bool texture3d (TextureHandle *texture_handle,
1302  Perthread *thread_info, TextureOptions &options,
1303  Runflag *runflags, int beginactive, int endactive,
1304  VaryingRef<Imath::V3f> P,
1305  VaryingRef<Imath::V3f> dPdx,
1306  VaryingRef<Imath::V3f> dPdy,
1307  VaryingRef<Imath::V3f> dPdz,
1308  int nchannels, float *result,
1309  float *dresultds=nullptr, float *dresultdt=nullptr,
1310  float *dresultdr=nullptr) = 0;
1311 #endif
1312 
1313  /// Perform filtered directional environment map lookups on a batch of
1314  /// directions from the same texture, all at once. The "point-like"
1315  /// parameters `R`, `dRdx`, and `dRdy` are each a pointers to arrays of
1316  /// `float value[3][BatchWidth]` (or alternately like
1317  /// `Imath::Vec3<FloatWide>`). That is, each one points to all the *x*
1318  /// values for the batch, immediately followed by all the *y* values,
1319  /// followed by the *z* values. The `mask` determines which of those
1320  /// array elements to actually compute.
1321  ///
1322  /// The various results arrays are also arranged as arrays that behave
1323  /// as if they were declared `float result[channels][BatchWidth]`, where
1324  /// all the batch values for channel 0 are adjacent, followed by all the
1325  /// batch values for channel 1, etc.
1326  ///
1327  /// @param filename
1328  /// The name of the texture, as a UTF-8 encode ustring.
1329  /// @param options
1330  /// A TextureOptBatch containing texture lookup options.
1331  /// This is conceptually the same as a TextureOpt, but the
1332  /// following fields are arrays of `[BatchWidth]` elements:
1333  /// sblur, tblur, swidth, twidth. The other fields are, as
1334  /// with TextureOpt, ordinary scalar values.
1335  /// @param mask
1336  /// A bit-field designating which "lanes" should be
1337  /// computed: if `mask & (1<<i)` is nonzero, then results
1338  /// should be computed and stored for `result[...][i]`.
1339  /// @param R
1340  /// Pointers to the 3D texture coordinates, each as a
1341  /// `float[3][BatchWidth]`.
1342  /// @param dRdx/dRdy
1343  /// The differentials of R relative to canonical directions
1344  /// x and y, each as a `float[3][BatchWidth]`.
1345  /// @param nchannels
1346  /// The number of channels of data to retrieve into `result`
1347  /// (e.g., 1 for a single value, 3 for an RGB triple, etc.).
1348  /// @param result[]
1349  /// The result of the filtered texture lookup will be placed
1350  /// here, as `float [nchannels][BatchWidth]`. (Note the
1351  /// "SOA" data layout.)
1352  /// @param dresultds/dresultdt
1353  /// If non-null, these designate storage locations for the
1354  /// derivatives of result, and like `result` are in SOA
1355  /// layout: `float [nchannels][BatchWidth]`
1356  /// @returns
1357  /// `true` upon success, or `false` if the file was not
1358  /// found or could not be opened by any available ImageIO
1359  /// plugin.
1360  ///
1361  virtual bool environment (ustring filename,
1362  TextureOptBatch &options, Tex::RunMask mask,
1363  const float *R, const float *dRdx, const float *dRdy,
1364  int nchannels, float *result,
1365  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1366  /// Slightly faster version of environment() if the app already has a
1367  /// texture handle and per-thread info.
1368  virtual bool environment (TextureHandle *texture_handle, Perthread *thread_info,
1369  TextureOptBatch &options, Tex::RunMask mask,
1370  const float *R, const float *dRdx, const float *dRdy,
1371  int nchannels, float *result,
1372  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1373 
1374 #ifndef OIIO_DOXYGEN
1375  // Retrieve an environment map lookup for direction R, for many
1376  // points at once.
1377  // DEPRECATED(1.8)
1378  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1379  virtual bool environment (ustring filename, TextureOptions &options,
1380  Runflag *runflags, int beginactive, int endactive,
1381  VaryingRef<Imath::V3f> R,
1382  VaryingRef<Imath::V3f> dRdx,
1383  VaryingRef<Imath::V3f> dRdy,
1384  int nchannels, float *result,
1385  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1386  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1387  virtual bool environment (TextureHandle *texture_handle,
1388  Perthread *thread_info, TextureOptions &options,
1389  Runflag *runflags, int beginactive, int endactive,
1390  VaryingRef<Imath::V3f> R,
1391  VaryingRef<Imath::V3f> dRdx,
1392  VaryingRef<Imath::V3f> dRdy,
1393  int nchannels, float *result,
1394  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1395 #endif
1396 
1397  // Batched shadow lookups
1398  virtual bool shadow (ustring filename,
1399  TextureOptBatch &options, Tex::RunMask mask,
1400  const float *P, const float *dPdx, const float *dPdy,
1401  float *result, float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1402  virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info,
1403  TextureOptBatch &options, Tex::RunMask mask,
1404  const float *P, const float *dPdx, const float *dPdy,
1405  float *result, float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1406 
1407 #ifndef OIIO_DOXYGEN
1408  // Retrieve a shadow lookup for position P at many points at once.
1409  // DEPRECATED(1.8)
1410  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1411  virtual bool shadow (ustring filename, TextureOptions &options,
1412  Runflag *runflags, int beginactive, int endactive,
1413  VaryingRef<Imath::V3f> P,
1414  VaryingRef<Imath::V3f> dPdx,
1415  VaryingRef<Imath::V3f> dPdy,
1416  float *result,
1417  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1418  OIIO_DEPRECATED("no longer support this multi-point call (1.8)")
1419  virtual bool shadow (TextureHandle *texture_handle, Perthread *thread_info,
1420  TextureOptions &options,
1421  Runflag *runflags, int beginactive, int endactive,
1422  VaryingRef<Imath::V3f> P,
1423  VaryingRef<Imath::V3f> dPdx,
1424  VaryingRef<Imath::V3f> dPdy,
1425  float *result,
1426  float *dresultds=nullptr, float *dresultdt=nullptr) = 0;
1427 #endif
1428 
1429  /// @}
1430 
1431 
1432  /// @{
1433  /// @name Texture metadata and raw texels
1434  ///
1435 
1436  /// Given possibly-relative 'filename' (UTF-8 encoded), resolve it using
1437  /// the search path rules and return the full resolved filename.
1438  virtual std::string resolve_filename (const std::string &filename) const=0;
1439 
1440  /// Get information or metadata about the named texture and store it in
1441  /// `*data`.
1442  ///
1443  /// Data names may include any of the following:
1444  ///
1445  /// - `exists` (int):
1446  /// Stores the value 1 if the file exists and is an image format
1447  /// that OpenImageIO can read, or 0 if the file does not exist,
1448  /// or could not be properly read as a texture. Note that unlike
1449  /// all other queries, this query will "succeed" (return `true`)
1450  /// even if the file does not exist.
1451  ///
1452  /// - `udim` (int) :
1453  /// Stores the value 1 if the file is a "virtual UDIM" or
1454  /// texture atlas file (as described in Section
1455  /// :ref:`sec-texturesys-udim`) or 0 otherwise.
1456  ///
1457  /// - `subimages` (int) :
1458  /// The number of subimages/faces in the file, as an integer.
1459  ///
1460  /// - `resolution` (int[2] or int[3]):
1461  /// The resolution of the texture file, if an array of 2
1462  /// integers (described as `TypeDesc(INT,2)`), or the 3D
1463  /// resolution of the texture file, which is an array of 3
1464  /// integers (described as `TypeDesc(INT,3)`) The third value
1465  /// will be 1 unless it's a volumetric (3D) image.
1466  ///
1467  /// - `miplevels` (int) :
1468  /// The number of MIPmap levels for the specified
1469  /// subimage (an integer).
1470  ///
1471  /// - `texturetype` (string) :
1472  /// A string describing the type of texture of the given file,
1473  /// which describes how the texture may be used (also which
1474  /// texture API call is probably the right one for it). This
1475  /// currently may return one of: "unknown", "Plain Texture",
1476  /// "Volume Texture", "Shadow", or "Environment".
1477  ///
1478  /// - `textureformat` (string) :
1479  /// A string describing the format of the given file, which
1480  /// describes the kind of texture stored in the file. This
1481  /// currently may return one of: "unknown", "Plain Texture",
1482  /// "Volume Texture", "Shadow", "CubeFace Shadow", "Volume
1483  /// Shadow", "LatLong Environment", or "CubeFace Environment".
1484  /// Note that there are several kinds of shadows and environment
1485  /// maps, all accessible through the same API calls.
1486  ///
1487  /// - `channels` (int) :
1488  /// The number of color channels in the file.
1489  ///
1490  /// - `format` (int) :
1491  /// The native data format of the pixels in the file (an
1492  /// integer, giving the `TypeDesc::BASETYPE` of the data). Note
1493  /// that this is not necessarily the same as the data format
1494  /// stored in the image cache.
1495  ///
1496  /// - `cachedformat` (int) :
1497  /// The native data format of the pixels as stored in the image
1498  /// cache (an integer, giving the `TypeDesc::BASETYPE` of the
1499  /// data). Note that this is not necessarily the same as the
1500  /// native data format of the file.
1501  ///
1502  /// - `datawindow` (int[4] or int[6]):
1503  /// Returns the pixel data window of the image, which is either
1504  /// an array of 4 integers (returning xmin, ymin, xmax, ymax) or
1505  /// an array of 6 integers (returning xmin, ymin, zmin, xmax,
1506  /// ymax, zmax). The z values may be useful for 3D/volumetric
1507  /// images; for 2D images they will be 0).
1508  ///
1509  /// - `displaywindow` (matrix) :
1510  /// Returns the display (a.k.a. full) window of the image, which
1511  /// is either an array of 4 integers (returning xmin, ymin,
1512  /// xmax, ymax) or an array of 6 integers (returning xmin, ymin,
1513  /// zmin, xmax, ymax, zmax). The z values may be useful for
1514  /// 3D/volumetric images; for 2D images they will be 0).
1515  ///
1516  /// - `worldtocamera` (matrix) :
1517  /// The viewing matrix, which is a 4x4 matrix (an `Imath::M44f`,
1518  /// described as `TypeMatrix44`) giving the world-to-camera 3D
1519  /// transformation matrix that was used when the image was
1520  /// created. Generally, only rendered images will have this.
1521  ///
1522  /// - `worldtoscreen` (matrix) :
1523  /// The projection matrix, which is a 4x4 matrix (an
1524  /// `Imath::M44f`, described as `TypeMatrix44`) giving the
1525  /// matrix that projected points from world space into a 2D
1526  /// screen coordinate system where *x* and *y* range from -1 to
1527  /// +1. Generally, only rendered images will have this.
1528  ///
1529  /// - `worldtoNDC` (matrix) :
1530  /// The projection matrix, which is a 4x4 matrix (an
1531  /// `Imath::M44f`, described as `TypeMatrix44`) giving the
1532  /// matrix that projected points from world space into a 2D
1533  /// screen coordinate system where *x* and *y* range from 0 to
1534  /// +1. Generally, only rendered images will have this.
1535  ///
1536  /// - `averagecolor` (float[nchannels]) :
1537  /// If available in the metadata (generally only for files that
1538  /// have been processed by `maketx`), this will return the
1539  /// average color of the texture (into an array of floats).
1540  ///
1541  /// - `averagealpha` (float) :
1542  /// If available in the metadata (generally only for files that
1543  /// have been processed by `maketx`), this will return the
1544  /// average alpha value of the texture (into a float).
1545  ///
1546  /// - `constantcolor` (float[nchannels]) :
1547  /// If the metadata (generally only for files that have been
1548  /// processed by `maketx`) indicates that the texture has the
1549  /// same values for all pixels in the texture, this will
1550  /// retrieve the constant color of the texture (into an array of
1551  /// floats). A non-constant image (or one that does not have the
1552  /// special metadata tag identifying it as a constant texture)
1553  /// will fail this query (return false).
1554  ///
1555  /// - `constantalpha` (float) :
1556  /// If the metadata indicates that the texture has the same
1557  /// values for all pixels in the texture, this will retrieve the
1558  /// constant alpha value of the texture. A non-constant image
1559  /// (or one that does not have the special metadata tag
1560  /// identifying it as a constant texture) will fail this query
1561  /// (return false).
1562  ///
1563  /// - `stat:tilesread` (int64) :
1564  /// Number of tiles read from this file.
1565  ///
1566  /// - `stat:bytesread` (int64) :
1567  /// Number of bytes of uncompressed pixel data read
1568  ///
1569  /// - `stat:redundant_tiles` (int64) :
1570  /// Number of times a tile was read, where the same tile had
1571  /// been rad before.
1572  ///
1573  /// - `stat:redundant_bytesread` (int64) :
1574  /// Number of bytes (of uncompressed pixel data) in tiles that
1575  /// were read redundantly.
1576  ///
1577  /// - `stat:redundant_bytesread` (int) :
1578  /// Number of tiles read from this file.
1579  ///
1580  /// - `stat:timesopened` (int) :
1581  /// Number of times this file was opened.
1582  ///
1583  /// - `stat:iotime` (float) :
1584  /// Time (in seconds) spent on all I/O for this file.
1585  ///
1586  /// - `stat:mipsused` (int) :
1587  /// Stores 1 if any MIP levels beyond the highest resolution
1588  /// were accessed, otherwise 0.
1589  ///
1590  /// - `stat:is_duplicate` (int) :
1591  /// Stores 1 if this file was a duplicate of another image,
1592  /// otherwise 0.
1593  ///
1594  /// - *Anything else* :
1595  /// For all other data names, the the metadata of the image file
1596  /// will be searched for an item that matches both the name and
1597  /// data type.
1598  ///
1599  ///
1600  /// @param filename
1601  /// The name of the texture, as a UTF-8 encode ustring.
1602  /// @param subimage
1603  /// The subimage to query. (The metadata retrieved is for
1604  /// the highest-resolution MIP level of that subimage.)
1605  /// @param dataname
1606  /// The name of the metadata to retrieve.
1607  /// @param datatype
1608  /// TypeDesc describing the data type.
1609  /// @param data
1610  /// Pointer to the caller-owned memory where the values
1611  /// should be stored. It is the caller's responsibility to
1612  /// ensure that `data` points to a large enough storage area
1613  /// to accommodate the `datatype` requested.
1614  ///
1615  /// @returns
1616  /// `true` if `get_textureinfo()` is able to find the
1617  /// requested `dataname` for the texture and it matched the
1618  /// requested `datatype`. If the requested data was not
1619  /// found or was not of the right data type, return `false`.
1620  /// Except for the `"exists"` query, a file that does not
1621  /// exist or could not be read properly as an image also
1622  /// constitutes a query failure that will return `false`.
1623  virtual bool get_texture_info (ustring filename, int subimage,
1624  ustring dataname, TypeDesc datatype, void *data) = 0;
1625 
1626  /// A more efficient variety of `get_texture_info()` for cases where you
1627  /// can use a `TextureHandle*` to specify the image and optionally have
1628  /// a `Perthread*` for the calling thread.
1629  virtual bool get_texture_info (TextureHandle *texture_handle,
1630  Perthread *thread_info, int subimage,
1631  ustring dataname, TypeDesc datatype, void *data) = 0;
1632 
1633  /// Copy the ImageSpec associated with the named texture (the first
1634  /// subimage by default, or as set by `subimage`).
1635  ///
1636  /// @param filename
1637  /// The name of the texture, as a UTF-8 encode ustring.
1638  /// @param subimage
1639  /// The subimage to query. (The spec retrieved is for the
1640  /// highest-resolution MIP level of that subimage.)
1641  /// @param spec
1642  /// ImageSpec into which will be copied the spec for the
1643  /// requested image.
1644  /// @returns
1645  /// `true` upon success, `false` upon failure failure (such
1646  /// as being unable to find, open, or read the file, or if
1647  /// it does not contain the designated subimage or MIP
1648  /// level).
1649  virtual bool get_imagespec (ustring filename, int subimage,
1650  ImageSpec &spec) = 0;
1651  /// A more efficient variety of `get_imagespec()` for cases where you
1652  /// can use a `TextureHandle*` to specify the image and optionally have
1653  /// a `Perthread*` for the calling thread.
1654  virtual bool get_imagespec (TextureHandle *texture_handle,
1655  Perthread *thread_info, int subimage,
1656  ImageSpec &spec) = 0;
1657 
1658  /// Return a pointer to an ImageSpec associated with the named texture
1659  /// if the file is found and is an image format that can be read,
1660  /// otherwise return `nullptr`.
1661  ///
1662  /// This method is much more efficient than `get_imagespec()`, since it
1663  /// just returns a pointer to the spec held internally by the
1664  /// TextureSystem (rather than copying the spec to the user's memory).
1665  /// However, the caller must beware that the pointer is only valid as
1666  /// long as nobody (even other threads) calls `invalidate()` on the
1667  /// file, or `invalidate_all()`, or destroys the TextureSystem and its
1668  /// underlying ImageCache.
1669  ///
1670  /// @param filename
1671  /// The name of the texture, as a UTF-8 encode ustring.
1672  /// @param subimage
1673  /// The subimage to query. (The spec retrieved is for the
1674  /// highest-resolution MIP level of that subimage.)
1675  /// @returns
1676  /// A pointer to the spec, if the image is found and able to
1677  /// be opened and read by an available image format plugin,
1678  /// and the designated subimage exists.
1679  virtual const ImageSpec *imagespec (ustring filename, int subimage=0) = 0;
1680  /// A more efficient variety of `imagespec()` for cases where you can
1681  /// use a `TextureHandle*` to specify the image and optionally have a
1682  /// `Perthread*` for the calling thread.
1683  virtual const ImageSpec *imagespec (TextureHandle *texture_handle,
1684  Perthread *thread_info = nullptr,
1685  int subimage=0) = 0;
1686 
1687  /// For a texture specified by name, retrieve the rectangle of raw
1688  /// unfiltered texels from the subimage specified in `options` and at
1689  /// the designated `miplevel`, storing the pixel values beginning at the
1690  /// address specified by `result`. The pixel values will be converted
1691  /// to the data type specified by `format`. The rectangular region to be
1692  /// retrieved includes `begin` but does not include `end` (much like STL
1693  /// begin/end usage). Requested pixels that are not part of the valid
1694  /// pixel data region of the image file will be filled with zero values.
1695  /// Channels requested but not present in the file will get the
1696  /// `options.fill` value.
1697  ///
1698  /// @param filename
1699  /// The name of the texture, as a UTF-8 encode ustring.
1700  /// @param options
1701  /// A TextureOpt describing access options, including wrap
1702  /// modes, fill value, and subimage, that will be used when
1703  /// retrieving pixels.
1704  /// @param miplevel
1705  /// The MIP level to retrieve pixels from (0 is the highest
1706  /// resolution level).
1707  /// @param xbegin/xend/ybegin/yend/zbegin/zend
1708  /// The range of pixels to retrieve. The pixels retrieved
1709  /// include the begin value but not the end value (much like
1710  /// STL begin/end usage).
1711  /// @param chbegin/chend
1712  /// Channel range to retrieve. To retrieve all channels, use
1713  /// `chbegin = 0`, `chend = nchannels`.
1714  /// @param format
1715  /// TypeDesc describing the data type of the values you want
1716  /// to retrieve into `result`. The pixel values will be
1717  /// converted to this type regardless of how they were
1718  /// stored in the file or in the cache.
1719  /// @param result
1720  /// Pointer to the memory where the pixel values should be
1721  /// stored. It is up to the caller to ensure that `result`
1722  /// points to an area of memory big enough to accommodate
1723  /// the requested rectangle (taking into consideration its
1724  /// dimensions, number of channels, and data format).
1725  ///
1726  /// @returns
1727  /// `true` for success, `false` for failure.
1728  virtual bool get_texels (ustring filename, TextureOpt &options,
1729  int miplevel, int xbegin, int xend,
1730  int ybegin, int yend, int zbegin, int zend,
1731  int chbegin, int chend,
1732  TypeDesc format, void *result) = 0;
1733  /// A more efficient variety of `get_texels()` for cases where you can
1734  /// use a `TextureHandle*` to specify the image and optionally have a
1735  /// `Perthread*` for the calling thread.
1736  virtual bool get_texels (TextureHandle *texture_handle,
1737  Perthread *thread_info, TextureOpt &options,
1738  int miplevel, int xbegin, int xend,
1739  int ybegin, int yend, int zbegin, int zend,
1740  int chbegin, int chend,
1741  TypeDesc format, void *result) = 0;
1742 
1743  /// @}
1744 
1745  /// @{
1746  /// @name Methods for UDIM patterns
1747  ///
1748 
1749  /// Is the UTF-8 encoded filename a UDIM pattern?
1750  ///
1751  /// This method was added in OpenImageIO 2.3.
1752  virtual bool is_udim(ustring filename) = 0;
1753 
1754  /// Does the handle refer to a file that's a UDIM pattern?
1755  ///
1756  /// This method was added in OpenImageIO 2.3.
1757  virtual bool is_udim(TextureHandle* udimfile) = 0;
1758 
1759  /// For a UDIM filename pattern (UTF-8 encoded) and texture coordinates,
1760  /// return the TextureHandle pointer for the concrete tile file it refers
1761  /// to, or nullptr if there is no corresponding tile (udim sets are
1762  /// allowed to be sparse).
1763  ///
1764  /// This method was added in OpenImageIO 2.3.
1765  virtual TextureHandle* resolve_udim(ustring udimpattern,
1766  float s, float t) = 0;
1767 
1768  /// A more efficient variety of `resolve_udim()` for cases where you
1769  /// have the `TextureHandle*` that corresponds to the "virtual" UDIM
1770  /// file and optionally have a `Perthread*` for the calling thread.
1771  ///
1772  /// This method was added in OpenImageIO 2.3.
1773  virtual TextureHandle* resolve_udim(TextureHandle* udimfile,
1774  Perthread* thread_info,
1775  float s, float t) = 0;
1776 
1777  /// Produce a full inventory of the set of concrete files comprising the
1778  /// UDIM set specified by UTF-8 encoded `udimpattern`. The apparent
1779  /// number of texture atlas tiles in the u and v directions will be
1780  /// written to `nutiles` and `nvtiles`, respectively. The vector
1781  /// `filenames` will be sized to `ntiles * nvtiles` and filled with the
1782  /// the names of the concrete files comprising the atlas, with an empty
1783  /// ustring corresponding to any unpopulated tiles (the UDIM set is
1784  /// allowed to be sparse). The filename list is indexed as
1785  /// `utile + vtile * nvtiles`.
1786  ///
1787  /// This method was added in OpenImageIO 2.3.
1788  virtual void inventory_udim(ustring udimpattern,
1789  std::vector<ustring>& filenames,
1790  int& nutiles, int& nvtiles) = 0;
1791 
1792  /// A more efficient variety of `inventory_udim()` for cases where you
1793  /// have the `TextureHandle*` that corresponds to the "virtual" UDIM
1794  /// file and optionally have a `Perthread*` for the calling thread.
1795  ///
1796  /// This method was added in OpenImageIO 2.3.
1797  virtual void inventory_udim(TextureHandle* udimfile,
1798  Perthread* thread_info,
1799  std::vector<ustring>& filenames,
1800  int& nutiles, int& nvtiles) = 0;
1801  /// @}
1802 
1803  /// @{
1804  /// @name Controlling the cache
1805  ///
1806 
1807  /// Invalidate any cached information about the named file (UTF-8
1808  /// encoded), including loaded texture tiles from that texture, and close
1809  /// any open file handle associated with the file. This calls
1810  /// `ImageCache::invalidate(filename,force)` on the underlying ImageCache.
1811  virtual void invalidate (ustring filename, bool force = true) = 0;
1812 
1813  /// Invalidate all cached data for all textures. This calls
1814  /// `ImageCache::invalidate_all(force)` on the underlying ImageCache.
1815  virtual void invalidate_all (bool force=false) = 0;
1816 
1817  /// Close any open file handles associated with a UTF-8 encoded filename,
1818  /// but do not invalidate any image spec information or pixels associated
1819  /// with the files. A client might do this in order to release OS file
1820  /// handle resources, or to make it safe for other processes to modify
1821  /// textures on disk. This calls `ImageCache::close(force)` on the
1822  /// underlying ImageCache.
1823  virtual void close (ustring filename) = 0;
1824 
1825  /// `close()` all files known to the cache.
1826  virtual void close_all () = 0;
1827 
1828  /// @}
1829 
1830  /// @{
1831  /// @name Errors and statistics
1832 
1833  /// Is there a pending error message waiting to be retrieved?
1834  virtual bool has_error() const = 0;
1835 
1836  /// Return the text of all pending error messages issued against this
1837  /// TextureSystem, and clear the pending error message unless `clear` is
1838  /// false. If no error message is pending, it will return an empty
1839  /// string.
1840  virtual std::string geterror(bool clear = true) const = 0;
1841 
1842  /// Returns a big string containing useful statistics about the
1843  /// TextureSystem operations, suitable for saving to a file or
1844  /// outputting to the terminal. The `level` indicates the amount of
1845  /// detail in the statistics, with higher numbers (up to a maximum of 5)
1846  /// yielding more and more esoteric information. If `icstats` is true,
1847  /// the returned string will also contain all the statistics of the
1848  /// underlying ImageCache, but if false will only contain
1849  /// texture-specific statistics.
1850  virtual std::string getstats (int level=1, bool icstats=true) const = 0;
1851 
1852  /// Reset most statistics to be as they were with a fresh TextureSystem.
1853  /// Caveat emptor: this does not flush the cache itself, so the resulting
1854  /// statistics from the next set of texture requests will not match the
1855  /// number of tile reads, etc., that would have resulted from a new
1856  /// TextureSystem.
1857  virtual void reset_stats () = 0;
1858 
1859  /// @}
1860 
1861  /// Return an opaque, non-owning pointer to the underlying ImageCache
1862  /// (if there is one).
1863  virtual ImageCache *imagecache () const = 0;
1864 
1865  virtual ~TextureSystem () { }
1866 
1867  // For testing -- do not use
1868  static void unit_test_hash();
1869 
1870 protected:
1871  // User code should never directly construct or destruct a TextureSystem.
1872  // Always use TextureSystem::create() and TextureSystem::destroy().
1873  TextureSystem (void) { }
1874 private:
1875  // Make delete private and unimplemented in order to prevent apps
1876  // from calling it. Instead, they should call TextureSystem::destroy().
1877  void operator delete(void* /*todel*/) {}
1878 };
1879 
1880 
Use just one mipmap level.
Definition: texture.h:210
Periodic, but only for powers of 2!!!
MipMode
Definition: texture.h:108
OIIO_API std::string geterror(bool clear=true)
OIIO_API bool has_error()
Is there a pending global error message waiting to be retrieved?
Clamp to [0..1].
Definition: texture.h:197
OIIO_INLINE_CONSTEXPR RunMask RunMaskOn
Definition: texture.h:161
GT_API const UT_StringHolder filename
float rnd
Stratified sample value.
Definition: texture.h:262
float twidth
Multiplier for derivatives.
Definition: texture.h:256
RunFlagVal
Definition: texture.h:179
OIIO_API Wrap decode_wrapmode(ustringhash name)
float tblur
Blur amount.
Definition: texture.h:255
Definition: ImathVec.h:32
Wrap
Definition: texture.h:82
GT_API const UT_StringHolder time
int samples
Number of samples for shadows.
Definition: texture.h:264
int subimage
Subimage or face ID.
Definition: texture.h:247
static void parse_wrapmodes(const char *wrapmodes, TextureOpt::Wrap &swrapcode, TextureOpt::Wrap &twrapcode)
Definition: texture.h:291
OIIO_INLINE_CONSTEXPR int BatchWidth
Definition: texture.h:137
DEPRECATED Stochastic trilinear.
Force bilinear lookup within a mip level.
GLint level
Definition: glcorearb.h:108
Use two MIPmap levels w/ anisotropic.
DEPRECATED Stochastic anisotropic.
Definition: texture.h:214
virtual ~TextureSystem()
Definition: texture.h:1865
GLdouble s
Definition: glad.h:3009
unsigned char Runflag
Definition: texture.h:175
**But if you need a or simply need to know when the task has note that the like this
Definition: thread.h:626
Force closest texel.
int anisotropic
Maximum anisotropic ratio.
Definition: texture.h:253
Use two MIPmap levels (trilinear)
#define OIIO_DEPRECATED(msg)
Definition: platform.h:466
**But if you need a result
Definition: thread.h:622
Periodic mod 1.
OIIO_INLINE_CONSTEXPR int BatchAlign
Definition: texture.h:138
void close() override
static Wrap decode_wrapmode(const char *name)
Definition: texture.h:275
Wrap swrap
Wrap mode in the s direction.
Definition: texture.h:249
Force cubic lookup within a mip level.
Definition: texture.h:222
Clamp to [0..1].
simd::VecType< int, OIIO_TEXTURE_SIMD_BATCH_WIDTH >::type IntWide
A type alias for a SIMD vector of ints with the batch width.
Definition: texture.h:144
Periodic mod 1.
Definition: texture.h:198
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1860
Default high-quality lookup.
Definition: texture.h:208
MipMode mipmode
Mip mode.
Definition: texture.h:251
uint64_t RunMask
Definition: texture.h:151
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Periodic mod 1.
Definition: texture.h:368
Mirror the image.
Definition: texture.h:369
Wrap twrap
Wrap mode in the t direction.
Definition: texture.h:250
OIIO_API void parse_wrapmodes(const char *wrapmodes, Wrap &swrapcode, Wrap &twrapcode)
Mirror the image.
Definition: texture.h:199
Periodic with shared border (env)
Definition: texture.h:371
#define OIIO_TEXTURE_SIMD_BATCH_WIDTH
Definition: texture.h:131
int firstchannel
First channel of the lookup.
Definition: texture.h:246
Just use highest-res image, no MIP mapping.
Use two MIPmap levels (trilinear)
Definition: texture.h:211
float fill
Fill value for missing channels.
Definition: texture.h:257
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
Black outside [0..1].
Definition: texture.h:196
GLint GLuint mask
Definition: glcorearb.h:124
static void parse_wrapmodes(const char *wrapmodes, TextureOptions::Wrap &swrapcode, TextureOptions::Wrap &twrapcode)
Definition: texture.h:447
Default high-quality lookup.
simd::VecType< float, OIIO_TEXTURE_SIMD_BATCH_WIDTH >::type FloatWide
A type alias for a SIMD vector of floats with the batch width.
Definition: texture.h:141
Mark the end – don't use this!
GLuint const GLchar * name
Definition: glcorearb.h:786
Force bilinear lookup within a mip level.
Definition: texture.h:221
TextureSystem(void)
Definition: texture.h:1873
GLdouble t
Definition: glad.h:2397
ustring subimagename
Subimage name.
Definition: texture.h:248
GLsizei samples
Definition: glcorearb.h:1298
InterpMode interpmode
Interpolation mode.
Definition: texture.h:252
int colortransformid
Color space id of the texture.
Definition: texture.h:271
float rblur
Blur amount in the r direction.
Definition: texture.h:268
Mirror the image.
float rwidth
Multiplier for derivatives in r direction.
Definition: texture.h:269
Default high-quality lookup.
Definition: texture.h:378
Force cubic lookup within a mip level.
Definition: texture.h:390
Wrap rwrap
Wrap mode in the r direction.
Definition: texture.h:267
Use two MIPmap levels (trilinear)
Definition: texture.h:381
Force bilinear lookup within a mip level.
Definition: texture.h:389
OIIO_API bool getattribute(string_view name, TypeDesc type, void *val)
Bicubic when magnifying, else bilinear.
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
Just use highest-res image, no MIP mapping.
Definition: texture.h:209
const float * missingcolor
Color for missing texture.
Definition: texture.h:258
Texture options for a batch of Tex::BatchWidth points and run mask.
Definition: texture.h:309
static Wrap decode_wrapmode(ustringhash name)
Definition: texture.h:283
Force closest texel.
Definition: texture.h:388
InterpMode
Definition: texture.h:120
SIM_API const UT_StringHolder force
Use two MIPmap levels w/ anisotropic.
Definition: texture.h:212
Clamp to [0..1].
Definition: texture.h:367
float bias
Bias for shadows (DEPRECATED)
Definition: texture.h:261
DEPRECATED Stochastic trilinear.
Definition: texture.h:213
GLuint index
Definition: glcorearb.h:786
TextureHandle * get_texture_handle(const std::wstring &filename, Perthread *thread_info=nullptr, const TextureOpt *options=nullptr)
Get a TextureHandle using a UTF-16 encoded wstring filename.
Definition: texture.h:822
GLuint GLfloat * val
Definition: glcorearb.h:1608
static Wrap decode_wrapmode(ustring name)
Definition: texture.h:279
bool conservative_filter
True == over-blur rather than alias.
Definition: texture.h:254
Force cubic lookup within a mip level.
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
Use the default found in the file.
Definition: texture.h:365
TextureOpt()
Definition: texture.h:229
GLuint texture
Definition: glcorearb.h:415
static Wrap decode_wrapmode(ustringhash name)
Definition: texture.h:439
OutGridT XformOp bool bool shared
Black outside [0..1].
Definition: texture.h:366
EnvLayout
Definition: texture.h:66
Periodic, but only for powers of 2!!!
Definition: texture.h:370
Force closest texel.
Definition: texture.h:220
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
float time
Time (for time-dependent texture lookups)
Definition: texture.h:259
Use just one mipmap level.
Classes for SIMD processing.
TexFormat
Definition: texture.h:54
Black outside [0..1].
std::string OIIO_UTIL_API utf16_to_utf8(const std::wstring &utf16str) noexcept
static Wrap decode_wrapmode(ustring name)
Definition: texture.h:435
DEPRECATED Stochastic anisotropic.
ustring subimagename
Subimage name.
Definition: texture.h:331
Periodic with shared border (env)
OIIO_API Wrap decode_wrapmode(const char *name)
Use the default found in the file.
Definition: texture.h:195
Definition: format.h:1821
Use the default found in the file.
Use just one mipmap level.
Definition: texture.h:380
Just use highest-res image, no MIP mapping.
Definition: texture.h:379
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126
#define OIIO_API
Definition: export.h:65