\chapter{Texture Access: {\cf TextureSystem}}
\label{chap:texturesystem}
\index{Texture System|(}

\def\TextureSystem{{\kw TextureSystem}\xspace}
\def\TextureOptions{{\kw TextureOptions}\xspace}
\def\TextureOpt{{\kw TextureOpt}\xspace}


\section{Texture System Introduction and Theory of Operation}
\label{sec:texturesys:intro}

Coming soon.
FIXME

\section{Helper Classes}
\label{sec:texturesys:helperclasses}

\subsection{Imath}

The texture functinality of \product uses the excellent open source
{\cf Ilmbase} package's {\cf Imath} types when it requires 3D vectors
and transformation matrixes.  Specifically, we use {\cf Imath::V3f}
for 3D positions and directions, and {\cf Imath::M44f} for $4 \times 4$
transformation matrices.  To use these yourself, we recommend that you:

\begin{code}
    #include <OpenEXR/ImathVec.h>
    #include <OpenEXR/ImathMatrix.h>
\end{code}

Please refer to the {\cf Ilmbase} and {\cf OpenEXR}
documentation and header files for more complete information about
use of these types in your own application.  However, note that you
are not strictly required to use these classes in your application ---
{\cf Imath::V3f} has a memory layout identical to {\cf float[3]}
and {\cf Imath::M44f} has a memory layout identical to {\cf float[16]},
so as long as your own internal vectors and matrices have the same
memory layout, it's ok to just cast pointers to them when passing
as arguments to \TextureSystem methods.


\subsection{\TextureOpt}
\indexapi{TextureOpt}

\TextureOpt is a structure that holds many options controlling
single-point texture lookups.  Because each texture lookup API call takes
a reference to a \TextureOpt, the call signatures remain uncluttered
rather than having an ever-growing list of parameters, most of which
will never vary from their defaults.  Here is a brief description of
the data members of a \TextureOpt structure:

\apiitem{int nchannels\\
int firstchannel}
The number of color channels to look up from the texture --- for
example, 1 (single channel), or 3 (for an RGB triple) --- and the number
of channels to look up.  The defaults are firstchannel = 0, nchannels =
1.

Examples: To retrieve the first three channels (typically RGB), you
should have nchannels = 3, firstchannel = 0.  To retrieve just the blue
channel, you should have nchannels = 1, firstchannel = 2.
\apiend

\apiitem{int subimage \\
ustring subimagename}
Specifies the subimage or face within the file to use for the texture lookup.
If {\cf subimagename} is set (it defaults to the empty string), it will
try to use the subimage that had a matching metadata
\qkw{oiio:subimagename}, otherwise the integer {\cf subimage} will be
used (which defaults to 0, i.e., the first/default subimage).  Nonzero
subimage indices only make sense for a texture file that supports
subimages or separate images per face (such as Ptex).  This will be
ignored if the file does not have multiple subimages or separate
per-face textures.
\apiend

\apiitem{Wrap swrap, twrap}
Specify the \emph{wrap mode} for 2D texture lookups (and 3D volume
texture lookups, using the additional {\cf rwrap} field).  These fields
are ignored for shadow and environment lookups.

These specify what happens when texture coordinates are found to be
outside the usual $[0,1]$ range over which the texture is defined.
{\cf Wrap} is an enumerated type that may take on any of the
following values:
\begin{description}
\item[\spc] \spc
\item[\rm \kw{WrapBlack}] The texture is black outside the [0,1] range.
\item[\rm \kw{WrapClamp}] The texture coordinates will be clamped to
  [0,1], i.e., the value outside [0,1] will be the same as the color
  at the nearest point on the border.
\item[\rm \kw{WrapPeriodic}] The texture is periodic, i.e., wraps back
  to 0 after going past 1.
\item[\rm \kw{WrapMirror}] The texture presents a mirror image at the
  edges, i.e., the coordinates go from 0 to 1, then back down to 0, then
  back up to 1, etc.
\item[\rm \kw{WrapDefault}] Use whatever wrap might be specified in the
  texture file itself, or some other suitable default (caveat emptor).
\end{description}

The wrap mode does not need to be identical in the $s$ and $t$
directions.
\apiend

\apiitem{float swidth, twidth}
For each direction, gives a multiplier for the derivatives.  Note that
a width of 0 indicates a point sampled lookup (assuming that blur is
also zero).  The default width is 1, indicating that the derivatives
should guide the amount of blur applied to the texture filtering (not
counting any additional \emph{blur} specified).
\apiend

\apiitem{float sblur, tblur}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.  In other words,
blur = 0.1 means that the texture lookup should act as if the texture
was pre-blurred with a filter kernel with a width 1/10 the size of the
full image.  The default blur amount is 0, indicating a sharp texture
lookup.
\apiend

\apiitem{float fill}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the last channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

\apiitem{const float* missingcolor}
If not NULL, indicates that a missing or broken texture should \emph{not}
be treated as an error, but rather will simply return the supplied color
as the texture lookup color and {\cf texture()} will return {\cf true}.  
If the {\cf missingcolor} field is left at its default (a NULL pointer),
a missing or broken texture will be treated as an error and
{\cf texture()} will return {\cf false}.
Note: When not NULL, the data must point to \emph{nchannels} contiguous floats.
\apiend

\apiitem{float *dresultds, *dresultdt}
If not NULL (the default), these specify locations in which to store
the \emph{derivatives} of the texture lookup, i.e., the change of the
filtered texture per unit of $s$ and $t$, respectively.  Each must point
to {\cf nchannels} contiguous floats.  If either is NULL, the derivative
computations will not be performed.
\apiend

\apiitem{float bias}
For shadow map lookups only, this gives the ``shadow bias'' amount.
\apiend

\apiitem{int samples}
For shadow map lookups only, the number of samples to use for the lookup.
\apiend

\apiitem{Wrap rwrap \\
float rblur, rwidth \\
float *dresultdr}
Specifies wrap, blur, width, and derivative results for the third
component of 3D volume texture lookups.  These are not used for 2D
texture lookups.
\apiend

\subsection{\TextureOptions}

\TextureOptions is a structure that holds many options controlling
batched texture lookups.  Because each texture lookup API call takes
a reference to a \TextureOptions, the call signatures remain uncluttered
rather than having an ever-growing list of parameters, most of which
will never vary from their defaults.  Here is a brief description of
the data members of a \TextureOptions structure:

\apiitem{int nchannels\\
int firstchannel}
The number of color channels to look up from the texture --- for
example, 1 (single channel), or 3 (for an RGB triple) --- and the number
of channels to look up.  The defaults are firstchannel = 0, nchannels =
1.

Examples: To retrieve the first three channels (typically RGB), you
should have nchannels = 3, firstchannel = 0.  To retrieve just the blue
channel, you should have nchannels = 1, firstchannel = 2.
\apiend

\apiitem{int subimage}
The subimage or face within the file to use for the texture lookup.
The default is 0, and larger values only make sense for a texture file
that supports subimages or separate images per face (such as Ptex).
This will be ignored if the file does not have multiple subimages or
separate per-face textures.
\apiend

\apiitem{Wrap swrap, twrap}
Specify the \emph{wrap mode} for 2D texture lookups (and 3D volume
texture lookups, using the additional {\cf rwrap} field).  These fields
are ignored for shadow and environment lookups.

These specify what happens when texture coordinates are found to be
outside the usual $[0,1]$ range over which the texture is defined.
{\cf Wrap} is an enumerated type that may take on any of the
following values:
\begin{description}
\item[\spc] \spc
\item[\rm \kw{WrapBlack}] The texture is black outside the [0,1] range.
\item[\rm \kw{WrapClamp}] The texture coordinates will be clamped to
  [0,1], i.e., the value outside [0,1] will be the same as the color
  at the nearest point on the border.
\item[\rm \kw{WrapPeriodic}] The texture is periodic, i.e., wraps back
  to 0 after going past 1.
\item[\rm \kw{WrapMirror}] The texture presents a mirror image at the
  edges, i.e., the coordinates go from 0 to 1, then back down to 0, then
  back up to 1, etc.
\item[\rm \kw{WrapDefault}] Use whatever wrap might be specified in the
  texture file itself, or some other suitable default (caveat emptor).
\end{description}

The wrap mode does not need to be identical in the $s$ and $t$
directions.
\apiend

\apiitem{VaryingRef<float> swidth, twidth}
For each direction, gives a multiplier for the derivatives.  Note that
a width of 0 indicates a point sampled lookup (assuming that blur is
also zero).  The default width is 1, indicating that the derivatives
should guide the amount of blur applied to the texture filtering (not
counting any additional \emph{blur} specified).
\apiend

\apiitem{VaryingRef<float> sblur, tblur}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.  In other words,
blur = 0.1 means that the texture lookup should act as if the texture
was pre-blurred with a filter kernel with a width 1/10 the size of the
full image.  The default blur amount is 0, indicating a sharp texture
lookup.
\apiend

\apiitem{VaryingRef<float> fill}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the lsat channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

\apiitem{VaryingRef<float> missingcolor}
If supplied, indicates that a missing or broken texture should \emph{not}
be treated as an error, but rather will simply return the supplied color
as the texture lookup color and {\cf texture()} will return {\cf true}.  
If the {\cf missingcolor} field is left at its default (a NULL pointer),
a missing or broken texture will be treated as an error and
{\cf texture()} will return {\cf false}.

Although this is a {\cf VaryingRef<float>}, the data must point to
\emph{nchannels} contiguous floats, and if ``varying,'' the step size must
be set to {\cf nchannels*sizeof(float)}, not {\cf sizeof(float)}.
\apiend

\apiitem{float *dresultds, *dresultdt}
If not NULL (the default), these specify locations in which to store
the \emph{derivatives} of the texture lookup, i.e., the change of the
filtered texture per unit of $s$ and $t$, respectively.  Each must point
to {\cf nchannels} contiguous floats.  If either is NULL, the derivative
computations will not be performed.
\apiend

\apiitem{VaryingRef<float> bias}
For shadow map lookups only, this gives the ``shadow bias'' amount.
\apiend

\apiitem{VaryingRef<int> samples}
For shadow map lookups only, the number of samples to use for each lookup.
\apiend

\apiitem{Wrap rwrap \\
VaryingRef<float> rblur, rwidth \\
float *dresultdr}
Specifies wrap, blur, width, and derivative results for the third
component of 3D volume texture lookups.  These are not used for 2D
texture lookups.
\apiend

\subsection{{\cf VaryingRef}: encapsulate uniform and varying}

Many texture access API routines are designed to look up
texture efficiently at many points at once.  Therefore, many of
the parameters to the API routines, and many of the fields in
\TextureOptions need to accommodate both uniform and varying values.
\emph{Uniform} means that a single value may be used for each of
the many simultaneous texture lookups, whereas \emph{varying} means
that a different value is provided for each of the positions where
you are sampling the texture.

Please read the comments in \qkw{varyingref.h} for the full gory 
details, but here's all you really need to know about it to use the
texture functionality.  Let's suppose that we have a routine 
whose prototype looks like this:

\begin{code}
        void API (int n, VaryingRef<float> x);
\end{code}

\noindent This means that parameter $x$ may either be a single value
for use at each of the $n$ texture lookups, or it may have $n$ different
values of $x$.  

If you want to pass a uniform value, you may do any of the following:

\begin{code}
      float x;   // just one value
      API (n, x);   // automatically knows what to do!
      API (n, &x);  // Also ok to pass the pointer to x
      API (n, VaryingRef<float>(x));  // Wordy but correct
      API (n, Uniform(x));  // Shorthand
\end{code}

If you want to pass a varying value, i.e., an array of values,

\begin{code}
      float x[n];   // One value for each of n points
      API (n, VaryingRef<float>(x), sizeof(x));  // Wordy but correct
      API (n, Varying(x));  // Shorthand if stride is sizeof(x)
\end{code}

You can also initialize a VaryingRef directly:

\begin{code}
    float x;     // just one value
    float y[n];  // array of values
    VaryingRef<float> r;
    r.init (&x);                 // Initialize to uniform
    r.init (&x, 0);              // Initialize to uniform the wordy way
    r.init (&y, sizeof(float));  // Initialize to varying
    ...
    API (n, r);
\end{code}


\subsection{SIMD Run Flags}

Many of the texture lookup API routines are written to accommodate
queries about many points at once.  Furthermore, only a subset of
points may need to compute.  This is all expressed using three
parameters:  {\cf Runflag *runflags, int beginactive, int endactive}.
There are also {\cf VaryingRef} parameters such as {\cf s} and {\cf t}
that act as if they are arrays.

The {\cf beginactive} and {\cf endactive} indices are the first
(inclusive) and
last (exclusive) points that should be computed, and for each point
{\cf runflags[i]} is nonzero if the point should be computed.  To
illustrate, here is how a routine might be written that would copy
values in {\cf arg} to {\cf result} using runflags:

\begin{code}
        void copy (Runflag *runflags, int beginactive, int endactive,
                   VaryingRef<float> arg, VaryingRef <float> result)
        {
            for (int i = beginactive; i < endactive;  ++i)
                if (runflags[i])
                    result[i] = arg[i];
        }
\end{code}


\newpage
\section{TextureSystem API}
\label{sec:texturesys:api}

\subsection{Creating and destroying texture systems}
\label{sec:texturesys:api:createdestroy}

\TextureSystem is an abstract API described as a pure
virtual class.  The actual internal implementation is not exposed
through the external API of \product.  Because of this, you cannot
construct or destroy the concrete implementation, so two static
methods of \TextureSystem are provided:

\apiitem{static TextureSystem *TextureSystem::{\ce create} (bool share=true)}
Creates a new \TextureSystem and returns a pointer to it.
If {\cf shared} is {\cf true}, the \TextureSystem created will share its
underlying \ImageCache with any other \TextureSystem's or \ImageCache's
that requested shared caches.  If {\cf shared} is {\cf false}, a
completely unique \ImageCache will be created that is private to this
particular \TextureSystem.
\apiend

\apiitem{static void TextureSystem::{\ce destroy} (TextureSystem *x, \\
\bigspc\bigspc bool teardown_imagecache=false)}
Destroys an allocated \TextureSystem, including freeing all system
resources that it holds (such as its underlying \ImageCache).

This is necessary to ensure that the memory is freed in a way that
matches the way it was allocated within the library.  Note that simply
using {\cf delete} on the pointer will not always work (at least,
not on some platforms in which a DSO/DLL can end up using a different
allocator than the main program).

If {\cf teardown_imagecache} is {\cf true}, and the \TextureSystem's
underlying \ImageCache is the \emph{shared} one, then that \ImageCache will
be thoroughly destroyed, not merely releasing the reference. \apiend

\subsection{Setting options and limits for the texture system}
\label{sec:texturesys:api:options}

The following member functions of \TextureSystem allow you to set
(and in some cases retrieve) options that control the overall
behavior of the texture system:

\apiitem{bool {\ce attribute} (string_view name, TypeDesc type,
  const void *val)}
\indexapi{attribute}

Sets an attribute (i.e., a property or option) of the \TextureSystem.
The {\cf name} designates the name of the attribute, {\cf type}
describes the type of data, and {\cf val} is a pointer to memory 
containing the new value for the attribute.

If the \TextureSystem recognizes a valid attribute name that matches the
type specified, the attribute will be set to the new value and {\cf
  attribute()} will return {\cf true}.  If {\cf name} is not recognized
as a valid attribute name, or if the types do not match (e.g., {\cf
  type} is {\cf TypeDesc::FLOAT} but the named attribute is a string),
the attribute will not be modified, and {\cf attribute()} will return
{\cf false}.

Here are examples:

\begin{code}
      TextureSystem *ts; 
      ...
      int maxfiles = 50;
      ts->attribute ("max_open_files", TypeDesc::INT, &maxfiles);

      const char *path = "/my/path";
      ts->attribute ("searchpath", TypeDesc::STRING, &path);
\end{code}

Note that when passing a string, you need to pass a pointer to the {\cf
  char*}, not a pointer to the first character.  (Rationale: for an {\cf
  int} attribute, you pass the address of the {\cf int}.  So for a
string, which is a {\cf char*}, you need to pass the address of the
string, i.e., a {\cf char**}).

The complete list of attributes can be found at the end of this section.

\apiend

\apiitem{bool {\ce attribute} (string_view name, int val) \\
bool {\ce attribute} (string_view name, float val) \\
bool {\ce attribute} (string_view name, double val) \\
bool {\ce attribute} (string_view name, string_view val)}
Specialized versions of {\cf attribute()} in which the data type is
implied by the type of the argument.

For example, the following are equivalent to the example above for the
general (pointer) form of {\cf attribute()}:

\begin{code}
      ts->attribute ("max_open_files", 50);
      ts->attribute ("searchpath", "/my/path");
\end{code}

\apiend


\apiitem{bool {\ce getattribute} (string_view name, TypeDesc type,
  void *val)}
\indexapi{getattribute}

Gets the current value of an attribute of the \TextureSystem.
The {\cf name} designates the name of the attribute, {\cf type}
describes the type of data, and {\cf val} is a pointer to memory 
where the user would like the value placed.

If the \TextureSystem recognizes a valid attribute name that matches the
type specified, the attribute value will be stored at address {\cf val}
and {\cf attribute()} will return {\cf true}.  If {\cf name} is not recognized
as a valid attribute name, or if the types do not match (e.g., {\cf
  type} is {\cf TypeDesc::FLOAT} but the named attribute is a string),
no data will be written to {\cf val}, and {\cf attribute()} will return
{\cf false}.

Here are examples:

\begin{code}
      TextureSystem *ts; 
      ...
      int maxfiles;
      ts->getattribute ("max_open_files", TypeDesc::INT, &maxfiles);

      const char *path;
      ts->getattribute ("searchpath", TypeDesc::STRING, &path);
\end{code}

Note that when passing a string, you need to pass a pointer to the {\cf
  char*}, not a pointer to the first character.  Also, the {\cf char*}
will end up pointing to characters owned by the \TextureSystem; the
caller does not need to ever free the memory that contains the
characters.

The complete list of attributes can be found at the end of this section.


\apiend

\apiitem{bool {\ce getattribute} (string_view name, int \&val) \\
bool {\ce getattribute} (string_view name, float \&val) \\
bool {\ce getattribute} (string_view name, double \&val) \\
bool {\ce getattribute} (string_view name, char **val) \\
bool {\ce getattribute} (string_view name, std::string \& val)}
Specialized versions of {\cf getattribute()} in which the data type is
implied by the type of the argument.

For example, the following are equivalent to the example above for the
general (pointer) form of {\cf getattribute()}:

\begin{code}
      int maxfiles;
      ts->getattribute ("max_open_files", &maxfiles);
      const char *path;
      ts->getattribute ("searchpath", &path);
\end{code}

\apiend


\subsubsection*{Texture system attributes}
\label{sec:texturesys:attributes}

Recognized attributes include the following:

\apiitem{int max_open_files \\
float max_memory_MB \\
string searchpath \\
string plugin_searchpath \\
int autotile \\
int autoscanline \\
int automip \\
int accept_untiled \\
int accept_unmipped \\
int failure_retries \\
int deduplicate \\
string substitute_image}

These attributes are all passed along to the underlying \ImageCache that
is used internally by the \TextureSystem.  Please consult the
\ImageCache attribute list in Section~\ref{sec:imagecache:api:attribute}
for explanations of these attributes.

\apiend

\apiitem{matrix worldtocommon}
The $4 \times 4$ matrix that provides the spatial transformation
from ``world'' to a ``common'' coordinate system.  This is used for
shadow map lookups, in which the shadow map itself encodes the
world coordinate system, but positions passed to {\cf shadow()} are
expressed in ``common'' coordinates.
\apiend

\apiitem{matrix commontoworld}
The $4 \times 4$ matrix that is the inverse of {\cf worldtocommon} ---
that is, it transforms points from ``common'' to ``world'' coordinates.

You do not need to set {\cf commontoworld} and {\cf worldtocommon}
separately; just setting either one will implicitly set the other, since
each is the inverse of the other.
\apiend

\apiitem{int gray_to_rgb}
If set to nonzero, texture lookups of single-channel (grayscale) 
images will replicate the sole channel's values into the next two
channels, making it behave like an RGB image that happens to have all
three channels with identical pixel values.  (Channels beyond the third
will get the ``fill'' value.)

The default value of zero means that all missing channels will get
the ``fill'' color.
\apiend

\apiitem{string latlong_up}
Sets the default ``up'' direction for latlong environment maps (only
applies if the map itself doesn't specify a format or is in a format
that explicitly requires a particular orientation).  The default is
\qkw{y}.  (Currently any other value will result in $z$ being ``up.'')
\apiend

\apiitem{string options}
This catch-all is simply a comma-separated list of {\cf name=value}
settings of named options.  For example,
\begin{code}
        ic->attribute ("options", "max_memory_MB=512.0,autotile=1");
\end{code}
\apiend



\subsection{Opaque data for performance lookups}
\label{sec:texturesys:api:opaque}

\apiitem{Perthread * {\ce get_perthread_info} ()}
\indexapi{get_perthread_info}

Retrieves an opaque handle for per-thread info, to be used for
{\cf get_texture_handle()} and the texture routines that take handles
directly.
\apiend

\apiitem{TextureHandle * {\ce get_texture_handle} (ustring filename,\\
\bigspc\bigspc\bigspc  Perthread *thread_info=NULL)}
\indexapi{get_texture_handle}

Retrieve an opaque handle for fast texture lookups.  The opaque
pointer {\cf thread_info} is thread-specific information returned by
{\cf get_perthread_info()}.  Return {\cf NULL} if something has gone
horribly wrong.

\apiend


%\newpage
\subsection{Texture Lookups}
\label{sec:texturesys:api:texture}

\apiitem{bool {\ce texture} (ustring filename, TextureOpt \&options,\\
\bigspc                   float s, float t, float dsdx, float dtdx,\\
\bigspc                   float dsdy, float dtdy, float *result)}
\indexapi{texture}

Perform a filtered 2D texture lookup on a position centered at 2D
coordinates ({\cf s}, {\cf t}) from the texture identified by
{\cf filename}, and using relevant texture {\cf options}.  The filtered
results will be stored in {\cf result[]}.

We assume that this lookup will be part of an image that has pixel
coordinates {\cf x} and {\cf y}.  By knowing how {\cf s} and {\cf t}
change from pixel to pixel in the final image, we can properly
\emph{filter} or antialias the texture lookups.  This information is
given via derivatives {\cf dsdx} and {\cf dtdx} that define the change
in {\cf s} and {\cf t} per unit of {\cf x}, and {\cf dsdy} and {\cf
  dtdy} that define the change in {\cf s} and {\cf t} per unit of {\cf
  y}.  If it is impossible to know the derivatives, you may pass 0 for
them, but in that case you will not receive an antialiased texture lookup.

Fields within {\cf options} that are honored for 2D texture lookups
include the following:

\vspace{-12pt}
\apiitem{int nchannels}
\vspace{10pt}
The number of color channels to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{int firstchannel}
\vspace{10pt}
The index of the first channel to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{int subimage}
\vspace{10pt}
The subimage or face within the file.
This will be ignored if the file does not have multiple subimages or
separate per-face textures.
\apiend

\vspace{-24pt}
\apiitem{Wrap swrap, twrap}
\vspace{10pt}
Specify the \emph{wrap mode} for each direction, one of: 
{\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror},
or {\cf WrapDefault}.
\apiend

\vspace{-24pt}
\apiitem{float swidth, twidth}
\vspace{10pt}
For each direction, gives a multiplier for the derivatives.
\apiend

\vspace{-24pt}
\apiitem{float sblur, tblur}
\vspace{10pt}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.
\apiend

\vspace{-24pt}
\apiitem{float fill}
\vspace{10pt}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the last channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

\vspace{-24pt}
\apiitem{const float *missingcolor}
\vspace{10pt}
If not NULL, specifies the color that will be returned for missing or
broken textures (rather than being an error).
\apiend

\vspace{-24pt}
\apiitem{float *dresultds, *dresultdt}
\vspace{10pt}
If not NULL, specifies locations in which to store the $s$ and $t$
derivatives of the filtered texture lookup.
\apiend

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend


\apiitem{bool {\ce texture} (TextureHandle *texture_handle,
                          Perthread *thread_info, \\
\bigspc                   TextureOpt \&options,\\
\bigspc                   float s, float t, float dsdx, float dtdx,\\
\bigspc                   float dsdy, float dtdy, float *result)}
A slightly faster {\cf texture} call for applications that are willing
to do the extra housekeeping of knowing the handle of the texture they
are accessing and the per-thread info for the curent thread.  These
may be retrieved by the {\cf get_texture_handle()} and 
{\cf get_perthread_info()} methods, respectively.
\apiend

\apiitem{bool {\ce texture} (ustring filename, TextureOptions \&options,\\
\bigspc                   Runflag *runflags, int beginactive, int endactive,\\
\bigspc                   VaryingRef<float> s, VaryingRef<float> t,\\
\bigspc                   VaryingRef<float> dsdx, VaryingRef<float> dtdx,\\
\bigspc                   VaryingRef<float> dsdy, VaryingRef<float> dtdy,\\
\bigspc                   float *result)}

Perform filtered 2D texture lookups on a collection of positions all at
once, which may be much more efficient than repeatedly calling the
single-point version of {\cf texture()}.  The parameters {\cf s},
{\cf t}, {\cf dsdx}, {\cf dtdx}, and {\cf dsdy}, {\cf dtdy} are now
{\cf VaryingRef}'s that may refer to either a single or an array of
values, as are many of the fields in the {\cf options}.

Texture will be computed at indices {\cf beginactive} through
{\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]}
is nonzero.  Results will be stored at corresponding positions of
{\cf result}, that is, 
{\cf result[i*n ... (i+1)*n-1]} where $n$ is the number of channels
requested by {\cf options.nchannels}.

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

