1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4 
5 // clang-format off
6 
7 
8 
9 #pragma once
10 
11 #include <OpenImageIO/imageio.h>
12 #include <OpenImageIO/ustring.h>
13 
14 
15 // Define symbols that let client applications determine if newly added
16 // features are supported.
17 
18 // Is the close() method present?
19 #define OIIO_IMAGECACHE_SUPPORTS_CLOSE 1
20 
21 // Does invalidate() support the optional `force` flag?
22 #define OIIO_IMAGECACHE_INVALIDATE_FORCE 1
23 
24 
25 
26 OIIO_NAMESPACE_BEGIN
27 
28 namespace pvt {
29 // Forward declaration
30 class ImageCacheImpl;
31 class ImageCacheFile;
32 class ImageCachePerThreadInfo;
33 };  // namespace pvt
34 
35 
36 
37 /// Define an API to an abstract class that manages image files,
38 /// caches of open file handles as well as tiles of pixels so that truly
39 /// huge amounts of image data may be accessed by an application with low
40 /// memory footprint.
41 class OIIO_API ImageCache {
42 public:
43     /// @{
44     /// @name Creating and destroying an image cache
45     ///
46     /// ImageCache is an abstract API described as a pure virtual class.
47     /// The actual internal implementation is not exposed through the
48     /// external API of OpenImageIO.  Because of this, you cannot construct
49     /// or destroy the concrete implementation, so two static methods of
50     /// ImageCache are provided:
51 
52     /// Create a ImageCache and return a raw pointer to it.  This should
53     /// only be freed by passing it to `ImageCache::destroy()`!
54     ///
55     /// @param  shared
56     ///     If `true`, the pointer returned will be a shared ImageCache (so
57     ///     that multiple parts of an application that request an ImageCache
58     ///     will all end up with the same one). If `shared` is `false`, a
59     ///     completely unique ImageCache will be created and returned.
60     ///
61     /// @returns
62     ///     A raw pointer to an ImageCache, which can only be freed with
63     ///     `ImageCache::destroy()`.
64     ///
65     /// @see    ImageCache::destroy
66     static ImageCache* create(bool shared = true);
67 
68     /// Destroy an allocated ImageCache, including freeing all system
69     /// resources that it holds.
70     ///
71     /// It is safe to destroy even a shared ImageCache, as the implementation
72     /// of `destroy()` will recognize a shared one and only truly release
73     /// its resources if it has been requested to be destroyed as many times as
74     /// shared ImageCache's were created.
75     ///
76     /// @param  cache
77     ///     Raw pointer to the ImageCache to destroy.
78     ///
79     /// @param  teardown
80     ///     For a shared ImageCache, if the `teardown` parameter is
81     ///     `true`, it will try to truly destroy the shared cache if
82     ///     nobody else is still holding a reference (otherwise, it will
83     ///     leave it intact). This parameter has no effect if `cache` was
84     ///     not the single globally shared ImageCache.
85     static void destroy(ImageCache* cache, bool teardown = false);
86 
87     /// @}
88 
89 
90     /// @{
91     /// @name Setting options and limits for the image cache
92     ///
93     /// These are the list of attributes that can bet set or queried by
94     /// attribute/getattribute:
95     ///
96     /// - `int max_open_files` :
97     ///           The maximum number of file handles that the image cache
98     ///           will hold open simultaneously.  (Default = 100)
99     /// - `float max_memory_MB` :
100     ///           The maximum amount of memory (measured in MB) used for the
101     ///           internal "tile cache." (Default: 256.0 MB)
102     /// - `string searchpath` :
103     ///           The search path for images: a colon-separated list of
104     ///           directories that will be searched in order for any image
105     ///           filename that is not specified as an absolute path.
106     ///           (Default: "")
107     /// - `string plugin_searchpath` :
108     ///           The search path for plugins: a colon-separated list of
109     ///           directories that will be searched in order for any OIIO
110     ///           plugins, if not found in OIIO's `lib` directory.
111     ///           (Default: "")
112     /// - `int autotile` ,
113     ///   `int autoscanline` :
114     ///           These attributes control how the image cache deals with
115     ///           images that are not "tiled" (i.e., are stored as
116     ///           scanlines).
117     ///
118     ///           If `autotile` is set to 0 (the default), an untiled image
119     ///           will be treated as if it were a single tile of the
120     ///           resolution of the whole image.  This is simple and fast,
121     ///           but can lead to poor cache behavior if you are
122     ///           simultaneously accessing many large untiled images.
123     ///
124     ///           If `autotile` is nonzero (e.g., 64 is a good recommended
125     ///           value), any untiled images will be read and cached as if
126     ///           they were constructed in tiles of size:
127     ///
128     ///               - `autotile * autotile`
129     ///                     if `autoscanline` is 0
130     ///               - `width * autotile`
131     ///                     if `autoscanline` is nonzero.
132     ///
133     ///           In both cases, this should lead more efficient caching.
134     ///           The `autoscanline` determines whether the "virtual tiles"
135     ///           in the cache are square (if `autoscanline` is 0, the
136     ///           default) or if they will be as wide as the image (but only
137     ///           `autotile` scanlines high).  You should try in your
138     ///           application to see which leads to higher performance.
139     /// - `int autoscanline` :
140     ///           autotile using full width tiles
141     /// - `int automip` :
142     ///           If 0 (the default), an untiled single-subimage file will
143     ///           only be able to utilize that single subimage.
144     ///           If nonzero, any untiled, single-subimage (un-MIP-mapped)
145     ///           images will have lower-resolution MIP-map levels generated
146     ///           on-demand if pixels are requested from the lower-res
147     ///           subimages (that don't really exist). Essentially this
148     ///           makes the ImageCache pretend that the file is MIP-mapped
149     ///           even if it isn't.
150     /// - `int accept_untiled` :
151     ///           When nonzero, ImageCache accepts untiled images as usual.
152     ///           When zero, ImageCache will reject untiled images with an
153     ///           error condition, as if the file could not be properly
154     ///           read. This is sometimes helpful for applications that want
155     ///           to enforce use of tiled images only. (default=1)
156     /// - `int accept_unmipped` :
157     ///           When nonzero, ImageCache accepts un-MIPmapped images as
158     ///           usual.  When set to zero, ImageCache will reject
159     ///           un-MIPmapped images with an error condition, as if the
160     ///           file could not be properly read. This is sometimes helpful
161     ///           for applications that want to enforce use of MIP-mapped
162     ///           images only. (Default: 1)
163     /// - `int statistics:level` :
164     ///           verbosity of statistics auto-printed.
165     /// - `int forcefloat` :
166     ///           If set to nonzero, all image tiles will be converted to
167     ///           `float` type when stored in the image cache.  This can be
168     ///           helpful especially for users of ImageBuf who want to
169     ///           simplify their image manipulations to only need to
170     ///           consider `float` data. The default is zero, meaning that
171     ///           image pixels are not forced to be `float` when in cache.
172     /// - `int failure_retries` :
173     ///           When nonzero (the default), ImageCache accepts
174     ///           un-MIPmapped images as usual.  When set to zero,
175     ///           ImageCache will reject un-MIPmapped images with an error
176     ///           condition, as if the file could not be properly read. This
177     ///           is sometimes helpful for applications that want to enforce
178     ///           use of MIP-mapped images only. (Default: 1)
179     /// - `int deduplicate` :
180     ///           When nonzero, the ImageCache will notice duplicate images
181     ///           under different names if their headers contain a SHA-1
182     ///           fingerprint (as is done with `maketx`-produced textures)
183     ///           and handle them more efficiently by avoiding redundant
184     ///           reads.  The default is 1 (de-duplication turned on). The
185     ///           only reason to set it to 0 is if you specifically want to
186     ///           disable the de-duplication optimization.
187     /// - `string substitute_image` :
188     ///           When set to anything other than the empty string, the
189     ///           ImageCache will use the named image in place of *all*
190     ///           other images.  This allows you to run an app using OIIO
191     ///           and (if you can manage to get this option set)
192     ///           automagically substitute a grid, zone plate, or other
193     ///           special debugging image for all image/texture use.
194     /// - `int unassociatedalpha` :
195     ///           When nonzero, will request that image format readers try
196     ///           to leave input images with unassociated alpha as they are,
197     ///           rather than automatically converting to associated alpha
198     ///           upon reading the pixels.  The default is 0, meaning that
199     ///           the automatic conversion will take place.
200     /// - `int max_errors_per_file` :
201     ///           The maximum number of errors that will be printed for each
202     ///           file. The default is 100. If your output is cluttered with
203     ///           error messages and after the first few for each file you
204     ///           aren't getting any helpful additional information, this
205     ///           can cut down on the clutter and the runtime. (default:
206     ///           100)
207     /// - `int trust_file_extensions` :
208     ///           When nonzero, assume that the file extensions of any
209     ///           texture requests correctly indicates the file format (when
210     ///           enabled, this reduces the number of file opens, at the
211     ///           expense of not being able to open files if their format do
212     ///           not actually match their filename extension). Default: 0
213     ///
214     /// - `string options`
215     ///           This catch-all is simply a comma-separated list of
216     ///           `name=value` settings of named options, which will be
217     ///           parsed and individually set. Example:
218     ///
219     ///                ic->attribute ("options", "max_memory_MB=512.0,autotile=1");
220     ///
221     ///           Note that if an option takes a string value that must
222     ///           itself contain a comma, it is permissible to enclose the
223     ///           value in either single (` ' ' `) or double (` " " `) quotes.
224     ///
225     /// **Read-only attributes**
226     ///
227     /// Additionally, there are some read-only attributes that can be
228     /// queried with `getattribute()` even though they cannot be set via
229     /// `attribute()`:
230     ///
231     /// - `int total_files` :
232     ///           The total number of unique file names referenced by calls
233     ///           to the ImageCache.
234     ///
235     /// - `string[] all_filenames` :
236     ///           An array that will be filled with the list of the names of
237     ///           all files referenced by calls to the ImageCache. (The
238     ///           array is of `ustring` or `char*`.)
239     ///
240     /// - `int64 stat:cache_memory_used` :
241     ///           Total bytes used by tile cache.
242     ///
243     /// - `int stat:tiles_created` ,
244     ///   `int stat:tiles_current` ,
245     ///   `int stat:tiles_peak` :
246     ///           Total times created, still allocated (at the time of the
247     ///           query), and the peak number of tiles in memory at any
248     ///           time.
249     ///
250     /// - `int stat:open_files_created` ,
251     ///   `int stat:open_files_current` ,
252     ///   `int stat:open_files_peak` :
253     ///           Total number of times a file was opened, number still
254     ///           opened (at the time of the query), and the peak number of
255     ///           files opened at any time.
256     ///
257     /// - `int stat:find_tile_calls` :
258     ///           Number of times a filename was looked up in the file cache.
259     ///
260     /// - `int64 stat:image_size` :
261     ///           Total size (uncompressed bytes of pixel data) of all
262     ///           images referenced by the ImageCache. (Note: Prior to 1.7,
263     ///           this was called `stat:files_totalsize`.)
264     ///
265     /// - `int64 stat:file_size` :
266     ///           Total size of all files (as on disk, possibly compressed)
267     ///           of all images referenced by the ImageCache.
268     ///
269     /// - `int64 stat:bytes_read` :
270     ///           Total size (uncompressed bytes of pixel data) read.
271     ///
272     /// - `int stat:unique_files` :
273     ///           Number of unique files opened.
274     ///
275     /// - `float stat:fileio_time` :
276     ///           Total I/O-related time (seconds).
277     ///
278     /// - `float stat:fileopen_time` :
279     ///           I/O time related to opening and reading headers (but not
280     ///           pixel I/O).
281     ///
282     /// - `float stat:file_locking_time` :
283     ///           Total time (across all threads) that threads blocked
284     ///           waiting for access to the file data structures.
285     ///
286     /// - `float stat:tile_locking_time` :
287     ///           Total time (across all threads) that threads blocked
288     ///           waiting for access to the tile cache data structures.
289     ///
290     /// - `float stat:find_file_time` :
291     ///           Total time (across all threads) that threads spent looking
292     ///           up files by name.
293     ///
294     /// - `float stat:find_tile_time` :
295     ///           Total time (across all threads) that threads spent looking
296     ///           up individual tiles.
297     ///
298     /// The following member functions of ImageCache allow you to set (and
299     /// in some cases retrieve) options that control the overall behavior of
300     /// the image cache:
301 
302     /// Set a named attribute (i.e., a property or option) of the
303     /// ImageCache.
304     ///
305     /// Example:
306     ///
307     ///     ImageCache *ic;
308     ///     ...
309     ///     int maxfiles = 50;
310     ///     ic->attribute ("max_open_files", TypeDesc::INT, &maxfiles);
311     ///
312     ///     const char *path = "/my/path";
313     ///     ic->attribute ("searchpath", TypeDesc::STRING, &path);
314     ///
315     ///     // There are specialized versions for setting a single int,
316     ///     // float, or string without needing types or pointers:
317     ///     ic->attribute ("max_open_files", 50);
318     ///     ic->attribute ("max_memory_MB", 4000.0f);
319     ///     ic->attribute ("searchpath", "/my/path");
320     ///
321     /// Note: When passing a string, you need to pass a pointer to the
322     /// `char*`, not a pointer to the first character.  (Rationale: for an
323     /// `int` attribute, you pass the address of the `int`.  So for a
324     /// string, which is a `char*`, you need to pass the address of the
325     /// string, i.e., a `char**`).
326     ///
327     /// @param  name    Name of the attribute to set.
328     /// @param  type    TypeDesc describing the type of the attribute.
329     /// @param  val     Pointer to the value data.
330     /// @returns        `true` if the name and type were recognized and the
331     ///                 attribute was set, or `false` upon failure
332     ///                 (including it being an unrecognized attribute or not
333     ///                 of the correct type).
334     ///
335     virtual bool attribute (string_view name, TypeDesc type,
336                             const void *val) = 0;
337 
338     /// Specialized `attribute()` for setting a single `int` value.
339     virtual bool attribute (string_view name, int val) = 0;
340     /// Specialized `attribute()` for setting a single `float` value.
341     virtual bool attribute (string_view name, float val) = 0;
342     virtual bool attribute (string_view name, double val) = 0;
343     /// Specialized `attribute()` for setting a single string value.
344     virtual bool attribute (string_view name, string_view val) = 0;
345 
346     /// Get the named attribute, store it in `*val`. All of the attributes
347     /// that may be set with the `attribute() call` may also be queried with
348     /// `getattribute()`.
349     ///
350     /// Examples:
351     ///
352     ///     ImageCache *ic;
353     ///     ...
354     ///     int maxfiles;
355     ///     ic->getattribute ("max_open_files", TypeDesc::INT, &maxfiles);
356     ///
357     ///     const char *path;
358     ///     ic->getattribute ("searchpath", TypeDesc::STRING, &path);
359     ///
360     ///     // There are specialized versions for retrieving a single int,
361     ///     // float, or string without needing types or pointers:
362     ///     int maxfiles;
363     ///     ic->getattribute ("max_open_files", maxfiles);
364     ///     const char *path;
365     ///     ic->getattribute ("searchpath", &path);
366     ///
367     /// Note: When retrieving a string, you need to pass a pointer to the
368     /// `char*`, not a pointer to the first character. Also, the `char*`
369     /// will end up pointing to characters owned by the ImageCache; the
370     /// caller does not need to ever free the memory that contains the
371     /// characters.
372     ///
373     /// @param  name    Name of the attribute to retrieve.
374     /// @param  type    TypeDesc describing the type of the attribute.
375     /// @param  val     Pointer where the attribute value should be stored.
376     /// @returns        `true` if the name and type were recognized and the
377     ///                 attribute was retrieved, or `false` upon failure
378     ///                 (including it being an unrecognized attribute or not
379     ///                 of the correct type).
380     virtual bool getattribute (string_view name, TypeDesc type,
381                                void *val) const = 0;
382 
383     /// Specialized `attribute()` for retrieving a single `int` value.
384     virtual bool getattribute (string_view name, int &val) const = 0;
385     /// Specialized `attribute()` for retrieving a single `float` value.
386     virtual bool getattribute (string_view name, float &val) const = 0;
387     virtual bool getattribute (string_view name, double &val) const = 0;
388     /// Specialized `attribute()` for retrieving a single `string` value
389     /// as a `char*`.
390     virtual bool getattribute (string_view name, char **val) const = 0;
391     /// Specialized `attribute()` for retrieving a single `string` value
392     /// as a `std::string`.
393     virtual bool getattribute (string_view name, std::string &val) const = 0;
394 
395     /// @}
396 
397 
398     /// @{
399     /// @name Opaque data for performance lookups
400     ///
401     /// The ImageCache implementation needs to maintain certain per-thread
402     /// state, and some methods take an opaque `Perthread` pointer to this
403     /// record. There are three options for how to deal with it:
404     ///
405     /// 1. Don't worry about it at all: don't use the methods that want
406     ///    `Perthread` pointers, or always pass `nullptr` for any
407     ///    `Perthread*1 arguments, and ImageCache will do
408     ///    thread-specific-pointer retrieval as necessary (though at some
409     ///    small cost).
410     ///
411     /// 2. If your app already stores per-thread information of its own, you
412     ///    may call `get_perthread_info(nullptr)` to retrieve it for that
413     ///    thread, and then pass it into the functions that allow it (thus
414     ///    sparing them the need and expense of retrieving the
415     ///    thread-specific pointer). However, it is crucial that this
416     ///    pointer not be shared between multiple threads. In this case, the
417     ///    ImageCache manages the storage, which will automatically be
418     ///    released when the thread terminates.
419     ///
420     /// 3. If your app also wants to manage the storage of the `Perthread`,
421     ///    it can explicitly create one with `create_perthread_info()`, pass
422     ///    it around, and eventually be responsible for destroying it with
423     ///    `destroy_perthread_info()`. When managing the storage, the app
424     ///    may reuse the `Perthread` for another thread after the first is
425     ///    terminated, but still may not use the same `Perthread` for two
426     ///    threads running concurrently.
427 
428     /// Define an opaque data type that allows us to have a pointer to
429     /// certain per-thread information that the ImageCache maintains. Any
430     /// given one of these should NEVER be shared between running threads.
431     typedef pvt::ImageCachePerThreadInfo Perthread;
432 
433     /// Retrieve a Perthread, unique to the calling thread. This is a
434     /// thread-specific pointer that will always return the Perthread for a
435     /// thread, which will also be automatically destroyed when the thread
436     /// terminates.
437     ///
438     /// Applications that want to manage their own Perthread pointers (with
439     /// `create_thread_info` and `destroy_thread_info`) should still call
440     /// this, but passing in their managed pointer. If the passed-in
441     /// thread_info is not NULL, it won't create a new one or retrieve a
442     /// TSP, but it will do other necessary housekeeping on the Perthread
443     /// information.
444     virtual Perthread* get_perthread_info(Perthread* thread_info = NULL) = 0;
445 
446     /// Create a new Perthread. It is the caller's responsibility to
447     /// eventually destroy it using `destroy_thread_info()`.
448     virtual Perthread* create_thread_info() = 0;
449 
450     /// Destroy a Perthread that was allocated by `create_thread_info()`.
451     virtual void destroy_thread_info(Perthread* thread_info) = 0;
452 
453     /// Define an opaque data type that allows us to have a handle to an
454     /// image (already having its name resolved) but without exposing any
455     /// internals.
456     typedef pvt::ImageCacheFile ImageHandle;
457 
458     /// Retrieve an opaque handle for fast image lookups.  The opaque
459     /// `pointer thread_info` is thread-specific information returned by
460     /// `get_perthread_info()`.  Return NULL if something has gone horribly
461     /// wrong.
462     virtual ImageHandle* get_image_handle (ustring filename,
463                                             Perthread *thread_info=NULL) = 0;
464 
465     /// Return true if the image handle (previously returned by
466     /// `get_image_handle()`) is a valid image that can be subsequently read.
467     virtual bool good(ImageHandle* file) = 0;
468 
469     /// @}
470 
471 
472     /// @{
473     /// @name   Getting information about images
474     ///
475 
476     /// Given possibly-relative `filename`, resolve it and use the true path
477     /// to the file, with searchpath logic applied.
478     virtual std::string resolve_filename(const std::string& filename) const = 0;
479 
480     /// Get information or metadata about the named image and store it in
481     /// `*data`.
482     ///
483     /// Data names may include any of the following:
484     ///
485     /// - `"exists"` : Stores the value 1 (as an `int`) if the file exists and
486     ///   is an image format that OpenImageIO can read, or 0 if the file
487     ///   does not exist, or could not be properly read as an image. Note
488     ///   that unlike all other queries, this query will "succeed" (return
489     ///   `true`) even if the file does not exist.
490     ///
491     /// - `"udim"` : Stores the value 1 (as an `int`) if the file is a
492     ///   "virtual UDIM" or texture atlas file (as described in
493     ///   :ref:`sec-texturesys-udim`) or 0 otherwise.
494     ///
495     /// - `"subimages"` : The number of subimages in the file, as an `int`.
496     ///
497     /// - `"resolution"` : The resolution of the image file, which is an
498     ///   array of 2 integers (described as `TypeDesc(INT,2)`).
499     ///
500     /// - `"miplevels"` : The number of MIPmap levels for the specified
501     ///   subimage (an integer).
502     ///
503     /// - `"texturetype"` : A string describing the type of texture of the
504     ///   given file, which describes how the texture may be used (also
505     ///   which texture API call is probably the right one for it). This
506     ///   currently may return one of: `"unknown"`, `"Plain Texture"`,
507     ///   `"Volume Texture"`, `"Shadow"`, or `"Environment"`.
508     ///
509     /// - `"textureformat"` : A string describing the format of the given
510     ///   file, which describes the kind of texture stored in the file. This
511     ///   currently may return one of: `"unknown"`, `"Plain Texture"`,
512     ///   `"Volume Texture"`, `"Shadow"`, `"CubeFace Shadow"`,
513     ///   `"Volume Shadow"`, `"LatLong Environment"`, or
514     ///   `"CubeFace Environment"`. Note that there are several kinds of
515     ///   shadows and environment maps, all accessible through the same API
516     ///   calls.
517     ///
518     /// - `"channels"` : The number of color channels in the file (an
519     ///   `int`).
520     ///
521     /// - `"format"` : The native data format of the pixels in the file (an
522     ///   integer, giving the `TypeDesc::BASETYPE` of the data). Note that
523     ///   this is not necessarily the same as the data format stored in the
524     ///   image cache.
525     ///
526     /// - `"cachedformat"` : The native data format of the pixels as stored
527     ///   in the image cache (an integer, giving the `TypeDesc::BASETYPE` of
528     ///   the data).  Note that this is not necessarily the same as the
529     ///   native data format of the file.
530     ///
531     /// - `"datawindow"` : Returns the pixel data window of the image, which
532     ///   is either an array of 4 integers (returning xmin, ymin, xmax,
533     ///   ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax,
534     ///   ymax, zmax). The z values may be useful for 3D/volumetric images;
535     ///   for 2D images they will be 0).
536     ///
537     /// - `"displaywindow"` : Returns the display (a.k.a. "full") window of
538     ///   the image, which is either an array of 4 integers (returning xmin,
539     ///   ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin,
540     ///   zmin, xmax, ymax, zmax). The z values may be useful for
541     ///   3D/volumetric images; for 2D images they will be 0).
542     ///
543     /// - `"worldtocamera"` : The viewing matrix, which is a 4x4 matrix (an
544     ///   `Imath::M44f`, described as `TypeDesc(FLOAT,MATRIX)`), giving the
545     ///   world-to-camera 3D transformation matrix that was used when  the
546     ///   image was created. Generally, only rendered images will have this.
547     ///
548     /// - `"worldtoscreen"` : The projection matrix, which is a 4x4 matrix
549     ///   (an `Imath::M44f`, described as `TypeDesc(FLOAT,MATRIX)`), giving
550     ///   the matrix that projected points from world space into a 2D screen
551     ///   coordinate system where $x$ and $y$ range from -1 to +1.
552     ///   Generally, only rendered images will have this.
553     ///
554     /// - `"worldtoNDC"` : The projection matrix, which is a 4x4 matrix
555     ///   (an `Imath::M44f`, described as `TypeDesc(FLOAT,MATRIX)`), giving
556     ///   the matrix that projected points from world space into a 2D NDC
557     ///   coordinate system where $x$ and $y$ range from 0 to +1. Generally,
558     ///   only rendered images will have this.
559     ///
560     /// - `"averagecolor"` : If available in the metadata (generally only
561     ///   for files that have been processed by `maketx`), this will return
562     ///   the average color of the texture (into an array of `float`).
563     ///
564     /// - `"averagealpha"` : If available in the metadata (generally only
565     ///   for files that have been processed by `maketx`), this will return
566     ///   the average alpha value of the texture (into a `float`).
567     ///
568     /// - `"constantcolor"` : If the metadata (generally only for files that
569     ///   have been processed by `maketx`) indicates that the texture has
570     ///   the same values for all pixels in the texture, this will retrieve
571     ///   the constant color of the texture (into an array of floats). A
572     ///   non-constant image (or one that does not have the special metadata
573     ///   tag identifying it as a constant texture) will fail this query
574     ///   (return `false`).
575     ///
576     /// - `"constantalpha"` : If the metadata indicates that the texture has
577     ///   the same values for all pixels in the texture, this will retrieve
578     ///   the constant alpha value of the texture (into a float). A
579     ///   non-constant image (or one that does not have the special metadata
580     ///   tag identifying it as a constant texture) will fail this query
581     ///   (return `false`).
582     ///
583     /// - `"stat:tilesread"` : Number of tiles read from this file
584     ///   (`int64`).
585     ///
586     /// - `"stat:bytesread"` : Number of bytes of uncompressed pixel data
587     ///   read from this file (`int64`).
588     ///
589     /// - `"stat:redundant_tiles"` : Number of times a tile was read, where
590     ///   the same tile had been rad before. (`int64`).
591     ///
592     /// - `"stat:redundant_bytesread"` : Number of bytes (of uncompressed
593     ///   pixel data) in tiles that were read redundantly. (`int64`).
594     ///
595     /// - `"stat:redundant_bytesread"` : Number of tiles read from this file (`int`).
596     ///
597     /// - `"stat:image_size"` : Size of the uncompressed image pixel data
598     /// of this image, in bytes (`int64`).
599     ///
600     /// - `"stat:file_size"` : Size of the disk file (possibly compressed)
601     ///   for this image, in bytes (`int64`).
602     ///
603     /// - `"stat:timesopened"` : Number of times this file was opened
604     ///   (`int`).
605     ///
606     /// - `"stat:iotime"` : Time (in seconds) spent on all I/O for this file
607     ///   (`float`).
608     ///
609     /// - `"stat:mipsused"` : Stores 1 if any MIP levels beyond the highest
610     ///   resolution were accessed, otherwise 0. (`int`)
611     ///
612     /// - `"stat:is_duplicate"` : Stores 1 if this file was a duplicate of
613     ///   another image, otherwise 0. (`int`)
614     ///
615     /// - *Anything else*  : For all other data names, the the metadata of
616     ///   the image file will be searched for an item that matches both the
617     ///   name and data type.
618     ///
619     ///
620     ///
621     /// @param  filename
622     ///             The name of the image.
623     /// @param  subimage/miplevel
624     ///             The subimage and MIP level to query.
625     /// @param  dataname
626     ///             The name of the metadata to retrieve.
627     /// @param  datatype
628     ///             TypeDesc describing the data type.
629     /// @param  data
630     ///             Pointer to the caller-owned memory where the values
631     ///             should be stored. It is the caller's responsibility to
632     ///             ensure that `data` points to a large enough storage area
633     ///             to accommodate the `datatype` requested.
634     ///
635     /// @returns
636     ///             `true` if `get_image_info()` is able to find the
637     ///             requested `dataname` for the image and it matched the
638     ///             requested `datatype`.  If the requested data was not
639     ///             found or was not of the right data type, return `false`.
640     ///             Except for the `"exists"` query, a file that does not
641     ///             exist or could not be read properly as an image also
642     ///             constitutes a query failure that will return `false`.
643     virtual bool get_image_info (ustring filename, int subimage, int miplevel,
644                          ustring dataname, TypeDesc datatype, void *data) = 0;
645     /// A more efficient variety of `get_image_info()` for cases where you
646     /// can use an `ImageHandle*` to specify the image and optionally have a
647     /// `Perthread*` for the calling thread.
648     virtual bool get_image_info (ImageHandle *file, Perthread *thread_info,
649                          int subimage, int miplevel,
650                          ustring dataname, TypeDesc datatype, void *data) = 0;
651 
652     /// Copy the ImageSpec associated with the named image (the first
653     /// subimage & miplevel by default, or as set by `subimage` and
654     /// `miplevel`).
655     ///
656     /// @param  filename
657     ///             The name of the image.
658     /// @param  spec
659     ///             ImageSpec into which will be copied the spec for the
660     ///             requested image.
661     /// @param  subimage/miplevel
662     ///             The subimage and MIP level to query.
663     /// @param  native
664     ///             If `false` (the default), then the spec retrieved will
665     ///             accurately describe the image stored internally in the
666     ///             cache, whereas if `native` is `true`, the spec retrieved
667     ///             will reflect the contents of the original file.  These
668     ///             may differ due to use of certain ImageCache settings
669     ///             such as `"forcefloat"` or `"autotile"`.
670     /// @returns
671     ///             `true` upon success, `false` upon failure failure (such
672     ///             as being unable to find, open, or read the file, or if
673     ///             it does not contain the designated subimage or MIP
674     ///             level).
675     virtual bool get_imagespec (ustring filename, ImageSpec &spec,
676                                 int subimage=0, int miplevel=0,
677                                 bool native=false) = 0;
678     /// A more efficient variety of `get_imagespec()` for cases where you
679     /// can use an `ImageHandle*` to specify the image and optionally have a
680     /// `Perthread*` for the calling thread.
681     virtual bool get_imagespec (ImageHandle *file, Perthread *thread_info,
682                                 ImageSpec &spec,
683                                 int subimage=0, int miplevel=0,
684                                 bool native=false) = 0;
685 
686     /// Return a pointer to an ImageSpec associated with the named image
687     /// (the first subimage & MIP level by default, or as set by `subimage`
688     /// and `miplevel`) if the file is found and is an image format that can
689     /// be read, otherwise return `nullptr`.
690     ///
691     /// This method is much more efficient than `get_imagespec()`, since it
692     /// just returns a pointer to the spec held internally by the ImageCache
693     /// (rather than copying the spec to the user's memory). However, the
694     /// caller must beware that the pointer is only valid as long as nobody
695     /// (even other threads) calls `invalidate()` on the file, or
696     /// `invalidate_all()`, or destroys the ImageCache.
697     ///
698     /// @param  filename
699     ///             The name of the image.
700     /// @param  subimage/miplevel
701     ///             The subimage and MIP level to query.
702     /// @param  native
703     ///             If `false` (the default), then the spec retrieved will
704     ///             accurately describe the image stored internally in the
705     ///             cache, whereas if `native` is `true`, the spec retrieved
706     ///             will reflect the contents of the original file.  These
707     ///             may differ due to use of certain ImageCache settings
708     ///             such as `"forcefloat"` or `"autotile"`.
709     /// @returns
710     ///             A pointer to the spec, if the image is found and able to
711     ///             be opened and read by an available image format plugin,
712     ///             and the designated subimage and MIP level exists.
713     virtual const ImageSpec *imagespec (ustring filename, int subimage=0,
714                                         int miplevel=0, bool native=false) = 0;
715     /// A more efficient variety of `imagespec()` for cases where you can
716     /// use an `ImageHandle*` to specify the image and optionally have a
717     /// `Perthread*` for the calling thread.
718     virtual const ImageSpec *imagespec (ImageHandle *file,
719                                         Perthread *thread_info,
720                                         int subimage=0, int miplevel=0,
721                                         bool native=false) = 0;
722     /// @}
723 
724     /// @{
725     /// @name   Getting Pixels
726 
727     /// For an image specified by name, retrieve the rectangle of pixels
728     /// from the designated subimage and MIP level, storing the pixel values
729     /// beginning at the address specified by `result` and with the given
730     /// strides.  The pixel values will be converted to the data type
731     /// specified by `format`. The rectangular region to be retrieved
732     /// includes `begin` but does not include `end` (much like STL begin/end
733     /// usage). Requested pixels that are not part of the valid pixel data
734     /// region of the image file will be filled with zero values.
735     ///
736     /// @param  filename
737     ///             The name of the image.
738     /// @param  subimage/miplevel
739     ///             The subimage and MIP level to retrieve pixels from.
740     /// @param  xbegin/xend/ybegin/yend/zbegin/zend
741     ///             The range of pixels to retrieve. The pixels retrieved
742     ///             include the begin value but not the end value (much like
743     ///             STL begin/end usage).
744     /// @param  chbegin/chend
745     ///             Channel range to retrieve. To retrieve all channels, use
746     ///             `chbegin = 0`, `chend = nchannels`.
747     /// @param  format
748     ///             TypeDesc describing the data type of the values you want
749     ///             to retrieve into `result`. The pixel values will be
750     ///             converted to this type regardless of how they were
751     ///             stored in the file.
752     /// @param  result
753     ///             Pointer to the memory where the pixel values should be
754     ///             stored.  It is up to the caller to ensure that `result`
755     ///             points to an area of memory big enough to accommodate
756     ///             the requested rectangle (taking into consideration its
757     ///             dimensions, number of channels, and data format).
758     /// @param  xstride/ystride/zstride
759     ///             The number of bytes between the beginning of successive
760     ///             pixels, scanlines, and image planes, respectively. Any
761     ///             stride values set to `AutoStride` will be assumed to
762     ///             indicate a contiguous data layout in that dimension.
763     /// @param  cache_chbegin/cache_chend These parameters can be used to
764     ///             tell the ImageCache to read and cache a subset of
765     ///             channels (if not specified or if they denote a
766     ///             non-positive range, all the channels of the file will be
767     ///             stored in the cached tile).
768     ///
769     /// @returns
770     ///             `true` for success, `false` for failure.
771     virtual bool get_pixels (ustring filename,
772                     int subimage, int miplevel, int xbegin, int xend,
773                     int ybegin, int yend, int zbegin, int zend,
774                     int chbegin, int chend, TypeDesc format, void *result,
775                     stride_t xstride=AutoStride, stride_t ystride=AutoStride,
776                     stride_t zstride=AutoStride,
777                     int cache_chbegin = 0, int cache_chend = -1) = 0;
778     /// A more efficient variety of `get_pixels()` for cases where you can
779     /// use an `ImageHandle*` to specify the image and optionally have a
780     /// `Perthread*` for the calling thread.
781     virtual bool get_pixels (ImageHandle *file, Perthread *thread_info,
782                     int subimage, int miplevel, int xbegin, int xend,
783                     int ybegin, int yend, int zbegin, int zend,
784                     int chbegin, int chend, TypeDesc format, void *result,
785                     stride_t xstride=AutoStride, stride_t ystride=AutoStride,
786                     stride_t zstride=AutoStride,
787                     int cache_chbegin = 0, int cache_chend = -1) = 0;
788 
789     /// A simplified `get_pixels()` where all channels are retrieved,
790     /// strides are assumed to be contiguous.
791     virtual bool get_pixels (ustring filename, int subimage, int miplevel,
792                              int xbegin, int xend, int ybegin, int yend,
793                              int zbegin, int zend,
794                              TypeDesc format, void *result) = 0;
795     /// A more efficient variety of `get_pixels()` for cases where you can
796     /// use an `ImageHandle*` to specify the image and optionally have a
797     /// `Perthread*` for the calling thread.
798     virtual bool get_pixels (ImageHandle *file, Perthread *thread_info,
799                              int subimage, int miplevel,
800                              int xbegin, int xend, int ybegin, int yend,
801                              int zbegin, int zend,
802                              TypeDesc format, void *result) = 0;
803     /// @}
804 
805     /// @{
806     /// @name Controlling the cache
807     ///
808 
809     /// Invalidate any loaded tiles or open file handles associated with the
810     /// filename, so that any subsequent queries will be forced to re-open
811     /// the file or re-load any tiles (even those that were previously
812     /// loaded and would ordinarily be reused).  A client might do this if,
813     /// for example, they are aware that an image being held in the cache
814     /// has been updated on disk.  This is safe to do even if other
815     /// procedures are currently holding reference-counted tile pointers
816     /// from the named image, but those procedures will not get updated
817     /// pixels until they release the tiles they are holding.
818     ///
819     /// If `force` is true, this invalidation will happen unconditionally;
820     /// if false, the file will only be invalidated if it has been changed
821     /// since it was first opened by the ImageCache.
822     virtual void invalidate(ustring filename, bool force = true) = 0;
823 
824     /// Invalidate all loaded tiles and close open file handles.  This is
825     /// safe to do even if other procedures are currently holding
826     /// reference-counted tile pointers from the named image, but those
827     /// procedures will not get updated pixels (if the images change) until
828     /// they release the tiles they are holding.
829     ///
830     /// If `force` is true, everything will be invalidated, no matter how
831     /// wasteful it is, but if `force` is false, in actuality files will
832     /// only be invalidated if their modification times have been changed
833     /// since they were first opened.
834     virtual void invalidate_all(bool force = false) = 0;
835 
836     /// Close any open file handles associated with a named file, but do not
837     /// invalidate any image spec information or pixels associated with the
838     /// files.  A client might do this in order to release OS file handle
839     /// resources, or to make it safe for other processes to modify image
840     /// files on disk.
841     virtual void close (ustring filename) = 0;
842 
843     /// `close()` all files known to the cache.
844     virtual void close_all () = 0;
845 
846     /// An opaque data type that allows us to have a pointer to a tile but
847     /// without exposing any internals.
848     class Tile;
849 
850     /// Find the tile specified by an image filename, subimage & miplevel,
851     /// the coordinates of a pixel, and optionally a channel range.   An
852     /// opaque pointer to the tile will be returned, or `nullptr` if no such
853     /// file (or tile within the file) exists or can be read.  The tile will
854     /// not be purged from the cache until after `release_tile()` is called
855     /// on the tile pointer the same number of times that `get_tile()` was
856     /// called (reference counting). This is thread-safe! If `chend <
857     /// chbegin`, it will retrieve a tile containing all channels in the
858     /// file.
859     virtual Tile * get_tile (ustring filename, int subimage, int miplevel,
860                              int x, int y, int z,
861                              int chbegin = 0, int chend = -1) = 0;
862     /// A slightly more efficient variety of `get_tile()` for cases where
863     /// you can use an `ImageHandle*` to specify the image and optionally
864     /// have a `Perthread*` for the calling thread.
865     ///
866     /// @see `get_pixels()`
867     virtual Tile * get_tile (ImageHandle *file, Perthread *thread_info,
868                              int subimage, int miplevel,
869                              int x, int y, int z,
870                              int chbegin = 0, int chend = -1) = 0;
871 
872     /// After finishing with a tile, release_tile will allow it to
873     /// once again be purged from the tile cache if required.
874     virtual void release_tile(Tile* tile) const = 0;
875 
876     /// Retrieve the data type of the pixels stored in the tile, which may
877     /// be different than the type of the pixels in the disk file.
878     virtual TypeDesc tile_format(const Tile* tile) const = 0;
879 
880     /// Retrieve the ROI describing the pixels and channels stored in the
881     /// tile.
882     virtual ROI tile_roi(const Tile* tile) const = 0;
883 
884     /// For a tile retrived by `get_tile()`, return a pointer to the pixel
885     /// data itself, and also store in `format` the data type that the
886     /// pixels are internally stored in (which may be different than the
887     /// data type of the pixels in the disk file).   This method should only
888     /// be called on a tile that has been requested by `get_tile()` but has
889     /// not yet been released with `release_tile()`.
890     virtual const void* tile_pixels(Tile* tile, TypeDesc& format) const = 0;
891 
892     /// The add_file() call causes a file to be opened or added to the
893     /// cache. There is no reason to use this method unless you are
894     /// supplying a custom creator, or configuration, or both.
895     ///
896     /// If creator is not NULL, it points to an ImageInput::Creator that
897     /// will be used rather than the default ImageInput::create(), thus
898     /// instead of reading from disk, creates and uses a custom ImageInput
899     /// to generate the image. The 'creator' is a factory that creates the
900     /// custom ImageInput and will be called like this:
901     ///
902     ///      std::unique_ptr<ImageInput> in (creator());
903     ///
904     /// Once created, the ImageCache owns the ImageInput and is responsible
905     /// for destroying it when done. Custom ImageInputs allow "procedural"
906     /// images, among other things.  Also, this is the method you use to set
907     /// up a "writable" ImageCache images (perhaps with a type of ImageInput
908     /// that's just a stub that does as little as possible).
909     ///
910     /// If `config` is not NULL, it points to an ImageSpec with configuration
911     /// options/hints that will be passed to the underlying
912     /// ImageInput::open() call. Thus, this can be used to ensure that the
913     /// ImageCache opens a call with special configuration options.
914     ///
915     /// This call (including any custom creator or configuration hints) will
916     /// have no effect if there's already an image by the same name in the
917     /// cache. Custom creators or configurations only "work" the FIRST time
918     /// a particular filename is referenced in the lifetime of the
919     /// ImageCache. But if replace is true, any existing entry will be
920     /// invalidated, closed and overwritten. So any subsequent access will
921     /// see the new file. Existing texture handles will still be valid.
922     virtual bool add_file (ustring filename, ImageInput::Creator creator=nullptr,
923                            const ImageSpec *config=nullptr,
924                            bool replace = false) = 0;
925 
926     /// Preemptively add a tile corresponding to the named image, at the
927     /// given subimage, MIP level, and channel range.  The tile added is the
928     /// one whose corner is (x,y,z), and buffer points to the pixels (in the
929     /// given format, with supplied strides) which will be copied and
930     /// inserted into the cache and made available for future lookups.
931     /// If chend < chbegin, it will add a tile containing the full set of
932     /// channels for the image. Note that if the 'copy' flag is false, the
933     /// data is assumed to be in some kind of persistent storage and will
934     /// not be copied, nor will its pixels take up additional memory in the
935     /// cache.
936     virtual bool add_tile (ustring filename, int subimage, int miplevel,
937                      int x, int y, int z, int chbegin, int chend,
938                      TypeDesc format, const void *buffer,
939                      stride_t xstride=AutoStride, stride_t ystride=AutoStride,
940                      stride_t zstride=AutoStride, bool copy = true) = 0;
941 
942     /// @}
943 
944     /// @{
945     /// @name Errors and statistics
946 
947     /// If any of the API routines returned `false` indicating an error,
948     /// this routine will return the error string (and clear any error
949     /// flags).  If no error has occurred since the last time `geterror()`
950     /// was called, it will return an empty string.
951     virtual std::string geterror() const = 0;
952 
953     /// Returns a big string containing useful statistics about the
954     /// ImageCache operations, suitable for saving to a file or outputting
955     /// to the terminal. The `level` indicates the amount of detail in
956     /// the statistics, with higher numbers (up to a maximum of 5) yielding
957     /// more and more esoteric information.
958     virtual std::string getstats(int level = 1) const = 0;
959 
960     /// Reset most statistics to be as they were with a fresh ImageCache.
961     /// Caveat emptor: this does not flush the cache itelf, so the resulting
962     /// statistics from the next set of texture requests will not match the
963     /// number of tile reads, etc., that would have resulted from a new
964     /// ImageCache.
965     virtual void reset_stats() = 0;
966 
967     /// @}
968 
~ImageCache()969     virtual ~ImageCache() {}
970 
971 protected:
972     // User code should never directly construct or destruct an ImageCache.
973     // Always use ImageCache::create() and ImageCache::destroy().
ImageCache(void)974     ImageCache(void) {}
975 private:
976     // Make delete private and unimplemented in order to prevent apps
977     // from calling it.  Instead, they should call ImageCache::destroy().
delete(void *)978     void operator delete(void* /*todel*/) {}
979 };
980 
981 
982 OIIO_NAMESPACE_END
983