\chapter{ImageOutput: Writing Images}
\label{chap:imageoutput}
\index{Image I/O API|(}
\indexapi{ImageOutput}


\section{Image Output Made Simple}
\label{sec:imageoutput:simple}

Here is the simplest sequence required to write the pixels of a 2D image
to a file:

\begin{code}
        #include <OpenImageIO/imageio.h>
        using namespace OIIO;
        ...

        const char *filename = "foo.jpg";
        const int xres = 640, yres = 480;
        const int channels = 3;  // RGB
        unsigned char pixels[xres*yres*channels];

        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (! out)
            return;
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
        out->open (filename, spec);
        out->write_image (TypeDesc::UINT8, pixels);
        out->close ();
\end{code}

\noindent This little bit of code does a surprising amount of useful work:  

\begin{itemize}
\item Search for an ImageIO plugin that is capable of writing the file
  (\qkw{foo.jpg}), deducing the format from the file extension.  When it
  finds such a plugin, it creates a subclass instance of \ImageOutput
  that writes the right kind of file format.
  \begin{code}
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
  \end{code}
\item Open the file, write the correct headers, and in all other
  important ways prepare a file with the given dimensions ($640 \times
  480$), number of color channels (3), and data format (unsigned 8-bit
  integer).
  \begin{code}
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
        out->open (filename, spec);
  \end{code}
\item Write the entire image, hiding all details of the encoding of
  image data in the file, whether the file is scanline- or tile-based,
  or what is the native format of data in the file (in this case, our
  in-memory data is unsigned 8-bit and we've requested the same format
  for disk storage, but if they had been different, {\kw write_image()}
  would do all the conversions for us).
  \begin{code}
        out->write_image (TypeDesc::UINT8, &pixels);
  \end{code}
\item Close the file.
  \begin{code}
        out->close ();
  \end{code}
\end{itemize}

\subsection*{What happens when the file format doesn't support the spec?}

The {\cf open()} call will fail (returning an empty pointer and set an appropriate
error message) if the output format cannot accommodate what is requested by
the \ImageSpec. This includes:
\begin{itemize}
\item Dimensions (width, height, or number of channels) exceeding the limits
  supported by the file format.\footnote{One exception to the rule about
  number of channels is that a file format that supports only RGB, but not
  alpha, is permitted to silently drop the alpha channel without considering
  that to be an error.}
\item Volumetric (depth $> 1$) if the format does not support volumetric
  data.
\item Tile size $>1$ if the format does not support tiles.
\item Multiple subimages or MIP levels if not supported by the format.
\end{itemize}


However, several other mismatches between requested \ImageSpec and file
format capabilities will be silently ignored, allowing {\cf open()} to
succeed:

\begin{itemize}
\item If the pixel data format is not supported (for example, a request for
  {\cf half} pixels when writing a JPEG/JFIF file), the format writer
  may substitute another data format (generally, whichever commonly-used
  data format supported by the file type will result in the least reduction
  of precision or range).
\item If the \ImageSpec requests different per-channel data formats, but
  the format supports only a single format for all channels, it may just
  choose the most precise format requested and use it for all channels.
\item If the file format does not support arbitrarily-named channels, the
  channel names may be lost when saving the file.
\item Any other metadata in the \ImageSpec may be summarily dropped if not
  supported by the file format.
\end{itemize}


\section{Advanced Image Output}
\label{sec:imageoutput:advanced}

Let's walk through many of the most common things you might want to do,
but that are more complex than the simple example above.

\subsection{Writing individual scanlines, tiles, and rectangles}
\label{sec:imageoutput:scanlinestiles}

The simple example of Section~\ref{sec:imageoutput:simple} wrote an
entire image with one call.  But sometimes you are generating output a
little at a time and do not wish to retain the entire image in memory
until it is time to write the file.  \product allows you to write images
one scanline at a time, one tile at a time, or by individual rectangles.

\subsubsection{Writing individual scanlines}

Individual scanlines may be written using the \writescanline API
call:

\begin{code}
        ...
        unsigned char scanline[xres*channels];
        out->open (filename, spec);
        int z = 0;   // Always zero for 2D images
        for (int y = 0;  y < yres;  ++y) {
            ... generate data in scanline[0..xres*channels-1] ...
            out->write_scanline (y, z, TypeDesc::UINT8, scanline);
        }
        out->close ();
        ...
\end{code}

The first two arguments to \writescanline specify which scanline is
being written by its vertical ($y$) scanline number (beginning with 0)
and, for volume images, its slice ($z$) number (the slice number should
be 0 for 2D non-volume images).  This is followed by a \TypeDesc
describing the data you are supplying, and a pointer to the pixel data
itself.  Additional optional arguments describe the data stride, which
can be ignored for contiguous data (use of strides is explained in
Section~\ref{sec:imageoutput:strides}).

All \ImageOutput implementations will accept scanlines in strict order
(starting with scanline 0, then 1, up to {\kw yres-1}, without skipping
any).  See Section~\ref{sec:imageoutput:randomrewrite} for details
on out-of-order or repeated scanlines.

The full description of the \writescanline function may be found
in Section~\ref{sec:imageoutput:reference}.

\subsubsection{Writing individual tiles}

Not all image formats (and therefore not all \ImageOutput
implementations) support tiled images.  If the format does not support
tiles, then \writetile will fail.  An application using \product
should gracefully handle the case that tiled output is not available for
the chosen format.

Once you {\kw create()} an \ImageOutput, you can ask if it is capable
of writing a tiled image by using the {\kw supports("tiles")} query:

\begin{code}
        ...
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (! out->supports ("tiles")) {
            // Tiles are not supported
        }
\end{code}

Assuming that the \ImageOutput supports tiled images, you need to
specifically request a tiled image when you {\kw open()} the file.  This
is done by setting the tile size in the \ImageSpec passed
to {\kw open()}.  If the tile dimensions are not set, they will default
to zero, which indicates that scanline output should be used rather than
tiled output.

\begin{code}
        int tilesize = 64;
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
        spec.tile_width = tilesize;
        spec.tile_height = tilesize;
        out->open (filename, spec);
        ...
\end{code}

In this example, we have used square tiles (the same number of pixels
horizontally and vertically), but this is not a requirement of \product.
However, it is possible that some image formats may only support square
tiles, or only certain tile sizes (such as restricting tile sizes to
powers of two).  Such restrictions should be documented by each
individual plugin.

\begin{code}
        unsigned char tile[tilesize*tilesize*channels];
        int z = 0;   // Always zero for 2D images
        for (int y = 0;  y < yres;  y += tilesize) {
            for (int x = 0;  x < xres;  x += tilesize) {
                ... generate data in tile[] ..
                out->write_tile (x, y, z, TypeDesc::UINT8, tile);
            }
        }
        out->close ();
        ...
\end{code}

The first three arguments to \writetile specify which tile is
being written by the pixel coordinates of any pixel contained in the
tile: $x$ (column), $y$ (scanline), and $z$ (slice, which should always
be 0 for 2D non-volume images).  This is followed by a \TypeDesc
describing the data you are supplying, and a pointer to the tile's pixel
data itself, which should be ordered by increasing slice, increasing
scanline within each slice, and increasing column within each scanline.
Additional optional arguments describe the data stride, which can be
ignored for contiguous data (use of strides is explained in
Section~\ref{sec:imageoutput:strides}).

All \ImageOutput implementations that support tiles will accept tiles in
strict order of increasing $y$ rows, and within each row, increasing $x$
column, without missing any tiles.  See
Section~\ref{sec:imageoutput:randomrewrite} for details on out-of-order
or repeated tiles.

The full description of the \writetile function may be found
in Section~\ref{sec:imageoutput:reference}.

\subsubsection{Writing arbitrary rectangles}

Some \ImageOutput implementations --- such as those implementing an
interactive image display, but probably not any that are outputting
directly to a file --- may allow you to send arbitrary rectangular pixel
regions.  Once you {\kw create()} an \ImageOutput, you can ask if it is
capable of accepting arbitrary rectangles by using the {\kw
supports("rectangles")} query:

\begin{code}
        ...
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (! out->supports ("rectangles")) {
            // Rectangles are not supported
        }
\end{code}

If rectangular regions are supported, they may be sent using
the {\kw write_rectangle()} API call:

\begin{code}
        unsigned int rect[...];
        ... generate data in rect[] ..
        out->write_rectangle (xbegin, xend, ybegin, yend, zbegin, zend,
                              TypeDesc::UINT8, rect);
\end{code}

The first six arguments to {\kw write_rectangle()} specify the region of
pixels that is being transmitted by supplying the minimum and one-past-maximum
pixel indices in $x$ (column), $y$ (scanline), and $z$ (slice, always 0
for 2D non-volume images).\footnote{\OpenImageIO nearly always follows
the C++ STL convention of specifying ranges as {\cf [begin,end)}, that
is, {\cf begin, begin+1, ..., end-1.}}
The total number of pixels being transmitted is therefore:
\begin{code}
        (xend-xbegin) * (yend-ybegin) * (zend-zbegin)
\end{code}
\noindent This is followed by a \TypeDesc describing the data you
are supplying, and a pointer to the rectangle's pixel data itself, which
should be ordered by increasing slice, increasing scanline within each
slice, and increasing column within each scanline.  Additional optional
arguments describe the data stride, which can be ignored for contiguous
data (use of strides is explained in
Section~\ref{sec:imageoutput:strides}).


\subsection{Converting pixel data types}
\label{sec:imageoutput:convertingtypes}

The code examples of the previous sections all assumed that your
internal pixel data is stored as unsigned 8-bit integers (i.e., 0-255
range).  But \product is significantly more flexible.  

You may request that the output image pixels be stored in any of several
data types.  This is done by setting the {\kw format} field of the
\ImageSpec prior to calling {\kw open}.  You can do this upon
construction of the \ImageSpec, as in the following example
that requests a spec that stores pixel values as 16-bit unsigned integers:
\begin{code}
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT16);
\end{code}

\noindent Or, for an \ImageSpec that has already been
constructed, you may reset its format using the {\kw set_format()}
method.

\begin{code}
        ImageSpec spec (...);
        spec.set_format (TypeDesc::UINT16);
\end{code}

Note that resetting the pixel data type must be done \emph{before} passing
the spec to {\kw open()}, or it will have no effect on the file.

Individual file formats, and therefore \ImageOutput implementations, may
only support a subset of the pixel data types understood by the \product library.
Each \ImageOutput plugin implementation should document which data
formats it supports.  An individual \ImageOutput implementation is expected
to always succeed, but if the file format does not support the requested
pixel data type, it is expected to choose a data type that is supported,
usually the data type that best preserves the precision and range
of the originally-requested data type.


The conversion from floating-point formats to integer formats (or from
higher to lower integer, which is done by first converting to float) is
always done by rescaling the value so that $0.0$ maps to integer $0$ and
$1.0$ to the maximum value representable by the integer type, then rounded
to an integer value for final output.  Here is the code that implements this
transformation ({\cf T} is the final output integer type):

\begin{code}
        float value = quant_max * input;
        T output = (T) clamp ((int)(value + 0.5), quant_min, quant_max);
\end{code}

\noindent Quantization limits for each integer type is as follows:\\

\smallskip
\begin{tabular}{|l|r|r|}
\hline
{\bf Data Format} & {\bf min} & {\bf max} \\
\hline
{\cf UINT8}  &           0 &        255 \\
{\cf INT8}   &        -128 &        127 \\
{\cf UINT16} &           0 &      65535 \\
{\cf INT16}  &      -32768 &      32767 \\
{\cf UINT}   &           0 & 4294967295 \\
{\cf INT}    & -2147483648 & 2147483647 \\
\hline
\end{tabular} \\
\smallskip

\noindent Note that the default is to use the entire positive range
of each integer type to represent the floating-point ($0.0 - 1.0$) range.
Floating-point types do not attempt to remap values,
and do not clamp (except to their full floating-point range).


It is not required that the pixel data passed to \writeimage,
\writescanline, \writetile, or {\kw write_rectangle()} actually be in
the same data type as that requested as the native pixel data type of the file.
You can fully mix and match data you pass to the various {\kw write}
routines and \product will automatically convert from the internal
format to the native file format.  For example, the following code will
open a TIFF file that stores pixel data as 16-bit unsigned integers
(values ranging from 0 to 65535), compute internal pixel values as
floating-point values, with \writeimage performing the conversion
automatically:

\begin{code}
        std::unique_ptr<ImageOutput> out = ImageOutput::create ("myfile.tif");
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT16);
        out->open (filename, spec);
        ...
        float pixels [xres*yres*channels];
        ...
        out->write_image (TypeDesc::FLOAT, pixels);