%\newpage
\subsection{Volume Texture Lookups}
\label{sec:texturesys:api:texture3d}

\apiitem{bool {\ce texture3d} (ustring filename, TextureOpt \&options,\\
\bigspc\spc                    const Imath::V3f \&P, const Imath::V3f \&dPdx,\\
\bigspc\spc                    const Imath::V3f \&dPdy, const Imath::V3f \&dPdz,\\
\bigspc\spc                    float *result)}
\indexapi{texture3d}

Perform a filtered 3D volumetric texture lookup on a position centered at
3D position {\cf P} from the texture identified by
{\cf filename}, and using relevant texture {\cf options}.  The filtered
results will be stored in {\cf result[]}.

We assume that this lookup will be part of an image that has pixel
coordinates {\cf x} and {\cf y} and depth {\cf z}.  
By knowing how {\cf P} changes from
pixel to pixel in the final image, and as we step in $z$ depth, we can properly \emph{filter} or
antialias the texture lookups.  This information is given via
derivatives {\cf dPdx}, {\cf dPdy}, and {\cf dPdz} that define the changes in {\cf P}
per unit of {\cf x}, {\cf y}, and {\cf z}, respectively.  If it is impossible to
know the derivatives, you may pass 0 for them, but in that case you will
not receive an antialiased texture lookup.

