Cached Images#
Image Cache Introduction and Theory of Operation#
ImageCache is a utility class that allows an application to read pixels from a large number of image files while using a remarkably small amount of memory and other resources. Of course it is possible for an application to do this directly using ImageInput objects. But ImageCache offers the following advantages:
ImageCache presents an even simpler user interface than ImageInput — the only supported operations are asking for an ImageSpec describing a subimage in the file, retrieving for a block of pixels, and locking/reading/releasing individual tiles. You refer to images by filename only; you don’t need to keep track of individual file handles or ImageInput objects. You don’t need to explicitly open or close files.
The ImageCache is completely thread-safe; if multiple threads are accessing the same file, the ImageCache internals will handle all the locking and resource sharing.
No matter how many image files you are accessing, the ImageCache will maintain a reasonable number of simultaneously-open files, automatically closing files that have not been needed recently.
No matter how large the total pixels in all the image files you are dealing with are, the ImageCache will use only a small amount of memory. It does this by loading only the individual tiles requested, and as memory allotments are approached, automatically releasing the memory from tiles that have not been used recently.
In short, if you have an application that will need to read pixels from many large image files, you can rely on ImageCache to manage all the resources for you. It is reasonable to access thousands of image files totalling hundreds of GB of pixels, efficiently and using a memory footprint on the order of 50 MB.
Below are some simple code fragments that shows ImageCache in action:
#include <OpenImageIO/imagecache.h>
using namespace OIIO;
// Create an image cache and set some options
ImageCache *cache = ImageCache::create ();
cache->attribute ("max_memory_MB", 500.0f);
cache->attribute ("autotile", 64);
// Get a block of pixels from a file.
// (for brevity of this example, let's assume that 'size' is the
// number of channels times the number of pixels in the requested region)
float pixels[size];
cache->get_pixels ("file1.jpg", 0, 0, xbegin, xend, ybegin, yend,
zbegin, zend, TypeDesc::FLOAT, pixels);
// Get information about a file
ImageSpec spec;
bool ok = cache->get_imagespec ("file2.exr", spec);
if (ok)
std::cout << "resolution is " << spec.width << "x"
<< spec.height << "\n";
// Request and hold a tile, do some work with its pixels, then release
ImageCache::Tile *tile;
tile = cache->get_tile ("file2.exr", 0, 0, x, y, z);
// The tile won't be freed until we release it, so this is safe:
TypeDesc format;
void *p = cache->tile_pixels (tile, format);
// Now p points to the raw pixels of the tile, whose data format
// is given by 'format'.
cache->release_tile (tile);
// Now cache is permitted to free the tile when needed
// Note that all files were referenced by name, we never had to open
// or close any files, and all the resource and memory management
// was automatic.
ImageCache::destroy (cache);
ImageCache API#
-
class ImageCache#
Define an API to an abstract class that manages image files, caches of open file handles as well as tiles of pixels so that truly huge amounts of image data may be accessed by an application with low memory footprint.
Opaque data for performance lookups
The ImageCache implementation needs to maintain certain per-thread state, and some methods take an opaque
Perthread
pointer to this record. There are three options for how to deal with it:Don’t worry about it at all: don’t use the methods that want
Perthread
pointers, or always passnullptr
for any `Perthread*1 arguments, and ImageCache will do thread-specific-pointer retrieval as necessary (though at some small cost).If your app already stores per-thread information of its own, you may call
get_perthread_info(nullptr)
to retrieve it for that thread, and then pass it into the functions that allow it (thus sparing them the need and expense of retrieving the thread-specific pointer). However, it is crucial that this pointer not be shared between multiple threads. In this case, the ImageCache manages the storage, which will automatically be released when the thread terminates.If your app also wants to manage the storage of the
Perthread
, it can explicitly create one withcreate_perthread_info()
, pass it around, and eventually be responsible for destroying it withdestroy_perthread_info()
. When managing the storage, the app may reuse thePerthread
for another thread after the first is terminated, but still may not use the samePerthread
for two threads running concurrently.
-
using Perthread = ImageCachePerThreadInfo#
Define an opaque data type that allows us to have a pointer to certain per-thread information that the ImageCache maintains. Any given one of these should NEVER be shared between running threads.
-
using ImageHandle = ImageCacheFile#
Define an opaque data type that allows us to have a handle to an image (already having its name resolved) but without exposing any internals.
-
Perthread *get_perthread_info(Perthread *thread_info = NULL)#
Retrieve a Perthread, unique to the calling thread. This is a thread-specific pointer that will always return the Perthread for a thread, which will also be automatically destroyed when the thread terminates.
Applications that want to manage their own Perthread pointers (with
create_thread_info
anddestroy_thread_info
) should still call this, but passing in their managed pointer. If the passed-in thread_info is not NULL, it won’t create a new one or retrieve a TSP, but it will do other necessary housekeeping on the Perthread information.
-
Perthread *create_thread_info()#
Create a new Perthread. It is the caller’s responsibility to eventually destroy it using
destroy_thread_info()
.
-
void destroy_thread_info(Perthread *thread_info)#
Destroy a Perthread that was allocated by
create_thread_info()
.
-
ImageHandle *get_image_handle(ustring filename, Perthread *thread_info = nullptr, const TextureOpt_v2 *options = nullptr)#
Retrieve an opaque handle for fast texture lookups, or nullptr upon failure. The filename is presumed to be UTF-8 encoded. The
options
, if not null, may be used to create a separate handle for certain texture option choices. (Currently unused, but reserved for the future or for alternate IC implementations.) The opaque pointerthread_info
is thread-specific information returned byget_perthread_info()
.
-
inline ImageHandle *get_image_handle(const std::wstring &filename, Perthread *thread_info = nullptr, const TextureOpt_v2 *options = nullptr)#
Get an ImageHandle using a UTF-16 encoded wstring filename.
-
bool good(ImageHandle *file)#
Return true if the image handle (previously returned by
get_image_handle()
) is a valid image that can be subsequently read.
-
ustring filename_from_handle(ImageHandle *handle)#
Given a handle, return the filename for that image.
This method was added in OpenImageIO 2.3.
Controlling the cache
-
using Tile = ImageCacheTile#
An opaque data type that allows us to have a pointer to a tile but without exposing any internals.
-
void invalidate(ustring filename, bool force = true)#
Invalidate any loaded tiles or open file handles associated with the filename (UTF-8 encoded), so that any subsequent queries will be forced to re-open the file or re-load any tiles (even those that were previously loaded and would ordinarily be reused). A client might do this if, for example, they are aware that an image being held in the cache has been updated on disk. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels until they release the tiles they are holding.
If
force
is true, this invalidation will happen unconditionally; if false, the file will only be invalidated if it has been changed since it was first opened by the ImageCache.
-
void invalidate(ImageHandle *file, bool force = true)#
A more efficient variety of
invalidate()
for cases where you already have anImageHandle*
for the file you want to invalidate.
-
void invalidate_all(bool force = false)#
Invalidate all loaded tiles and close open file handles. This is safe to do even if other procedures are currently holding reference-counted tile pointers from the named image, but those procedures will not get updated pixels (if the images change) until they release the tiles they are holding.
If
force
is true, everything will be invalidated, no matter how wasteful it is, but ifforce
is false, in actuality files will only be invalidated if their modification times have been changed since they were first opened.
-
void close(ustring filename)#
Close any open file handles associated with a named file (UTF-8 encoded), but do not invalidate any image spec information or pixels associated with the files. A client might do this in order to release OS file handle resources, or to make it safe for other processes to modify image files on disk.
-
Tile *get_tile(ustring filename, int subimage, int miplevel, int x, int y, int z, int chbegin = 0, int chend = -1)#
Find the tile specified by an image filename (UTF-8 encoded), subimage & miplevel, the coordinates of a pixel, and optionally a channel range. An opaque pointer to the tile will be returned, or
nullptr
if no such file (or tile within the file) exists or can be read. The tile will not be purged from the cache until afterrelease_tile()
is called on the tile pointer the same number of times thatget_tile()
was called (reference counting). This is thread-safe! Ifchend < chbegin
, it will retrieve a tile containing all channels in the file.
-
Tile *get_tile(ImageHandle *file, Perthread *thread_info, int subimage, int miplevel, int x, int y, int z, int chbegin = 0, int chend = -1)#
A slightly more efficient variety of
get_tile()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.See also
-
void release_tile(Tile *tile) const#
After finishing with a tile, release_tile will allow it to once again be purged from the tile cache if required.
-
TypeDesc tile_format(const Tile *tile) const#
Retrieve the data type of the pixels stored in the tile, which may be different than the type of the pixels in the disk file.
-
ROI tile_roi(const Tile *tile) const#
Retrieve the ROI describing the pixels and channels stored in the tile.
-
const void *tile_pixels(Tile *tile, TypeDesc &format) const#
For a tile retrieved by
get_tile()
, return a pointer to the pixel data itself, and also store informat
the data type that the pixels are internally stored in (which may be different than the data type of the pixels in the disk file). This method should only be called on a tile that has been requested byget_tile()
but has not yet been released withrelease_tile()
.
-
bool add_file(ustring filename, ImageInput::Creator creator = nullptr, const ImageSpec *config = nullptr, bool replace = false)#
The add_file() call causes a file to be opened or added to the cache. There is no reason to use this method unless you are supplying a custom creator, or configuration, or both.
If creator is not NULL, it points to an ImageInput::Creator that will be used rather than the default ImageInput::create(), thus instead of reading from disk, creates and uses a custom ImageInput to generate the image. The ‘creator’ is a factory that creates the custom ImageInput and will be called like this:
Once created, the ImageCache owns the ImageInput and is responsible for destroying it when done. Custom ImageInputs allow “procedural” images, among other things. Also, this is the method you use to set up a “writable” ImageCache images (perhaps with a type of ImageInput that’s just a stub that does as little as possible).std::unique_ptr<ImageInput> in (creator());
If
config
is not NULL, it points to an ImageSpec with configuration options/hints that will be passed to the underlying ImageInput::open() call. Thus, this can be used to ensure that the ImageCache opens a call with special configuration options.This call (including any custom creator or configuration hints) will have no effect if there’s already an image by the same name in the cache. Custom creators or configurations only “work” the FIRST time a particular filename is referenced in the lifetime of the ImageCache. But if replace is true, any existing entry will be invalidated, closed and overwritten. So any subsequent access will see the new file. Existing texture handles will still be valid.
-
bool add_tile(ustring filename, int subimage, int miplevel, int x, int y, int z, int chbegin, int chend, TypeDesc format, const void *buffer, stride_t xstride = AutoStride, stride_t ystride = AutoStride, stride_t zstride = AutoStride, bool copy = true)#
Preemptively add a tile corresponding to the named image, at the given subimage, MIP level, and channel range. The tile added is the one whose corner is (x,y,z), and buffer points to the pixels (in the given format, with supplied strides) which will be copied and inserted into the cache and made available for future lookups. If chend < chbegin, it will add a tile containing the full set of channels for the image. Note that if the ‘copy’ flag is false, the data is assumed to be in some kind of persistent storage and will not be copied, nor will its pixels take up additional memory in the cache.
Creating and destroying an image cache
ImageCache is an abstract API described as a pure virtual class. The actual internal implementation is not exposed through the external API of OpenImageIO. Because of this, you cannot construct or destroy the concrete implementation, so two static methods of ImageCache are provided:
-
static std::shared_ptr<ImageCache> create(bool shared = true)#
Create a ImageCache and return a shared pointer to it.
See also
- Parameters:
shared – If
true
, the pointer returned will be a shared ImageCache (so that multiple parts of an application that request an ImageCache will all end up with the same one). Ifshared
isfalse
, a completely unique ImageCache will be created and returned.- Returns:
A shared pointer to an ImageCache, which can only be freed with
ImageCache::destroy()
.
Release the shared_ptr to an ImageCache, including freeing all system resources that it holds if no one else is still using it. This is not strictly necessary to call, simply destroying the shared_ptr will do the same thing, but this call is for backward compatibility and is helpful if you want to use the teardown option.
- Parameters:
cache – Shared pointer to the ImageCache to destroy.
teardown – For a shared ImageCache, if the
teardown
parameter istrue
, it will try to truly destroy the shared cache if nobody else is still holding a reference (otherwise, it will leave it intact). This parameter has no effect ifcache
was not the single globally shared ImageCache.
Setting options and limits for the image cache
These are the list of attributes that can bet set or queried by attribute/getattribute:
int max_open_files
: The approximate maximum number of file handles that the image cache will hold open simultaneously. This is not an iron-clad guarantee; the number of handles may momentarily exceed this by a small percentage. (Default = 100)float max_memory_MB
: The approximate maximum amount of memory (measured in MB) used for the internal “tile cache.” (Default: 1024.0 MB)string searchpath
: The search path for images: a colon-separated list of directories that will be searched in order for any image filename that is not specified as an absolute path. (Default: “”)string plugin_searchpath
: The search path for plugins: a colon-separated list of directories that will be searched in order for any OIIO plugins, if not found in OIIO’slib
directory. (Default: “”)int autotile
,int autoscanline
: These attributes control how the image cache deals with images that are not “tiled” (i.e., are stored as scanlines).If
autotile
is set to 0 (the default), an untiled image will be treated as if it were a single tile of the resolution of the whole image. This is simple and fast, but can lead to poor cache behavior if you are simultaneously accessing many large untiled images.If
autotile
is nonzero (e.g., 64 is a good recommended value), any untiled images will be read and cached as if they were constructed in tiles of size:autotile * autotile
ifautoscanline
is 0width * autotile
ifautoscanline
is nonzero.
In both cases, this should lead more efficient caching. The
autoscanline
determines whether the “virtual tiles” in the cache are square (ifautoscanline
is 0, the default) or if they will be as wide as the image (but onlyautotile
scanlines high). You should try in your application to see which leads to higher performance.int autoscanline
: autotile using full width tilesint automip
: If 0 (the default), an untiled single-subimage file will only be able to utilize that single subimage. If nonzero, any untiled, single-subimage (un-MIP-mapped) images will have lower-resolution MIP-map levels generated on-demand if pixels are requested from the lower-res subimages (that don’t really exist). Essentially this makes the ImageCache pretend that the file is MIP-mapped even if it isn’t.int accept_untiled
: When nonzero, ImageCache accepts untiled images as usual. When zero, ImageCache will reject untiled images with an error condition, as if the file could not be properly read. This is sometimes helpful for applications that want to enforce use of tiled images only. (default=1)int accept_unmipped
: When nonzero, ImageCache accepts un-MIPmapped images as usual. When set to zero, ImageCache will reject un-MIPmapped images with an error condition, as if the file could not be properly read. This is sometimes helpful for applications that want to enforce use of MIP-mapped images only. (Default: 1)int statistics:level
: verbosity of statistics auto-printed.int forcefloat
: If set to nonzero, all image tiles will be converted tofloat
type when stored in the image cache. This can be helpful especially for users of ImageBuf who want to simplify their image manipulations to only need to considerfloat
data. The default is zero, meaning that image pixels are not forced to befloat
when in cache.int failure_retries
: When an image file is opened or a tile/scanline is read but a file error occurs, if this attribute is nonzero, it will try the operation again up to this many times before giving up and reporting a failure. Setting this to a small nonzero number (like 3) may help make an application more robust to occasional spurious networking or other glitches that would otherwise cause the entire long-running application to fail upon a single transient error. (Default: 0)int deduplicate
: When nonzero, the ImageCache will notice duplicate images under different names if their headers contain a SHA-1 fingerprint (as is done withmaketx
-produced textures) and handle them more efficiently by avoiding redundant reads. The default is 1 (de-duplication turned on). The only reason to set it to 0 is if you specifically want to disable the de-duplication optimization.int max_open_files_strict
: If nonzero, work harder to make sure that we have smaller possible overages to the max open files limit. (Default: 0)string substitute_image
: When set to anything other than the empty string, the ImageCache will use the named image in place of all other images. This allows you to run an app using OIIO and (if you can manage to get this option set) automagically substitute a grid, zone plate, or other special debugging image for all image/texture use.int unassociatedalpha
: When nonzero, will request that image format readers try to leave input images with unassociated alpha as they are, rather than automatically converting to associated alpha upon reading the pixels. The default is 0, meaning that the automatic conversion will take place.int max_errors_per_file
: The maximum number of errors that will be printed for each file. The default is 100. If your output is cluttered with error messages and after the first few for each file you aren’t getting any helpful additional information, this can cut down on the clutter and the runtime. (default: 100)int trust_file_extensions
: When nonzero, assume that the file extensions of any texture requests correctly indicates the file format (when enabled, this reduces the number of file opens, at the expense of not being able to open files if their format do not actually match their filename extension). Default: 0string colorspace
: The working colorspace of the texture system. Default: none.string colorconfig
: Name of the OCIO config to use. Default: “” (meaning to use the default color config).string options
This catch-all is simply a comma-separated list ofname=value
settings of named options, which will be parsed and individually set. Example:Note that if an option takes a string value that must itself contain a comma, it is permissible to enclose the value in either single ( ‘ic->attribute ("options", "max_memory_MB=512.0,autotile=1");
) or double (
“ “ `) quotes.
Read-only attributes
Additionally, there are some read-only attributes that can be queried with
getattribute()
even though they cannot be set viaattribute()
:int total_files
: The total number of unique file names referenced by calls to the ImageCache.string[] all_filenames
: An array that will be filled with the list of the names of all files referenced by calls to the ImageCache. (The array is ofustring
orchar*
.)int64 stat:cache_footprint
: Total bytes used by image cache.int64 stat:cache_memory_used
: Total bytes used by tile cache.int stat:tiles_created
,int stat:tiles_current
,int stat:tiles_peak
: Total times created, still allocated (at the time of the query), and the peak number of tiles in memory at any time.int stat:open_files_created
,int stat:open_files_current
,int stat:open_files_peak
: Total number of times a file was opened, number still opened (at the time of the query), and the peak number of files opened at any time.int stat:find_tile_calls
: Number of times a filename was looked up in the file cache.int64 stat:image_size
: Total size (uncompressed bytes of pixel data) of all images referenced by the ImageCache. (Note: Prior to 1.7, this was calledstat:files_totalsize
.)int64 stat:file_size
: Total size of all files (as on disk, possibly compressed) of all images referenced by the ImageCache.int64 stat:bytes_read
: Total size (uncompressed bytes of pixel data) read.int stat:unique_files
: Number of unique files opened.float stat:fileio_time
: Total I/O-related time (seconds).float stat:fileopen_time
: I/O time related to opening and reading headers (but not pixel I/O).float stat:file_locking_time
: Total time (across all threads) that threads blocked waiting for access to the file data structures.float stat:tile_locking_time
: Total time (across all threads) that threads blocked waiting for access to the tile cache data structures.float stat:find_file_time
: Total time (across all threads) that threads spent looking up files by name.float stat:find_tile_time
: Total time (across all threads) that threads spent looking up individual tiles.
The following member functions of ImageCache allow you to set (and in some cases retrieve) options that control the overall behavior of the image cache:
-
bool attribute(string_view name, TypeDesc type, const void *val)#
Set a named attribute (i.e., a property or option) of the ImageCache.
Example:
Note: When passing a string, you need to pass a pointer to theImageCache *ic; ... int maxfiles = 50; ic->attribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path = "/my/path"; ic->attribute ("searchpath", TypeDesc::STRING, &path); // There are specialized versions for setting a single int, // float, or string without needing types or pointers: ic->attribute ("max_open_files", 50); ic->attribute ("max_memory_MB", 4000.0f); ic->attribute ("searchpath", "/my/path");
char*
, not a pointer to the first character. (Rationale: for anint
attribute, you pass the address of theint
. So for a string, which is achar*
, you need to pass the address of the string, i.e., achar**
).- Parameters:
name – Name of the attribute to set.
type – TypeDesc describing the type of the attribute.
val – Pointer to the value data.
- Returns:
true
if the name and type were recognized and the attribute was set, orfalse
upon failure (including it being an unrecognized attribute or not of the correct type).
-
inline bool attribute(string_view name, int val)#
Specialized
attribute()
for setting a singleint
value.
-
inline bool attribute(string_view name, float val)#
Specialized
attribute()
for setting a singlefloat
value.
-
inline bool attribute(string_view name, string_view val)#
Specialized
attribute()
for setting a single string value.
-
bool getattribute(string_view name, TypeDesc type, void *val) const#
Get the named attribute, store it in
*val
. All of the attributes that may be set with theattribute() call
may also be queried withgetattribute()
.Examples:
Note: When retrieving a string, you need to pass a pointer to theImageCache *ic; ... int maxfiles; ic->getattribute ("max_open_files", TypeDesc::INT, &maxfiles); const char *path; ic->getattribute ("searchpath", TypeDesc::STRING, &path); // There are specialized versions for retrieving a single int, // float, or string without needing types or pointers: int maxfiles; ic->getattribute ("max_open_files", maxfiles); const char *path; ic->getattribute ("searchpath", &path);
char*
, not a pointer to the first character. Also, thechar*
will end up pointing to characters owned by the ImageCache; the caller does not need to ever free the memory that contains the characters.- Parameters:
name – Name of the attribute to retrieve.
type – TypeDesc describing the type of the attribute.
val – Pointer where the attribute value should be stored.
- Returns:
true
if the name and type were recognized and the attribute was retrieved, orfalse
upon failure (including it being an unrecognized attribute or not of the correct type).
-
inline bool getattribute(string_view name, int &val) const#
Specialized
attribute()
for retrieving a singleint
value.
-
inline bool getattribute(string_view name, float &val) const#
Specialized
attribute()
for retrieving a singlefloat
value.
-
inline bool getattribute(string_view name, char **val) const#
Specialized
attribute()
for retrieving a singlestring
value as achar*
.
-
inline bool getattribute(string_view name, std::string &val) const#
Specialized
attribute()
for retrieving a singlestring
value as astd::string
.
Getting information about images
-
std::string resolve_filename(const std::string &filename) const#
Given possibly-relative
filename
(UTF-8 encoded), resolve it and use the true path to the file, with searchpath logic applied.
-
bool get_image_info(ustring filename, int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data)#
Get information or metadata about the named image and store it in
*data
.Data names may include any of the following:
"exists"
: Stores the value 1 (as anint
) if the file exists and is an image format that OpenImageIO can read, or 0 if the file does not exist, or could not be properly read as an image. Note that unlike all other queries, this query will “succeed” (returntrue
) even if the file does not exist."udim"
: Stores the value 1 (as anint
) if the file is a “virtual UDIM” or texture atlas file (as described in :ref:sec-texturesys-udim
) or 0 otherwise."subimages"
: The number of subimages in the file, as anint
."resolution"
: The resolution of the image file, which is an array of 2 integers (described asTypeDesc(INT,2)
)."miplevels"
: The number of MIPmap levels for the specified subimage (an integer)."texturetype"
: A string describing the type of texture of the given file, which describes how the texture may be used (also which texture API call is probably the right one for it). This currently may return one of:"unknown"
,"Plain Texture"
,"Volume Texture"
,"Shadow"
, or"Environment"
."textureformat"
: A string describing the format of the given file, which describes the kind of texture stored in the file. This currently may return one of:"unknown"
,"Plain Texture"
,"Volume Texture"
,"Shadow"
,"CubeFace Shadow"
,"Volume Shadow"
,"LatLong Environment"
, or"CubeFace Environment"
. Note that there are several kinds of shadows and environment maps, all accessible through the same API calls."channels"
: The number of color channels in the file (anint
)."format"
: The native data format of the pixels in the file (an integer, giving theTypeDesc::BASETYPE
of the data). Note that this is not necessarily the same as the data format stored in the image cache."cachedformat"
: The native data format of the pixels as stored in the image cache (an integer, giving theTypeDesc::BASETYPE
of the data). Note that this is not necessarily the same as the native data format of the file."datawindow"
: Returns the pixel data window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The z values may be useful for 3D/volumetric images; for 2D images they will be 0)."displaywindow"
: Returns the display (a.k.a. “full”) window of the image, which is either an array of 4 integers (returning xmin, ymin, xmax, ymax) or an array of 6 integers (returning xmin, ymin, zmin, xmax, ymax, zmax). The z values may be useful for 3D/volumetric images; for 2D images they will be 0)."worldtocamera"
: The viewing matrix, which is a 4x4 matrix (anImath::M44f
, described asTypeDesc(FLOAT,MATRIX)
), giving the world-to-camera 3D transformation matrix that was used when the image was created. Generally, only rendered images will have this."worldtoscreen"
: The projection matrix, which is a 4x4 matrix (anImath::M44f
, described asTypeDesc(FLOAT,MATRIX)
), giving the matrix that projected points from world space into a 2D screen coordinate system where $x$ and $y$ range from -1 to +1. Generally, only rendered images will have this."worldtoNDC"
: The projection matrix, which is a 4x4 matrix (anImath::M44f
, described asTypeDesc(FLOAT,MATRIX)
), giving the matrix that projected points from world space into a 2D NDC coordinate system where $x$ and $y$ range from 0 to +1. Generally, only rendered images will have this."averagecolor"
: If available in the metadata (generally only for files that have been processed bymaketx
), this will return the average color of the texture (into an array offloat
)."averagealpha"
: If available in the metadata (generally only for files that have been processed bymaketx
), this will return the average alpha value of the texture (into afloat
)."constantcolor"
: If the metadata (generally only for files that have been processed bymaketx
) indicates that the texture has the same values for all pixels in the texture, this will retrieve the constant color of the texture (into an array of floats). A non-constant image (or one that does not have the special metadata tag identifying it as a constant texture) will fail this query (returnfalse
)."constantalpha"
: If the metadata indicates that the texture has the same values for all pixels in the texture, this will retrieve the constant alpha value of the texture (into a float). A non-constant image (or one that does not have the special metadata tag identifying it as a constant texture) will fail this query (returnfalse
)."stat:tilesread"
: Number of tiles read from this file (int64
)."stat:bytesread"
: Number of bytes of uncompressed pixel data read from this file (int64
)."stat:redundant_tiles"
: Number of times a tile was read, where the same tile had been rad before. (int64
)."stat:redundant_bytesread"
: Number of bytes (of uncompressed pixel data) in tiles that were read redundantly. (int64
)."stat:redundant_bytesread"
: Number of tiles read from this file (int
)."stat:image_size"
: Size of the uncompressed image pixel data of this image, in bytes (int64
)."stat:file_size"
: Size of the disk file (possibly compressed) for this image, in bytes (int64
)."stat:timesopened"
: Number of times this file was opened (int
)."stat:iotime"
: Time (in seconds) spent on all I/O for this file (float
)."stat:mipsused"
: Stores 1 if any MIP levels beyond the highest resolution were accessed, otherwise 0. (int
)"stat:is_duplicate"
: Stores 1 if this file was a duplicate of another image, otherwise 0. (int
)Anything else : For all other data names, the the metadata of the image file will be searched for an item that matches both the name and data type.
- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
subimage/miplevel – The subimage and MIP level to query.
dataname – The name of the metadata to retrieve.
datatype – TypeDesc describing the data type.
data – Pointer to the caller-owned memory where the values should be stored. It is the caller’s responsibility to ensure that
data
points to a large enough storage area to accommodate thedatatype
requested.
- Returns:
true
ifget_image_info()
is able to find the requesteddataname
for the image and it matched the requesteddatatype
. If the requested data was not found or was not of the right data type, returnfalse
. Except for the"exists"
query, a file that does not exist or could not be read properly as an image also constitutes a query failure that will returnfalse
.
-
bool get_image_info(ImageHandle *file, Perthread *thread_info, int subimage, int miplevel, ustring dataname, TypeDesc datatype, void *data)#
A more efficient variety of
get_image_info()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
-
bool get_imagespec(ustring filename, ImageSpec &spec, int subimage = 0)#
Copy the ImageSpec that describes the named image file.
Note that the spec returned describes the file as it exists in the file, at the base (highest-resolution) MIP level of that subimage. Certain aspects of the in-cache representation may differ from the file (due to ImageCache implementation strategy or options like
"forcefloat"
or"autotile"
). If you really need to know the in-cache data type, tile size, or how the resolution or tiling changes on a particular MIP level, you should useget_cache_dimensions()
.- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
spec – ImageSpec into which will be copied the spec for the requested image.
subimage – The subimage to query.
- Returns:
true
upon success,false
upon failure failure (such as being unable to find, open, or read the file, or if it does not contain the designated subimage.
-
bool get_imagespec(ImageHandle *file, Perthread *thread_info, ImageSpec &spec, int subimage = 0)#
A more efficient variety of
get_imagespec()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
-
inline bool get_imagespec(ustring filename, ImageSpec &spec, int subimage, int miplevel, bool native = false)#
DEPRECATED(3.0) old API. Note that the miplevel and native parameters are ignored: it will always get the native spec of miplevel 0. We recommend switching to the new API.
-
inline bool get_imagespec(ImageHandle *file, Perthread *thread_info, ImageSpec &spec, int subimage, int miplevel, bool native = false)#
DEPRECATED(3.0) old API.
-
const ImageSpec *imagespec(ustring filename, int subimage = 0)#
Return a pointer to an ImageSpec that describes the named image file. If the file is found and is an image format that can be read, otherwise return
nullptr
.This method is much more efficient than
get_imagespec()
, since it just returns a pointer to the spec held internally by the ImageCache (rather than copying the spec to the user’s memory). However, the caller must beware that the pointer is only valid as long as nobody (even other threads) callsinvalidate()
on the file, orinvalidate_all()
, or destroys the ImageCache.Note that the spec returned describes the file as it exists in the file, at the base (highest-resolution) MIP level of that subimage. Certain aspects of the in-cache representation may differ from the file (due to ImageCache implementation strategy or options like
"forcefloat"
or"autotile"
). If you really need to know the in-cache data type, tile size, or how the resolution or tiling changes on a particular MIP level, you should useget_cache_dimensions()
.- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
subimage – The subimage to query.
- Returns:
A pointer to the spec, if the image is found and able to be opened and read by an available image format plugin, and the designated subimage exists.
-
const ImageSpec *imagespec(ImageHandle *file, Perthread *thread_info, int subimage = 0)#
A more efficient variety of
imagespec()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
-
inline const ImageSpec *imagespec(ustring filename, int subimage, int miplevel, bool native = false)#
DEPRECATED(3.0) old API. Note that the miplevel and native parameters are ignored: it will always get the native spec of miplevel 0. We recommend switching to the new API.
-
inline const ImageSpec *imagespec(ImageHandle *file, Perthread *thread_info, int subimage, int miplevel, bool native = false)#
DEPRECATED(3.0) old API.
-
bool get_cache_dimensions(ustring filename, ImageSpec &spec, int subimage = 0, int miplevel = 0)#
Copy the image dimensions (x, y, z, width, height, depth, full*, nchannels, format) and data types that describes the named image cache file for the specified subimage and miplevel. It does not copy arbitrary named metadata or channel names (thus, for an
ImageSpec
with lots of metadata, it is much less expensive than copying the whole thing withoperator=()
). The associated metadata and channels names can be retrieved withimagespec()
orget_imagespec
.- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
spec – ImageSpec into which will be copied the dimensions for the requested image.
subimage/miplevel – The subimage and mip level to query.
- Returns:
true
upon success,false
upon failure failure (such as being unable to find, open, or read the file, or if it does not contain the designated subimage or mip level.
-
bool get_cache_dimensions(ImageHandle *file, Perthread *thread_info, ImageSpec &spec, int subimage = 0, int miplevel = 0)#
A more efficient variety of
get_cache_dimensions()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
-
bool get_thumbnail(ustring filename, ImageBuf &thumbnail, int subimage = 0)#
Copy into
thumbnail
any associated thumbnail associated with this image (for the first subimage by default, or as set bysubimage
).- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
thumbnail – ImageBuf into which will be copied the thumbnail, if it exists. If no thumbnail can be retrieved,
thumb
will be reset to an uninitialized (empty) ImageBuf.subimage – The subimage to query.
- Returns:
true
upon success,false
upon failure failure (such as being unable to find, open, or read the file, or if it does not contain a thumbnail).
-
bool get_thumbnail(ImageHandle *file, Perthread *thread_info, ImageBuf &thumbnail, int subimage = 0)#
A more efficient variety of
get_thumbnail()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
Getting Pixels
-
bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride = AutoStride, stride_t ystride = AutoStride, stride_t zstride = AutoStride, int cache_chbegin = 0, int cache_chend = -1)#
For an image specified by name, retrieve the rectangle of pixels from the designated subimage and MIP level, storing the pixel values beginning at the address specified by
result
and with the given strides. The pixel values will be converted to the data type specified byformat
. The rectangular region to be retrieved includesbegin
but does not includeend
(much like STL begin/end usage). Requested pixels that are not part of the valid pixel data region of the image file will be filled with zero values.- Parameters:
filename – The name of the image, as a UTF-8 encoded ustring.
subimage/miplevel – The subimage and MIP level to retrieve pixels from.
xbegin/xend/ybegin/yend/zbegin/zend – The range of pixels to retrieve. The pixels retrieved include the begin value but not the end value (much like STL begin/end usage).
chbegin/chend – Channel range to retrieve. To retrieve all channels, use
chbegin = 0
,chend = nchannels
.format – TypeDesc describing the data type of the values you want to retrieve into
result
. The pixel values will be converted to this type regardless of how they were stored in the file.result – Pointer to the memory where the pixel values should be stored. It is up to the caller to ensure that
result
points to an area of memory big enough to accommodate the requested rectangle (taking into consideration its dimensions, number of channels, and data format).xstride/ystride/zstride – The number of bytes between the beginning of successive pixels, scanlines, and image planes, respectively. Any stride values set to
AutoStride
will be assumed to indicate a contiguous data layout in that dimension.cache_chbegin/cache_chend – These parameters can be used to tell the ImageCache to read and cache a subset of channels (if not specified or if they denote a non-positive range, all the channels of the file will be stored in the cached tile).
- Returns:
true
for success,false
for failure.
-
bool get_pixels(ImageHandle *file, Perthread *thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, TypeDesc format, void *result, stride_t xstride = AutoStride, stride_t ystride = AutoStride, stride_t zstride = AutoStride, int cache_chbegin = 0, int cache_chend = -1)#
A more efficient variety of
get_pixels()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
-
bool get_pixels(ustring filename, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result)#
A simplified
get_pixels()
where all channels are retrieved, strides are assumed to be contiguous.
-
bool get_pixels(ImageHandle *file, Perthread *thread_info, int subimage, int miplevel, int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, TypeDesc format, void *result)#
A more efficient variety of
get_pixels()
for cases where you can use anImageHandle*
to specify the image and optionally have aPerthread*
for the calling thread.
Errors and statistics
-
bool has_error() const#
Is there a pending error message waiting to be retrieved?
-
std::string geterror(bool clear = true) const#
Return the text of all pending error messages issued against this ImageCache, and clear the pending error message unless
clear
is false. If no error message is pending, it will return an empty string.
-
std::string getstats(int level = 1) const#
Returns a big string containing useful statistics about the ImageCache operations, suitable for saving to a file or outputting to the terminal. The
level
indicates the amount of detail in the statistics, with higher numbers (up to a maximum of 5) yielding more and more esoteric information.
-
void reset_stats()#
Reset most statistics to be as they were with a fresh ImageCache. Caveat emptor: this does not flush the cache itelf, so the resulting statistics from the next set of texture requests will not match the number of tile reads, etc., that would have resulted from a new ImageCache.