\end{code}

\noindent Note that \writescanline, \writetile, and {\cf
  write_rectangle} have a parameter that works in a corresponding
manner.


\subsection{Data Strides}
\label{sec:imageoutput:strides}

In the preceeding examples, we have assumed that the block of data being
passed to the {\cf write} functions are \emph{contiguous}, that is:

\begin{itemize}
\item each pixel in memory consists of a number of data values equal to
  the declared number of channels that are being written to the file;
\item successive column pixels within a row directly follow each other in
  memory, with the first channel of pixel $x$ immediately following
  last channel of pixel $x-1$ of the same row;
\item for whole images, tiles or rectangles, the data for each row
  immediately follows the previous one in memory (the first pixel of row
  $y$ immediately follows the last column of row $y-1$);
\item for 3D volumetric images, the first pixel of slice $z$ immediately
  follows the last pixel of of slice $z-1$.
\end{itemize}

Please note that this implies that data passed to
\writetile be contiguous in the shape of a single tile (not just an
offset into a whole image worth of pixels), and that data passed to {\cf
  write_rectangle()} be contiguous in the dimensions of the rectangle.

The \writescanline function takes an optional {\cf xstride} argument,
and the \writeimage, \writetile, and {\cf write_rectangle} functions
take optional {\cf xstride}, {\cf ystride}, and {\cf zstride} values
that describe the distance, in \emph{bytes}, between successive pixel
columns, rows, and slices, respectively, of the data you are passing.
For any of these values that are not supplied, or are given as the
special constant {\cf AutoStride}, contiguity will be assumed.

By passing different stride values, you can achieve some surprisingly
flexible functionality.  A few representative examples follow:

\begin{itemize}
\item Flip an image vertically upon writing, by using \emph{negative}
  $y$ stride:
  \begin{code}
    unsigned char pixels[xres*yres*channels];
    int scanlinesize = xres * channels * sizeof(pixels[0]);
    ...
    out->write_image (TypeDesc::UINT8,
                      (char *)pixels+(yres-1)*scanlinesize, // offset to last
                      AutoStride,                  // default x stride
                      -scanlinesize,               // special y stride
                      AutoStride);                 // default z stride
  \end{code}
\item Write a tile that is embedded within a whole image of pixel data,
  rather than having a one-tile-only memory layout:
  \begin{code}
    unsigned char pixels[xres*yres*channels];
    int pixelsize = channels * sizeof(pixels[0]);
    int scanlinesize = xres * pixelsize;
    ...
    out->write_tile (x, y, 0, TypeDesc::UINT8,
                     (char *)pixels + y*scanlinesize + x*pixelsize,
                     pixelsize,
                     scanlinesize);
  \end{code}