The {\cf P} coordinate and {\cf dPdx}, {\cf dPdy}, and {\cf dPdz}
derivatives are assumed to be in some kind of common global coordinate
system (usually \qkw{world} space) and will be automatically transformed
into volume local coordinates, if such a transormation is specified in
the volume file itself.

Fields within {\cf options} that are honored for 3D texture lookups
include the following:

\vspace{-12pt}
\apiitem{int nchannels}
\vspace{10pt}
The number of color channels to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{int firstchannel}
\vspace{10pt}
The index of the first channel to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{Wrap swrap, twrap, rwrap}
\vspace{10pt}
Specify the wrap modes for each direction, one of: 
{\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror},
or {\cf WrapDefault}.
\apiend

\vspace{-24pt}
\apiitem{float swidth, twidth, rwidth}
\vspace{10pt}
For each direction, gives a multiplier for the derivatives.
\apiend

\vspace{-24pt}
\apiitem{float sblur, tblur, rblur}
\vspace{10pt}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.
\apiend

\vspace{-24pt}
\apiitem{float fill}
\vspace{10pt}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the last channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

\vspace{-24pt}
\apiitem{const float *missingcolor}
\vspace{10pt}
If not NULL, specifies the color that will be returned for missing or
broken textures (rather than being an error).
\apiend