\item Write only a subset of channels to disk.  In this example, our
  internal data layout consists of 4 channels, but we write just 
  channel 3 to disk as a one-channel image:
  \begin{code}
    // In-memory representation is 4 channel
    const int xres = 640, yres = 480;
    const int channels = 4;  // RGBA
    const int channelsize = sizeof(unsigned char);
    unsigned char pixels[xres*yres*channels];

    // File representation is 1 channel
    std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
    ImageSpec spec (xres, yres, 1, TypeDesc::UINT8);
    out->open (filename, spec);

    // Use strides to write out a one-channel "slice" of the image
    out->write_image (TypeDesc::UINT8,
                      (char *)pixels+3*channelsize, // offset to chan 3
                      channels*channelsize,         // 4 channel x stride
                      AutoStride,                   // default y stride
                      AutoStride);                  // default z stride
    ...
  \end{code}
\end{itemize}

Please consult Section~\ref{sec:imageoutput:reference} for detailed
descriptions of the stride parameters to each {\cf write} function.


\subsection{Writing a crop window or overscan region}
\label{sec:imageoutput:cropwindows}
\index{crop windows} \index{overscan}

% FIXME -- Marcos suggests adding a figure here to illustrate
% the w/h/d, xyz, full

The \ImageSpec fields {\cf width}, {\cf height}, and {\cf depth}
describe the dimensions of the actual pixel data.

At times, it may be useful to also describe an abstract \emph{full} or
\emph{display} image window, whose position and size may not correspond
exactly to the data pixels.  For example, a pixel data window that is a
subset of the full display window might indicate a \emph{crop window}; a
pixel data window that is a superset of the full display window might
indicate \emph{overscan} regions (pixels defined outside the eventual
viewport).

The \ImageSpec fields {\cf full_width}, {\cf full_height}, and
{\cf full_depth} describe the dimensions of the full display
window, and {\cf full_x}, {\cf full_y}, {\cf full_z} describe its
origin (upper left corner).  The fields {\cf x}, {\cf y}, {\cf z}
describe the origin (upper left corner)
of the pixel data.

These fields collectively describe an abstract full display image
ranging from [{\cf full_x} ... {\cf full_x+full_width-1}] horizontally,
[{\cf full_y} ... {\cf full_y+full_height-1}] vertically,
and [{\cf full_z} ... {\cf full_z+full_depth-1}] in depth (if it is
a 3D volume), and actual pixel data over the pixel coordinate range 
[{\cf x} ... {\cf x+width-1}] horizontally,
[{\cf y} ... {\cf y+height-1}] vertically,
and [{\cf z} ... {\cf z+depth-1}] in depth (if it is a volume).

Not all image file formats have a way to describe display windows.  An
\ImageOutput implementation that cannot express display windows will
always write out the {\cf width} $\times$ {\cf height} pixel data, may
upon writing lose information about offsets or crop windows.

Here is a code example that opens an image file that will contain a $32
\times 32$ pixel crop window within an abstract $640 \times 480$ full
size image.  Notice that the pixel indices (column, scanline, slice)
passed to the {\cf write} functions are the coordinates relative to
the full image, not relative to the crop widow, but the data pointer
passed to the {\cf write} functions should point to the beginning of
the actual pixel data being passed (not the the hypothetical start of
the full data, if it was all present).

\begin{code}
        int fullwidth = 640, fulllength = 480; // Full display image size
        int cropwidth = 16, croplength = 16;  // Crop window size
        int xorigin = 32, yorigin = 128;      // Crop window position
        unsigned char pixels [cropwidth * croplength * channels]; // Crop size!
        ...
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        ImageSpec spec (cropwidth, croplength, channels, TypeDesc::UINT8);
        spec.full_x = 0;
        spec.full_y = 0;
        spec.full_width = fullwidth;
        spec.full_length = fulllength;
        spec.x = xorigin;
        spec.y = yorigin;
        out->open (filename, spec);
        ...
        int z = 0;   // Always zero for 2D images
        for (int y = yorigin;  y < yorigin+croplength;  ++y) {
            out->write_scanline (y, z, TypeDesc::UINT8,
                                 (y-yorigin)*cropwidth*channels);
        }
        out->close ();
\end{code}


\subsection{Writing metadata}
\label{sec:imageoutput:metadata}

The \ImageSpec passed to {\cf open()} can specify all the common
required properties that describe an image: data format, dimensions,
number of channels, tiling.  However, there may be a variety of
additional \emph{metadata}\footnote{\emph{Metadata} refers to data about
data, in this case, data about the image that goes beyond the pixel
values and description thereof.} that should be carried along with the
image or saved in the file.  

The remainder of this section explains how to store additional metadata
in the \ImageSpec.  It is up to the \ImageOutput to store these
in the file, if indeed the file format is able to accept the data.
Individual \ImageOutput implementations should document which metadata
they respect.

\subsubsection{Channel names}

In addition to specifying the number of color channels, it is also
possible to name those channels.  Only a few \ImageOutput
implementations have a way of saving this in the file, but some do, so
you may as well do it if you have information about what the channels
represent.

By convention, channel names for red, green, blue, and alpha (or a main
image) should be named \qkw{R}, \qkw{G}, \qkw{B}, and \qkw{A},
respectively.  Beyond this guideline, however, you can use any names you
want.

The \ImageSpec has a vector of strings called {\cf
  channelnames}.  Upon construction, it starts out with reasonable
default values.  If you use it
at all, you should make sure that it contains the same number of strings
as the number of color channels in your image.  Here is an example:

\begin{code}
        int channels = 4;
        ImageSpec spec (width, length, channels, TypeDesc::UINT8);
        spec.channelnames.clear ();
        spec.channelnames.push_back ("R");
        spec.channelnames.push_back ("G");
        spec.channelnames.push_back ("B");
        spec.channelnames.push_back ("A");
\end{code}

Here is another example in which custom channel names are used to 
label the channels in an 8-channel image containing beauty pass
RGB, per-channel opacity, and texture $s,t$ coordinates for each pixel.

\begin{code}
        int channels = 8;
        ImageSpec spec (width, length, channels, TypeDesc::UINT8);
        spec.channelnames.clear ();
        spec.channelnames.push_back ("R");
        spec.channelnames.push_back ("G");
        spec.channelnames.push_back ("B");
        spec.channelnames.push_back ("opacityR");
        spec.channelnames.push_back ("opacityG");
        spec.channelnames.push_back ("opacityB");
        spec.channelnames.push_back ("texture_s");
        spec.channelnames.push_back ("texture_t");
\end{code}

The main advantage to naming color channels is that if you are saving to
a file format that supports channel names, then any application that
uses \product to read the image back has the option to retain those
names and use them for helpful purposes.  For example, the {\cf iv}
image viewer will display the channel names when viewing individual
channels or displaying numeric pixel values in ``pixel view'' mode.


\subsubsection{Specially-designated channels}

The \ImageSpec contains two fields, {\cf alpha_channel} and {\cf
  z_channel}, which can be used to designate which channel indices are
used for alpha and $z$ depth, if any.  Upon construction, these are both
set to {\cf -1}, indicating that it is not known which channels 
are alpha or depth.  Here is an example of setting up a 5-channel output
that represents RGBAZ:

\begin{code}
        int channels = 5;
        ImageSpec spec (width, length, channels, format);
        spec.channelnames.push_back ("R");
        spec.channelnames.push_back ("G");
        spec.channelnames.push_back ("B");
        spec.channelnames.push_back ("A");
        spec.channelnames.push_back ("Z");
        spec.alpha_channel = 3;
        spec.z_channel = 4;
\end{code}

There are two advantages to designating the alpha and depth channels in
this manner:  
\begin{itemize}
\item Some file formats may require that these channels be stored in a
  particular order, with a particular precision, or the \ImageOutput may
  in some other way need to know about these special channels.
\end{itemize}

\subsubsection{Arbitrary metadata}

For all other metadata that you wish to save in the file, you can attach
the data to the \ImageSpec using the {\cf attribute()} methods.
These come in polymorphic varieties that allow you to attach an
attribute name and a value consisting of a single {\cf int}, {\cf
  unsigned int}, {\cf float}, {\cf char*}, or {\cf std::string}, as
shown in the following examples:

\begin{code}
        ImageSpec spec (...);
        ...

        unsigned int u = 1;
        spec.attribute ("Orientation", u);

        float x = 72.0;
        spec.attribute ("dotsize", f);

        std::string s = "Fabulous image writer 1.0";
        spec.attribute ("Software", s);
\end{code}

These are convenience routines for metadata that consist of a single
value of one of these common types.  For other data types, or more
complex arrangements, you can use the more general form of {\cf
  attribute()}, which takes arguments giving the name, type (as a
\TypeDesc), number of values (1 for a single value, $>1$ for an
  array), and then a pointer to the data values.  For example,

\begin{code}
        ImageSpec spec (...);

        // Attach a 4x4 matrix to describe the camera coordinates
        float mymatrix[16] = { ... };
        spec.attribute ("worldtocamera", TypeMatrix, &mymatrix);

        // Attach an array of two floats giving the CIE neutral color
        float neutral[2] = { ... };
        spec.attribute ("adoptedNeutral", TypeDesc(TypeDesc::FLOAT, 2), &neutral);
\end{code}

In general, most image file formats (and therefore most \ImageOutput
implementations) are aware of only a small number of name/value pairs
that they predefine and will recognize.  Some file formats (OpenEXR,
notably) do accept arbitrary user data and save it in the image file.
If an \ImageOutput does not recognize your metadata and does not support
arbitrary metadata, that metadatum will be silently ignored and will not
be saved with the file.

Each individual \ImageOutput implementation should document the names,
types, and meanings of all metadata attributes that they understand.


\subsubsection{Color space hints}

We certainly hope that you are using only modern file formats that
support high precision and extended range pixels (such as OpenEXR) and
keeping all your images in a linear color space.  But you may have to
work with file formats that dictate the use of nonlinear color values.
This is prevalent in formats that store pixels only as 8-bit values,
since 256 values are not enough to linearly represent colors without
banding artifacts in the dim values.

Since this can (and probably will) happen, we have a convention
for explaining what color space your image pixels are
in.  Each individual \ImageOutput should document how it uses this (or
not).

The {\cf ImageSpec::extra_attribs} field should store metadata that
reveals the color space of the pixels you are sending the ImageOutput
(see Section~\ref{metadata:colorspace} for explanations of
particular values).

\noindent The color space hints only describe color channels.  You should always
pass alpha, depth, or other non-color channels with linear values.

Here is a simple example of setting up the \ImageSpec
when you know that the pixel values you are writing are linear:

\begin{code}
        ImageSpec spec (width, length, channels, format);
        spec.attribute ("oiio:ColorSpace", "Linear");
        ...
\end{code}

If a particular \ImageOutput implementation is required (by the rules of
the file format it writes) to have pixels in a particular color space,
then it should try to convert the color values of your image to the right color
space if it is not already in that space.  For example, JPEG images
must be in sRGB space, so if you declare your pixels to be \qkw{Linear},
the JPEG \ImageOutput will convert to sRGB.

If you leave the \qkw{oiio:ColorSpace} unset, the values will not be
transformed, since the plugin can't be sure that it's not in the correct
space to begin with.



\subsection{Random access and repeated transmission of pixels}
\label{sec:imageoutput:randomrewrite}

All \ImageOutput implementations that support scanlines and tiles should write pixels in strict
order of increasing $z$ slice, increasing $y$ scanlines/rows within each
slice, and increasing $x$ column within each row.  It is generally not
safe to skip scanlines or tiles, or transmit them out of order, unless
the plugin specifically advertises that it supports random access or
rewrites, which may be queried using:

\begin{code}
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (out->supports ("random_access"))
            ...
\end{code}

\noindent Similarly, you should assume the plugin will not correctly
handle repeated transmissions of a scanline or tile that has already
been sent, unless it advertises that it supports rewrites, which may be
queried using:

\begin{code}
        if (out->supports ("rewrite"))
            ...
\end{code}


\subsection{Multi-image files}
\label{sec:imageoutput:multiimage}

Some image file formats support storing multiple images within a single
file.  Given a created \ImageOutput, you can query whether multiple
images may be stored in the file:

\begin{code}
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (out->supports ("multiimage"))
            ...
\end{code}

Some image formats allow you to do the initial {\cf open()} call
without declaring the specifics of the subimages, and simply append
subimages as you go.  You can detect this by checking
\begin{code}
        if (out->supports ("appendsubimage"))
            ...
\end{code}

In this case, all you have to do is, after writing all the pixels of one
image but before calling {\cf close()}, call {\cf open()} again for the
next subimage and pass {\cf AppendSubimage} as the value for the
\emph{mode} argument (see Section~\ref{sec:imageoutput:reference} for
the full technical description of the arguments to {\cf open}).  The
{\cf close()} routine is called just once, after all subimages are
completed.  Here is an example:

\begin{code}
        const char *filename = "foo.tif";
        int nsubimages;     // assume this is set
        ImageSpec specs[];  // assume these are set for each subimage
        unsigned char *pixels[]; // assume a buffer for each subimage

        // Create the ImageOutput
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);

        // Be sure we can support subimages
        if (subimages > 1 &&  (! out->supports("multiimage") ||
                               ! out->supports("appendsubimage"))) {
            std::cerr << "Does not support appending of subimages\n";
            return;
        }

        // Use Create mode for the first level.
        ImageOutput::OpenMode appendmode = ImageOutput::Create;

        // Write the individual subimages
        for (int s = 0;  s < nsubimages;  ++s) {
            out->open (filename, specs[s], appendmode);
            out->write_image (TypeDesc::UINT8, pixels[s]);
            // Use AppendSubimage mode for subsequent levels
            appendmode = ImageOutput::AppendSubimage;
        }
        out->close ();
\end{code}


On the other hand, if {\cf out->supports("appendsubimage")} returns
{\cf false}, then you must use a different {\cf open()} variety that
allows you to declare the number of subimages and their specifications
up front.

Below is an example of how to write a multi-subimage file, assuming that
you know all the image specifications ahead of time.  This should be
safe for any file format that supports multiple subimages, regardless of
whether it supports appending, and thus is the preferred method for
writing subimages, assuming that you are able to know the number and
specification of the subimages at the time you first open the file.

\begin{code}
        const char *filename = "foo.tif";
        int nsubimages;     // assume this is set
        ImageSpec specs[];  // assume these are set for each subimage
        unsigned char *pixels[]; // assume a buffer for each subimage

        // Create the ImageOutput
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);

        // Be sure we can support subimages
        if (subimages > 1 && ! out->supports ("multiimage")) {
            std::cerr << "Cannot write multiple subimages\n";
            return;
        }

        // Open and declare all subimages
        out->open (filename, nsubimages, specs);

        // Write the individual subimages
        for (int s = 0;  s < nsubimages;  ++s) {
            if (s > 0)  // Not needed for the first, which is already open
                out->open (filename, specs[s], ImageInput::AppendSubimage);
            out->write_image (TypeDesc::UINT8, pixels[s]);
        }
        out->close ();
\end{code}

In both of these examples, we have used \writeimage, but of course
\writescanline, \writetile, and {\cf write_rectangle()} work as you
would expect, on the current subimage.


\subsection{MIP-maps}
\label{sec:imageoutput:mipmap}

Some image file formats support multiple copies of an image at successively
lower resolutions (MIP-map levels, or an ``image pyramid'').  Given a
created \ImageOutput, you can query whether MIP-maps may be
stored in the file:

\begin{code}
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (out->supports ("mipmap"))
            ...
\end{code}

If you are working with an \ImageOutput that supports MIP-map levels, it
is easy to write these levels.  After writing all the pixels of one
MIP-map level, 
call {\cf open()} again for the next MIP level and pass
{\cf ImageInput::AppendMIPLevel} as the value for the \emph{mode}
argument, and then write the pixels of the subsequent MIP level.
(See Section~\ref{sec:imageoutput:reference} for
the full technical description of the arguments to {\cf open()}.)  The
{\cf close()} routine is called just once, after all subimages and MIP
levels are completed.