\vspace{-24pt}
\apiitem{float time}
\vspace{10pt}
A time value to use if the volume texture specifies a time-varying
local transformation (default: 0).
\apiend

\vspace{-24pt}
\apiitem{float *dresultds, *dresultdt, *dresultdr}
\vspace{10pt}
If not NULL, specifies locations in which to store the $s$, $t$, and $r$
derivatives of the filtered texture lookup.
\apiend

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.

\apiend

\apiitem{bool {\ce texture3d} (TextureHandle *texture_handle,
                          Perthread *thread_info, \\
\bigspc                   TextureOpt \&opt,\\
\bigspc                          const Imath::V3f \&P,\\
\bigspc                          const Imath::V3f \&dPdx,\\
\bigspc                          const Imath::V3f \&dPdy,\\
\bigspc                          const Imath::V3f \&dPdz,\\
\bigspc                          float *result)}
A slightly faster {\cf texture3d} call for applications that are willing
to do the extra housekeeping of knowing the handle of the texture they
are accessing and the per-thread info for the curent thread.  These
may be retrieved by the {\cf get_texture_handle()} and 
{\cf get_perthread_info()} methods, respectively.
\apiend

\apiitem{bool {\ce texture3d} (ustring filename, TextureOptions \&options,\\
\bigspc                          Runflag *runflags, int beginactive, int endactive,\\
\bigspc                          VaryingRef<Imath::V3f> P,\\
\bigspc                          VaryingRef<Imath::V3f> dPdx,\\
\bigspc                          VaryingRef<Imath::V3f> dPdy,\\
\bigspc                          VaryingRef<Imath::V3f> dPdz,\\
\bigspc                          float *result)}