Below is pseudocode for writing a MIP-map (a multi-resolution image
used for texture mapping):

\begin{code}
        const char *filename = "foo.tif";
        const int xres = 512, yres = 512;
        const int channels = 3;  // RGB
        unsigned char *pixels = new unsigned char [xres*yres*channels];

        // Create the ImageOutput
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);

        // Be sure we can support either mipmaps or subimages
        if (! out->supports ("mipmap") && ! out->supports ("multiimage")) {
            std::cerr << "Cannot write a MIP-map\n";
            return;
        }
        // Set up spec for the highest resolution
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);

        // Use Create mode for the first level.
        ImageOutput::OpenMode appendmode = ImageOutput::Create;

        // Write images, halving every time, until we're down to
        // 1 pixel in either dimension
        while (spec.width >= 1 && spec.height >= 1) {
            out->open (filename, spec, appendmode);
            out->write_image (TypeDesc::UINT8, pixels);
            // Assume halve() resamples the image to half resolution
            halve (pixels, spec.width, spec.height);
            // Don't forget to change spec for the next iteration
            spec.width /= 2;
            spec.height /= 2;

            // For subsequent levels, change the mode argument to
            // open().  If the format doesn't support MIPmaps directly,
            // try to emulate it with subimages.
            if (out->supports("mipmap"))
                appendmode = ImageOutput::AppendMIPLevel;
            else
                appendmode = ImageOutput::AppendSubimage;
        }
        out->close ();
\end{code}

In this example, we have used \writeimage, but of course \writescanline,
\writetile, and {\cf write_rectangle()} work as you would expect, on the
current MIP level.


\subsection{Per-channel formats}
\label{sec:imageoutput:channelformats}

Some image formats allow separate per-channel data formats (for example,
{\cf half} data for colors and {\cf float} data for depth).  When this
is desired, the following steps are necessary:

\begin{enumerate}
\item Verify that the writer supports per-channel formats by checking \\
  {\cf supports ("channelformats")}.
\item The \ImageSpec passed to {\cf open()} should have its {\cf
  channelformats} vector filled with the types for each channel.
\item The call to {\cf write_scanline}, {\cf read_scanlines},
  {\cf write_tile}, {\cf write_tiles}, or {\cf
  write_image} should pass a {\cf data} pointer to the raw data, already
  in the native per-channel format of the file and contiguously packed,
  and specify that the data is of type {\cf TypeDesc::UNKNOWN}.
\end{enumerate}

For example, the following code fragment will write a 5-channel image
to an OpenEXR file, consisting of R/G/B/A channels in {\cf half} and
a Z channel in {\cf float}:

\begin{code}
        // Mixed data type for the pixel
        struct Pixel { half r,g,b,a; float z; };
        Pixel pixels[xres*yres];

        std::unique_ptr<ImageOutput> out = ImageOutput::create ("foo.exr");

        // Double check that this format accepts per-channel formats
        if (! out->supports("channelformats")) {
            return;
        }

        // Prepare an ImageSpec with per-channel formats
        ImageSpec spec (xres, yres, 5, TypeDesc::FLOAT);
        spec.channelformats.push_back (TypeDesc::HALF);
        spec.channelformats.push_back (TypeDesc::HALF);
        spec.channelformats.push_back (TypeDesc::HALF);
        spec.channelformats.push_back (TypeDesc::HALF);
        spec.channelformats.push_back (TypeDesc::FLOAT);
        spec.channelnames.clear ();
        spec.channelnames.push_back ("R");
        spec.channelnames.push_back ("G");
        spec.channelnames.push_back ("B");
        spec.channelnames.push_back ("A");
        spec.channelnames.push_back ("Z");

        out->open (filename, spec);
        out->write_image (TypeDesc::UNKNOWN, /* use channel formats */
                          pixels,            /* data buffer */
                          sizeof(Pixel));    /* pixel stride */
\end{code}


\subsection{Writing ``deep'' data}
\label{sec:imageoutput:deepdata}  \index{deep data}
Some image file formats (OpenEXR only, at this time) support the concept
of ``deep'' pixels -- those containing multiple samples per pixel (and a
potentially differing number of them in each pixel).  You can tell
if a format supports deep images by checking {\cf supports("deepdata")},
and you can specify a deep data in an \ImageSpec by setting its {\cf deep}
field will be {\cf true}.

Deep files cannot be written with the usual {\cf write_scanline}, {\cf
  write_scanlines}, {\cf write_tile}, {\cf write_tiles}, {\cf write_image}
functions, due to the nature of their variable number of samples per
pixel.  Instead, \ImageOutput has three special member functions used
only for writing deep data:

\begin{code}
    bool write_deep_scanlines (int ybegin, int yend, int z,
                               const DeepData &deepdata);

    bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend,
                           int zbegin, int zend, const DeepData &deepdata);

    bool write_deep_image (const DeepData &deepdata);
\end{code}

It is only possible to write ``native'' data types to deep files; that
is, there is no automatic translation into arbitrary data types as there
is for ordinary images.  All three of these functions are passed
deep data in a special {\cf DeepData} structure, described in
detail in Section~\ref{sec:deepdata}.


\noindent Here is an example of using these methods to write a deep image:

\begin{code}
    // Prepare the spec for 'half' RGBA, 'float' z
    int nchannels = 5;
    ImageSpec spec (xres, yres, nchannels);
    TypeDesc channeltypes[] = { TypeDesc::HALF, TypeDesc::HALF,
          TypeDesc::HALF, TypeDesc::HALF, TypeDesc::FLOAT };
    spec.z_channel = 4;
    spec.channelnames[spec.z_channel] = "Z";
    spec.channeltypes.assign (channeltypes+0, channeltypes+nchannels);
    spec.deep = true;

    // Prepare the data (sorry, complicated, but need to show the gist)
    DeepData deepdata;
    deepdata.init (spec);
    for (int y = 0;  y < yres;  ++y)
        for (int x = 0;  x < xres;  ++x)
            deepdata.set_samples(y*xres+x, ...samples for that pixel...);
    deepdata.alloc ();  // allocate pointers and data
    int pixel = 0;
    for (int y = 0;  y < yres;  ++y)
        for (int x = 0;  x < xres;  ++x, ++pixel)
            for (int chan = 0;  chan < nchannels;  ++chan)
                for (int samp = 0; samp < deepdata.samples(pixel); ++samp)
                    deepdata.set_deep_value (pixel, chan, samp, ...value...);


    // Create the output
    std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
    if (! out)
        return;
    // Make sure the format can handle deep data and per-channel formats
    if (! out->supports("deepdata") || ! out->supports("channelformats"))
        return;

    // Do the I/O (this is the easy part!)
    out->open (filename, spec);
    out->write_deep_image (deepdata);
    out->close ();
\end{code}


\subsection{Copying an entire image}
\label{sec:imageoutput:copyimage}

Suppose you want to copy an image, perhaps with alterations to the 
metadata but not to the pixels.  You could open an \ImageInput and
perform a {\cf read_image()}, and open another \ImageOutput and
call {\cf write_image()} to output the pixels from the input image.
However, for compressed images, this may be inefficient due to the
unnecessary decompression and subsequent re-compression.  In addition,
if the compression is \emph{lossy}, the output image may not contain
pixel values identical to the original input.

A special {\cf copy_image} method of \ImageOutput is available that
attempts to copy an image from an open \ImageInput (of the same
format) to the output as efficiently as possible with without altering
pixel values, if at all possible.

Not all format plugins will provide an implementation of {\cf
  copy_image} (in fact, most will not), but the default implemenatation
simply copies pixels one scanline or tile at a time (with
decompression/recompression) so it's still safe to call.  Furthermore,
even a provided {\cf copy_image} is expected to fall back on the default
implementation if the input and output are not able to do an efficient
copy.  Nevertheless, this method is recommended
for copying images so that maximal advantage will be taken in cases
where savings can be had.

The following is an example use of {\cf copy_image} to transfer pixels
without alteration while modifying the image description metadata:

\begin{code}
    // Open the input file
    const char *input = "input.jpg";
    std::unique_ptr<ImageInput> in = ImageInput::open (input);

    // Make an output spec, identical to the input except for metadata
    ImageSpec out_spec = in->spec();
    out_spec.attribute ("ImageDescription", "My Title");

    // Create the output file and copy the image
    const char *output = "output.jpg";
    std::unique_ptr<ImageOutput> out = ImageOutput::create (output);
    out->open (output, out_spec);
    out->copy_image (in);

    // Clean up
    out->close ();
    in->close ();
\end{code}


\subsection{Custom I/O proxies (and writing the file to a memory buffer)}
\label{sec:imageoutput:ioproxy}
\index{writing an image file to memory buffer}

Some file format writers allow you to supply a custom I/O proxy object that
can allow bypassing the usual file I/O with custom behavior, including the
ability to fill an in-memory buffer with a byte-for-byte representation of
the correctly formatted file that would have been written to disk.

Only some output format writers support this feature. To find out if a
particular file format supports this feature, you can create an \ImageOutput
of the right type, and check if it supports the feature name \qkw{ioproxy}:

\begin{code}
    ImageOutput *out = ImageOutput::create (filename);
    if (! out  ||  ! out->supports ("ioproxy")) {
        ImageOutput::destroy (out);
        out = nullptr;
        return;
    }
\end{code}

\ImageOutput writers that support \qkw{ioproxy} will respond to a special
attribute, \qkw{oiio:ioproxy}, which passes a pointer to a {\cf
Filesystem::IOProxy*} (see \product's {\cf filesystem.h} for this type and
its subclasses). {\cf IOProxy} is an abstract type, and concrete subclasses
include {\cf IOFile} (which wraps I/O to an open {\cf FILE*}) and {\cf
IOVecOutput} (which sends output to a {\cf std::vector<unsigned char>}).

Here is an example of using a proxy that writes the ``file'' to a
{\cf std::vector<unsigned char>}:

\begin{code}
    // ImageSpec describing the image we want to write.
    ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);

    std::vector<unsigned char> file_buffer;  // bytes will go here
    Filesystem::IOVecOutput vecout (file_buffer);  // I/O proxy object
    void *ptr = &vecout;
    spec.attribute ("oiio:ioproxy", TypeDesc::PTR, &ptr);

    ImageOutput *out = ImageOutput::open ("out.exr", spec);
    out->write_image (...);
    ImageOutput::destroy (out);

    // At this point, file_buffer will contain the "file"
\end{code}



\subsection{Custom search paths for plugins}
\label{sec:imageoutput:searchpaths}

When you call {\cf ImageOutput::create()}, the \product library will try
to find a plugin that is able to write the format implied by your
filename.  These plugins are alternately known as DLL's on Windows (with
the {\cf .dll} extension), DSO's on Linux (with the {\cf .so}
extension), and dynamic libraries on Mac OS X (with the {\cf .dylib}
extension).  