Perform filtered 3D volumetric texture lookups on a collection of positions all at
once, which may be much more efficient than repeatedly calling the
single-point version of {\cf texture()}.  The parameters {\cf P},
{\cf dPdx}, {\cf dPdy}, and {\cf dPdz} are now
{\cf VaryingRef}'s that may refer to either a single or an array of
values, as are all the fields in the {\cf options}.

Texture will be computed at indices {\cf beginactive} through
{\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]}
is nonzero.  Results will be stored at corresponding positions of
{\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ 
is the number of channels requested by {\cf options.nchannels}.

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

%\newpage
\subsection{Shadow Lookups}
\label{sec:texturesys:api:shadow}

\apiitem{bool {\ce shadow} (ustring filename, TextureOpt \&opt,\\
\bigspc                         const Imath::V3f \&P, const Imath::V3f \&dPdx,\\
\bigspc                         const Imath::V3f \&dPdy, float *result)}
\indexapi{shadow}

Perform a shadow map lookup on a position centered at 3D
coordinate {\cf P} (in a designated ``common'' space) from the shadow map identified by
{\cf filename}, and using relevant texture {\cf options}.  The filtered
results will be stored in {\cf result[]}.

We assume that this lookup will be part of an image that has pixel
coordinates {\cf x} and {\cf y}.  By knowing how {\cf P} changes from
pixel to pixel in the final image, we can properly \emph{filter} or
antialias the texture lookups.  This information is given via
derivatives {\cf dPdx} and {\cf dPdy} that define the changes in {\cf P}
per unit of {\cf x} and {\cf y}, respectively.  If it is impossible to
know the derivatives, you may pass 0 for them, but in that case you will
not receive an antialiased texture lookup.

Fields within {\cf options} that are honored for 2D texture lookups
include the following:

\vspace{-12pt}
\apiitem{float swidth, twidth}
\vspace{10pt}
For each direction, gives a multiplier for the derivatives.
\apiend

\vspace{-24pt}
\apiitem{float sblur, tblur}
\vspace{10pt}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.
\apiend

\vspace{-24pt}
\apiitem{float bias}
\vspace{10pt}
Specifies the amount of \emph{shadow bias} to use --- this effectively
ignores shadow occlusion that is closer than the bias amount to the
surface, helping to eliminate self-shadowing artifacts.
\apiend

\vspace{-24pt}
\apiitem{int samples}
\vspace{10pt}
Specifies the number of samples to use when evaluating the shadow map.
More samples will give a smoother, less noisy, appearance to the
shadows, but may also take longer to compute.
\apiend

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

\apiitem{bool {\ce shadow} (TextureHandle *texture_handle,
                          Perthread *thread_info, \\
\bigspc                   TextureOpt \&opt,\\
\bigspc                         const Imath::V3f \&P,\\
\bigspc                         const Imath::V3f \&dPdx,\\
\bigspc                         const Imath::V3f \&dPdy,\\
\bigspc                         float *result)}
A slightly faster {\cf shadow} call for applications that are willing
to do the extra housekeeping of knowing the handle of the texture they
are accessing and the per-thread info for the curent thread.  These
may be retrieved by the {\cf get_texture_handle()} and 
{\cf get_perthread_info()} methods, respectively.
\apiend

\apiitem{bool {\ce shadow} (ustring filename, TextureOptions \&options,\\
\bigspc                         Runflag *runflags, int beginactive, int endactive,\\
\bigspc                         VaryingRef<Imath::V3f> P,\\
\bigspc                         VaryingRef<Imath::V3f> dPdx,\\
\bigspc                         VaryingRef<Imath::V3f> dPdy,\\
\bigspc                         float *result)}

Perform filtered shadow map lookups on a collection of positions all at
once, which may be much more efficient than repeatedly calling the
single-point version of {\cf shadow()}.  The parameters {\cf P},
{\cf dPdx}, and {\cf dPdy} are now
{\cf VaryingRef}'s that may refer to either a single or an array of
values, as are many the fields in the {\cf options}.

Shadow lookups will be computed at indices {\cf beginactive} through
{\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]}
is nonzero.  Results will be stored at corresponding positions of
{\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ 
is the number of channels requested by {\cf options.nchannels}.

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

%\newpage
\subsection{Environment Lookups}
\label{sec:texturesys:api:environment}

\apiitem{bool {\ce environment} (ustring filename, TextureOpt \&options,\\
\bigspc                              const Imath::V3f \&R, const Imath::V3f \&dRdx,\\
\bigspc                              const Imath::V3f \&dRdy, float *result)}
\indexapi{environment}

Perform a filtered directional environment map lookup in the direction
of vector {\cf R}, from the texture identified by {\cf filename}, and
using relevant texture {\cf options}.  The filtered results will be
stored in {\cf result[]}.

We assume that this lookup will be part of an image that has pixel
coordinates {\cf x} and {\cf y}.  By knowing how {\cf R} changes from
pixel to pixel in the final image, we can properly \emph{filter} or
antialias the texture lookups.  This information is given via
derivatives {\cf dRdx} and {\cf dRdy} that define the changes in {\cf R}
per unit of {\cf x} and {\cf y}, respectively.  If it is impossible to
know the derivatives, you may pass 0 for them, but in that case you will
not receive an antialiased texture lookup.

Fields within {\cf options} that are honored for 3D texture lookups
include the following:

\vspace{-12pt}
\apiitem{int nchannels}
\vspace{10pt}
The number of color channels to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{int firstchannel}
\vspace{10pt}
The index of the first channel to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{float swidth, twidth}
\vspace{10pt}
For each direction, gives a multiplier for the derivatives.
\apiend

\vspace{-24pt}
\apiitem{float sblur, tblur}
\vspace{10pt}
For each direction, specifies an additional amount of pre-blur to apply
to the texture (\emph{after} derivatives are taken into account),
expressed as a portion of the width of the texture.
\apiend

\vspace{-24pt}
\apiitem{float fill}
\vspace{10pt}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the last channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

\apiitem{bool {\ce environment} (TextureHandle *texture_handle,
                          Perthread *thread_info, \\
\bigspc                   TextureOpt \&opt,\\
\bigspc                              const Imath::V3f \&R,\\
\bigspc                              const Imath::V3f \&dRdx,\\
\bigspc                              const Imath::V3f \&dRdy,\\
\bigspc                              float *result)}
A slightly faster {\cf environment} call for applications that are willing
to do the extra housekeeping of knowing the handle of the texture they
are accessing and the per-thread info for the curent thread.  These
may be retrieved by the {\cf get_texture_handle()} and 
{\cf get_perthread_info()} methods, respectively.
\apiend

\apiitem{bool {\ce environment} (ustring filename, TextureOptions \&options,\\
\bigspc                              Runflag *runflags, int beginactive, int endactive,\\
\bigspc                              VaryingRef<Imath::V3f> R,\\
\bigspc                              VaryingRef<Imath::V3f> dRdx,\\
\bigspc                              VaryingRef<Imath::V3f> dRdy,\\
\bigspc                              float *result)}

Perform filtered directional environment map lookups on a collection of
directions all at once, which may be much more efficient than repeatedly
calling the single-point version of {\cf environment()}.  The parameters
{\cf R}, {\cf dRdx}, and {\cf dRdy} are now {\cf VaryingRef}'s that may
refer to either a single or an array of values, as are many the fields in
the {\cf options}.

Results will be computed at indices {\cf beginactive} through
{\cf endactive} (exclusive of the end), but only at indices where {\cf runflags[i]}
is nonzero.  Results will be stored at corresponding positions of
{\cf result}, that is, {\cf result[i*n ... (i+1)*n-1]} where $n$ 
is the number of channels requested by {\cf options.nchannels}.

This function returns {\cf true} upon success, or {\cf false} if the
file was not found or could not be opened by any available ImageIO
plugin.
\apiend

%\newpage
\subsection{Texture Metadata and Raw Texels}
\label{sec:texturesys:api:gettextureinfo}
\label{sec:texturesys:api:getimagespec}

\apiitem{bool {\ce get_texture_info} (ustring filename, int subimage, \\
\bigspc\spc\spc ustring dataname, TypeDesc datatype, void *data)}

Retrieves information about the texture named by {\cf filename}.
The {\cf dataname} is a keyword indcating what information should
be retrieved, {\cf datatype} is the type of data expected, and
{\cf data} points to caller-owned memory where the results should be
placed.  It is up to the caller to ensure that {\cf data} contains
enough space to hold an item of the requested {\cf datatype}.

The return value is {\cf true} if {\cf get_texture_info()} is able
to find the requested {\cf dataname} and it matched the requested
{\cf datatype}.  If the requested data was not found, or was not
of the right data type, {\cf get_texture_info()} will return {\cf false}.

Supported {\cf dataname} values include:

\begin{description}
\item[\spc] \spc \vspace{-12pt} 
\item[\rm \kw{exists}] Return 1 if the file exists and
is an image format that OpenImageIO knows how to read, otherwise return
0.  The {\cf data} pointer is not used.

\item[\rm \kw{subimages}] The number of subimages/faces in the file, as an integer.

\item[\rm \kw{resolution}] The resolution of the texture file, which
is an array of 2 integers (described as {\cf TypeDesc(INT,2)}).

\item[\rm \kw{resolution} (int[3])] The 3D resolution of the texture file, which
is an array of 3 integers (described as {\cf TypeDesc(INT,3)})  The
third value will e 1 unless it's a volumetric (3D) image.

\item[\rm \kw{miplevels}] The number of MIPmap levels for the specified
subimage (an integer).

\item[\rm \kw{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: \qkw{unknown}, \qkw{Plain Texture},
\qkw{Volume Texture}, \qkw{Shadow}, 
or \qkw{Environment}.

\item[\rm \kw{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: \qkw{unknown}, \qkw{Plain Texture},
\qkw{Volume Texture}, \qkw{Shadow}, \qkw{CubeFace Shadow}, \qkw{Volume
  Shadow}, \qkw{LatLong Environment}, or \qkw{CubeFace Environment}.
Note that there are several kinds of shadows and environment maps,
all accessible through the same API calls.

\item[\rm \kw{channels}] The number of color channels in the file 
(an integer).

\item[\rm \kw{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).

\item[\rm \kw{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).

\item[\rm \kw{viewingmatrix}] The viewing matrix, which is a
$4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf
  TypeDesc(FLOAT,MATRIX)}).

\item[\rm \kw{projectionmatrix}] The projection matrix, which is a
$4 \times 4$ matrix (an {\cf Imath::M44f}, described as {\cf
  TypeDesc(FLOAT,MATRIX)}).

\item[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.

\end{description}
\apiend

\apiitem{bool {\ce get_imagespec} (ustring filename, int subimage, ImageSpec \&spec)}

If the named image is found and able to be opened by an available
image format plugin, this function copies its image specification into
{\cf spec} and returns {\cf true}.  Otherwise, if the file is not
found, could not be opened, or is not of a format readable by any
plugin that could be found, the return value is {\cf false}.
\apiend


\apiitem{const ImageSpec * {\ce imagespec} (ustring filename, int subimage)}

If the named image is found and able to be opened by an available
image format plugin, and the designated subimage exists, this function
returns a pointer to an \ImageSpec that describes it.  Otherwise, if the
file is not found, could not be opened, is not of a format readable by
any plugin that could be find, or the designated subimage did
not exist in the file, the return value is NULL.

This method is much more efficient than {\cf get_imagespec()}, since it
just returns a pointer to the spec held internally by the underlying \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) calls {\cf invalidate()} on the file, or {\cf
  invalidate_all()}, or destroys the \TextureSystem.
\apiend

\apiitem{bool {\ce get_texels} (ustring filename, TextureOpt \&options, int level, \\
\bigspc                       int xbegin, int xend, int ybegin, int yend,\\
\bigspc                       int zbegin, int zend, TypeDesc format, void *result)}

Retrieve a rectangle of raw unfiltered texels at the named MIP-map level, storing
the texel values beginning at the address specified by result.
Note that the face/subimage is communicated through {\kw options.subimage}.
The texel values will be converted to the type specified by
format.  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).  The rectangular region to be
retrieved includes {\cf begin} but does not include {\cf end} (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.

Fields within {\cf options} that are honored for raw texel retieval
include the following:

\vspace{-12pt}
\apiitem{int subiamge}
\vspace{10pt}
The subimage to retrieve.
\apiend

\vspace{-24pt}
\apiitem{int nchannels}
\vspace{10pt}
The number of color channels to look up from the texture.
\apiend

\vspace{-24pt}
\apiitem{int firstchannel}
\vspace{10pt}
The index of the first channel to look up from the texture.
\apiend

% FIXME -- we should support this
%\vspace{-24pt}
%\apiitem{Wrap swrap, twrap}
%\vspace{10pt}
%Specify the \emph{wrap mode} for each direction, one of: 
%{\cf WrapBlack}, {\cf WrapClamp}, {\cf WrapPeriodic}, {\cf WrapMirror},
%or {\cf WrapDefault}.
%\apiend

\vspace{-24pt}
\apiitem{float fill}
\vspace{10pt}
Specifies the value that will be used for any color channels that are
requested but not found in the file.  For example, if you perform a
4-channel lookup on a 3-channel texture, the last channel will
get the fill value.  (Note: this behavior is affected by the
\qkw{gray_to_rgb} attribute described in 
Section~\ref{sec:texturesys:attributes}.)
\apiend

Return true if the file is found and could be opened by an
available ImageIO plugin, otherwise return false.

\apiend

\apiitem{std::string {\ce resolve_filename} (const std::string \&filename)}
Returns the true path to the given file name, with searchpath logic
applied.
\apiend

\subsection{Miscellaneous -- Statistics, errors, flushing the cache}
\label{sec:texturesys:api:geterror}
\label{sec:texturesys:api:getstats}
\label{sec:texturesys:api:resetstats}
\label{sec:texturesys:api:invalidate}

\apiitem{std::string {\ce geterror} ()}
\index{error checking}
If any other API routines return {\cf false}, indicating that an
error has occurred, this routine will retrieve the error and clear
the error status.  If no error has occurred since the last time
{\cf geterror()} was called, it will return an empty string.
\apiend

\apiitem{std::string {\ce getstats} (int level=1, bool icstats=true)}
Returns a big string containing useful statistics about the \ImageCache
operations, suitable for saving to a file or outputting to the terminal.
The {\cf level} indicates the amount of detail in the statistics,
with higher numbers (up to a maximum of 5) yielding more and more
esoteric information.  If {\cf icstats} is true, the returned string
will also contain all the statistics of the underlying \ImageCache,
but if false will only contain texture-specific statistics.
\apiend

\apiitem{void {\ce 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.
\apiend

\apiitem{void {\ce invalidate} (ustring filename)}
Invalidate any loaded tiles or open file handles associated with
the filename, 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.
\apiend

\apiitem{void {\ce invalidate_all} (bool force=false)}
Invalidate all loaded tiles and open file handles, 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,
everything will be invalidated, no matter how wasteful it is, but if
force is false, in actuality files will only be invalidated if their
modification times have been changed since they were first opened.
\apiend

\index{Texture System|)}

\chapwidthend