\product will look for matching plugins according to
\emph{search paths}, which are strings giving a list of directories to
search, with each directory separated by a colon (`{\cf :}').  Within
a search path, any
substrings of the form {\cf \$\{FOO\}} will be replaced
by the value of environment variable {\cf FOO}.  For
example, the searchpath \qkw{\$\{HOME\}/plugins:/shared/plugins}
will first check the directory \qkw{/home/tom/plugins} (assuming the
user's home directory is {\cf /home/tom}), and if not
found there, will then check the directory \qkw{/shared/plugins}.

The first search path it will check is that stored in the environment
variable {\cf OIIO_LIBRARY_PATH}.  It will check each directory in
turn, in the order that they are listed in the variable.  If no adequate
plugin is found in any of the directories listed in this environment
variable, then it will check the custom searchpath passed as the
optional second argument to {\cf ImageOutput::create()}, searching in
the order that the directories are listed.  Here is an example:

\begin{code} 
        char *mysearch = "/usr/myapp/lib:${HOME}/plugins";
        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename, mysearch);
        ...
\end{code} % $


\subsection{Error checking}
\label{sec:imageoutput:errors}
\index{error checking}

Nearly every \ImageOutput API function returns a {\cf bool} indicating
whether the operation succeeded ({\cf true}) or failed ({\cf false}).
In the case of a failure, the \ImageOutput will have saved an error
message describing in more detail what went wrong, and the latest
error message is accessible using the \ImageOutput method 
{\cf geterror()}, which returns the message as a {\cf std::string}.

The exception to this rule is {\cf ImageOutput::create}, which returns
{\cf NULL} if it could not create an appropriate \ImageOutput.  And in
this case, since no \ImageOutput exists for which you can call its {\cf
  geterror()} function, there exists a global {\cf geterror()}
function (in the {\cf OpenImageIO} namespace) that retrieves the latest
error message resulting from a call to {\cf create}.

Here is another version of the simple image writing code from
Section~\ref{sec:imageoutput:simple}, but this time it is fully 
elaborated with error checking and reporting:

\begin{code}
        #include <OpenImageIO/imageio.h>
        using namespace OIIO;
        ...

        const char *filename = "foo.jpg";
        const int xres = 640, yres = 480;
        const int channels = 3;  // RGB
        unsigned char pixels[xres*yres*channels];

        std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
        if (! out) {
            std::cerr << "Could not create an ImageOutput for " 
                      << filename << ", error = " 
                      << OpenImageIO::geterror() << "\n";
            return;
        }
        ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);

        if (! out->open (filename, spec)) {
            std::cerr << "Could not open " << filename 
                      << ", error = " << out->geterror() << "\n";
            return;
        }

        if (! out->write_image (TypeDesc::UINT8, pixels)) {
            std::cerr << "Could not write pixels to " << filename 
                      << ", error = " << out->geterror() << "\n";
            return;
        }

        if (! out->close ()) {
            std::cerr << "Error closing " << filename 
                      << ", error = " << out->geterror() << "\n";
            return;
        }
\end{code}



\section{\ImageOutput Class Reference}
\label{sec:imageoutput:reference}

\apiitem{static std::unique_ptr<ImageOutput> {\ce create} (const std::string \&filename, \\
\bigspc\bigspc\spc const std::string \&plugin_searchpath="")}

Create an \ImageOutput that can be used to write an image file.  The
type of image file (and hence, the particular subclass of \ImageOutput
returned, and the plugin that contains its methods) is inferred from the
extension of the file name.  The {\kw plugin_searchpath} parameter is a
colon-separated list of directories to search for \product plugin
DSO/DLL's.
\apiend

\apiitem{const char * {\ce format_name} ()}
Returns the canonical name of the format that this \ImageOutput
instance is capable of writing.
\apiend

\apiitem{int {\ce supports} (string_view feature) const}
\label{sec:supportsfeaturelist}
Given the name of a \emph{feature}, tells if this \ImageOutput  instance
supports that feature.  Most queries will simply return 0 for ``doesn't
support the feature'' and nonzero for ``supports the feature,'' but it is
acceptable to have queries return other nonzero integers to indicate varying
degrees of support or limits (but those queries should be clearly documented
as such). The following features are recognized by this query:
\begin{description}
\item[\spc] \spc 
\item[\rm \qkw{tiles}] Is this plugin able to write tiled images?
\item[\rm \qkw{rectangles}] Can this plugin accept arbitrary rectangular
  pixel regions (via {\kw write_rectangle()})?  False indicates that
  pixels must be transmitted via \writescanline (if
  scanline-oriented) or \writetile (if tile-oriented, and only if
  {\kw supports("tiles")} returns true).
\item[\rm \qkw{random_access}] May tiles or scanlines be written in any
  order?  False indicates that they must be in successive order.
\item[\rm \qkw{multiimage}] Does this format support multiple subimages
  within a single file?
\item[\rm \qkw{appendsubimage}] Does this format support multiple
  subimages that can be successively appended at will, without needing
  to pre-declare the number and specifications the subimages when the 
  file is first opened?
\item[\rm \qkw{mipmap}] Does this format support resolutions per
  image/subimage (MIP-map levels)?
\item[\rm \qkw{volumes}] Does this format support ``3D'' pixel arrays
  (a.k.a.\ volume images)?
\item[\rm \qkw{alpha}] Does this format support an alpha channel?
\item[\rm \qkw{nchannels}] Does this format support an arbitrary number
  of channels (beyond RGBA)?
\item[\rm \qkw{rewrite}] Does this plugin allow the same scanline or
  tile to be sent more than once?  Generally this is true for plugins
  that implement some sort of interactive display, rather than a saved
  image file.
\item[\rm \qkw{empty}] Does this plugin support passing a NULL data
  pointer to the various {\kw write} routines to indicate that the
  entire data block is composed of pixels with value zero.  Plugins
  that support this achieve a speedup when passing blank scanlines or
  tiles (since no actual data needs to be transmitted or converted).
\item[\rm \qkw{channelformats}] Does this format writer support per-channel
  data formats, respecting the \ImageSpec's {\cf channelformats}
  field?  (If not, it only accepts a single data format for all
  channels and will ignore the {\cf channelformats} field of the spec.)
\item[\rm \qkw{displaywindow}] Does the image format support specifying
  a display (``full'') window that is distinct from the pixel data
  window?
\item[\rm \qkw{origin}] Does the image format support specifying
  a pixel window origin (i.e., nonzero \ImageSpec {\cf x}, {\cf y},
  {\cf z})?
\item[\rm \qkw{negativeorigin}] Does the image format allow pixel
  and data window origins (i.e., nonzero \ImageSpec {\cf x}, {\cf y},
  {\cf z}, {\cf full_x}, {\cf full_y}, {\cf full_z}) to have
  negative values?
\item[\rm \qkw{deepdata}] Does the image format allow ``deep'' data
  consisting of multiple values per pixel (and potentially a differing
  number of values from pixel to pixel)?
\item[\rm \qkw{arbitrary_metadata}] Does the image file format allow
  metadata with arbitrary names (and either arbitrary, or a reasonable set
  of, data types)? (Versus the file format supporting only a fixed list of
  specific metadata names/values?
\item[\rm \qkw{exif}] Does the image file format support Exif camera data
  (either specifically, or via arbitrary named metadata)?
\item[\rm \qkw{iptc}] Does the image file format support IPTC data
  (either specifically, or via arbitrary named metadata)?
\item[\rm \qkw{ioproxy}] Does the image file format support writing
  to an {\cf IOProxy}?
\end{description}

\noindent This list of queries may be extended in future releases.
Since this can be done simply by recognizing new query strings, and does
not require any new API entry points, addition of support for new
queries does not break ``link compatibility'' with previously-compiled
plugins.
\apiend

\apiitem{bool {\ce open} (const std::string \&name, const ImageSpec \&newspec,\\
\bigspc  OpenMode mode=Create)}
\label{sec:imageoutputopen}

Open the file with given {\kw name}, with resolution and other format
data as given in {\kw newspec}.  This function returns {\kw true} for
success, {\kw false} for failure.  Note that it is legal to call 
{\kw open()} multiple times on the same file without a call to
{\kw close()}, if it supports multiimage and {\kw mode} is 
{\kw AppendSubimage}, or if it supports MIP-maps and {\kw mode} is 
{\kw AppendMIPLevel} -- this is interpreted as appending a subimage, or
a MIP level to the current subimage, respectively.
\apiend

\apiitem{bool {\ce open} (const std::string \&name, int subimages,
 const ImageSpec *specs)}
Open the file with given {\cf name}, expecting to have a given total
number of subimages, described by {\cf specs[0..subimages-1]}.  Return
{\cf true} for success, {\cf false} for failure.  Upon success, the
first subimage will be open and ready for transmission of
pixels.  Subsequent subimages will be denoted with the usual
call of {\cf open(name,spec,AppendSubimage)} (and MIP levels by
{\cf open(name,spec,AppendMIPLevel)}).

The purpose of this call is to accommodate format-writing libraries that
must know the number and specifications of the subimages upon first
opening the file; such formats can be detected by
\begin{code}
    supports("multiimage") && ! supports("appendsubimage")
\end{code}
The individual specs passed to the appending {\cf open()} calls for
subsequent subimages must match the ones originally passed.
\apiend


\apiitem{const ImageSpec \& {\ce spec} ()}
Returns the spec internally associated with this currently open
\ImageOutput.
\apiend

\apiitem{bool {\ce close} ()}
Closes the currently open file associated with this \ImageOutput
and frees any memory or resources associated with it.
\apiend

\apiitem{bool {\ce write_scanline} (int y, int z, TypeDesc format,
     const void *data, \\
\bigspc stride_t xstride=AutoStride)}

Write the scanline that includes pixels $(*,y,z)$ from {\cf data}.  For
2D non-volume images, $z$ is ignored.
The {\cf xstride} value gives the data spacing of adjacent pixels (in
bytes).  Strides set to the special value {\kw AutoStride} imply
contiguous data, i.e., \\ 
\spc {\kw xstride} $=$ {\kw spec.nchannels * format.size()} \\

This method automatically converts the data from the specified {\kw format}
to the actual output format of the file.  
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to
already be in the file's native format (including per-channel formats, 
as specified in the \ImageSpec's {\cf channelformats} field, if applicable).
Return {\kw true} for success, {\kw false} for failure.  
It is a failure to call \writescanline with an
out-of-order scanline if this format driver does not support random
access.
\apiend

\apiitem{bool {\ce write_scanlines} (int ybegin, int yend, int z, \\
\bigspc TypeDesc format,
     const void *data, \\
\bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride)}

Write a block of scanlines that include pixels $(*,y,z)$,
where ${\mathit ybegin} \le y < {\mathit yend}$.  This is essentially
identical to {\cf write_scanline()}, except that it can write more than
one scanline at a time, which may be more efficient for certain
image format writers.

For 2D non-volume images, $z$ is ignored.  The {\kw xstride} value gives
the distance between successive pixels (in bytes), and {\kw ystride}
gives the distance between successive scanlines.  Strides set to the
special value {\kw AutoStride} imply contiguous data, i.e., \\
 \spc {\kw xstride} $=$ {\kw spec.nchannels*format.size()} \\ \spc {\kw ystride} $=$ {\kw spec.width*xstride}

This method automatically converts the data from the specified {\kw format}
to the actual output format of the file.  
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to
already be in the file's native format (including per-channel formats, 
as specified in the \ImageSpec's {\cf channelformats} field, if applicable).
Return {\kw true} for success, {\kw false} for failure.  
It is a failure to call \writescanline with an
out-of-order scanline if this format driver does not support random
access.
\apiend

\apiitem{bool {\ce write_tile} (int x, int y, int z, TypeDesc format,
                             const void *data, \\ \bigspc stride_t xstride=AutoStride,
                             stride_t ystride=AutoStride, \\ \bigspc stride_t zstride=AutoStride)}

Write the tile with $(x,y,z)$ as the upper left corner.  For 2D
non-volume images, $z$ is ignored.  The three stride values give the
distance (in bytes) between successive pixels, scanlines, and volumetric
slices, respectively.  Strides set to the special value {\kw AutoStride}
imply contiguous data in the shape of a full tile, i.e., \\
\spc {\kw xstride} $=$ {\kw spec.nchannels * format.size()} \\
\spc {\kw ystride} $=$ {\kw xstride * spec.tile_width} \\
\spc {\kw zstride} $=$ {\kw ystride * spec.tile_height} \\
This method automatically converts the
data from the specified {\kw format} to the actual output format of the
file. 
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to
already be in the file's native format (including per-channel formats, 
as specified in the \ImageSpec's {\cf channelformats} field, if applicable).
Return {\kw true} for success, {\kw false} for failure.  It is a
failure to call \writetile with an out-of-order tile if this
format driver does not support random access.

This function returns {\cf true} if it successfully writes the tile,
otherwise {\cf false} for a failure.
The call will fail if the image is not tiled, or if $(x,y,z)$ is not
actually a tile boundary.
\apiend

\apiitem{bool {\ce write_tiles} (int xbegin, int xend, int ybegin, int yend,\\
\bigspc int zbegin, int zend, TypeDesc format, const void *data, \\
\bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride, \\
\bigspc stride_t zstride=AutoStride)}

Write the tiles that include pixels {\kw xbegin} $\le x <$ {\kw xend},
{\kw ybegin} $\le y <$ {\kw yend}, {\kw zbegin} $\le z <$ {\kw zend}
from {\kw data},
converting if necessary from {\kw format} specified into the file's
native data format.
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data will be assumed
to already be in the native format (including per-channel formats, if applicable).
The stride values
give the data spacing of adjacent pixels, scanlines, and volumetric
slices, respectively (measured in bytes).  Strides set to the special
value of {\kw AutoStride} imply contiguous data in the shape of the
region specified, i.e., \\
\spc {\kw xstride} $=$ {\kw spec.nchannels * spec.pixel_size()} \\
\spc {\kw ystride} $=$ {\kw xstride * (xend - xbegin)} \\
\spc {\kw zstride} $=$ {\kw ystride * (yend - ybegin)} \\
The data for those tiles is assumed to be in the usual image order, as if
it were just one big tile, and not ``paded'' to a whole multiple of the tile size.

This function returns {\cf true} if it successfully writes the tiles,
otherwise {\cf false} for a failure.
The call will fail if the image is not tiled, or if the pixel ranges
do not fall along tile (or image) boundaries, or if it is not a valid
tile range.
\apiend

\apiitem{bool {\ce write_rectangle} ({\small int xbegin, int xend, int ybegin, int yend, \\ \bigspc
                                  int zbegin, int zend,} TypeDesc format,
                                  const void *data, \\ \bigspc stride_t xstride=AutoStride,
                                  stride_t ystride=AutoStride, \\
                                  \bigspc stride_t zstride=AutoStride)}

Write pixels covering the range that includes pixels {\kw xbegin} $\le x <$ {\kw xend},
{\kw ybegin} $\le y <$ {\kw yend}, {\kw zbegin} $\le z <$ {\kw zend}.
The three stride values give the distance
(in bytes) between successive pixels, scanlines, and volumetric slices,
respectively.  Strides set to the special value {\kw AutoStride} imply
contiguous data, i.e.,\\
\spc {\kw xstride} $=$ {\kw spec.nchannels*format.size()} \\
\spc {\kw ystride} $=$ {\kw xstride*(xend-xbegin)} \\
\spc {\kw zstride} $=$ {\kw ystride*(yend-ybegin)}\\
This method automatically converts the data from the specified 
{\kw format} to the actual output format of the file.  
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to
already be in the file's native format (including per-channel formats, 
as specified in the \ImageSpec's {\cf channelformats} field, if applicable).
Return {\kw true}
for success, {\kw false} for failure.  It is a failure to call 
{\kw write_rectangle} for a format plugin that does not return true for
{\kw supports("rectangles")}.

\apiend

\apiitem{bool {\ce write_image} (TypeDesc format, const void *data, \\
                              \bigspc stride_t xstride=AutoStride, stride_t ystride=AutoStride,
                              \\ \bigspc stride_t zstride=AutoStride, \\
                              \bigspc ProgressCallback progress_callback=NULL,\\
                              \bigspc void *progress_callback_data=NULL)}

Write the entire image of {\kw spec.width} $\times$ {\kw spec.height}
$\times$ {\kw spec.depth}
pixels, with the given strides and in the desired format.
If {\cf format} is {\cf TypeDesc::UNKNOWN}, the data is assumed to
already be in the file's native format (including per-channel formats, 
as specified in the \ImageSpec's {\cf channelformats} field, if applicable).
Strides set to the special value {\kw AutoStride} imply contiguous data,
i.e., \\
\spc {\kw xstride} $=$ {\kw spec.nchannels * format.size()} \\
\spc {\kw ystride} $=$ {\kw xstride * spec.width} \\
\spc {\kw zstride} $=$ {\kw ystride * spec.height}\\
The function will internally either call \writescanline or 
\writetile, depending on whether the file is scanline- or
tile-oriented.

Because this may be an expensive operation, a progress callback may be passed.
Periodically, it will be called as follows:
\begin{code}
        progress_callback (progress_callback_data, float done)
\end{code}
\noindent where \emph{done} gives the portion of the image 
(between 0.0 and 1.0) that has been written thus far.

\apiend


\apiitem{bool {\ce write_deep_scanlines} (int ybegin, int yend, int z, \\
\bigspc const DeepData \&deepdata) \\
bool {\ce write_deep_tiles} (int xbegin, int xend, int ybegin, int yend,\\
\bigspc int zbegin, int zend, const DeepData \&deepdata) \\
bool {\ce write_deep_image} (const DeepData \&deepdata)}
Write deep data for a block of scanlines, a block of tiles, or an entire
image (analogously to the usual {\cf write_scanlines}, {\cf write_tiles},
and {\cf write_image}, but with deep data).
Return {\kw true} for success, {\kw false} for failure.
\apiend


\apiitem{bool {\ce copy_image} (ImageInput *in)}

Read the current subimage of {\cf in}, and write it as the next subimage
of {\cf *this}, in a way that is efficient and does not alter pixel
values, if at all possible.  Both {\cf in} and {\cf this} must be a
properly-opened \ImageInput and \ImageOutput, respectively, and their
current images must match in size and number of channels.  Return {\cf true}
if it works ok, {\cf false} if for some reason the operation wasn't possible.

If a particular \ImageOutput implementation does not supply a
{\cf copy_image} method, it will inherit the default implementation,
which is to simply read scanlines or tiles from {\cf in} and write
them to {\cf *this}.  However, some file format implementations may have a
special technique for directly copying raw pixel data from the
input to the output, when both input and output are the same
file type and the same data format.  This can be more efficient 
than {\cf in->read_image} followed by {\cf out->write_image}, and avoids any
unintended pixel alterations, especially for formats that use
lossy compression.
\apiend

\apiitem{int {\ce send_to_output} (const char *format, ...)}
General message passing between client and image output server.
This is currently undefined and is reserved for future use.
\apiend

\apiitem{int {\ce send_to_client} (const char *format, ...)}
General message passing between client and image output server.
This is currently undefined and is reserved for future use.
\apiend

\apiitem{void {\ce threads} (int n) \\
int {\ce threads} () const}
\index{threads}
Get or set the threading policy for this \ImageOutput, controlling the
maximum amount of parallelizing thread ``fan-out'' that might occur during
large write operations. The default of 0 means that the global
{\cf attribute("threads")} value should be used (which itself defaults to
using as many threads as cores; see Section~\ref{sec:attribute:threads}).

The main reason to change this value is to set it to 1 to indicate that the
calling thread should do all the work rather than spawning new threads. That
is probably the desired behavior in situations where the calling application
has already spawned multiple worker threads.
\apiend

\apiitem{std::string {\ce geterror} ()}
\index{error checking}
Returns the current error string describing what went wrong if
any of the public methods returned {\kw false} indicating an error.
(Hopefully the implementation plugin called {\kw error()} with a
helpful error message.)
\apiend



\index{Image I/O API|)}

\chapwidthend
