1\chapter{Python Bindings}
2\label{chap:pythonbindings}
3\indexapi{Python|()}
4
5\section{Overview}
6
7\OpenImageIO provides Python language bindings for much of its
8functionality.
9
10\smallskip
11
12You must ensure that the environment variable {\cf PYTHONPATH} includes
13the {\cf python} subdirectory of the \OpenImageIO installation.
14
15\smallskip
16
17A Python program must import the {\cf OpenImageIO} package:
18\begin{code}
19    import OpenImageIO
20\end{code}
21\noindent In most of our examples below, we assume that for the sake
22of brevity, we will alias the package name as follows:
23\begin{code}
24    import OpenImageIO as oiio
25    from OpenImageIO import ImageInput, ImageOutput
26    from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo
27\end{code}
28
29\section{TypeDesc}
30\label{sec:pythontypedesc}
31
32The \TypeDesc class that describes data types of pixels and metadata,
33described in detail in Section~\ref{sec:TypeDesc}, is replicated for Python.
34
35\apiitem{BASETYPE}
36The {\cf BASETYPE} enum corresponds to the C++ {\cf TypeDesc::BASETYPE} and
37contains the following values: \\
38{\cf UNKNOWN NONE UINT8 INT8 UINT16 INT16 UINT32 INT32 UINT64 INT64 \\
39HALF FLOAT DOUBLE STRING PTR} \\
40These names are also exported to the {\cf OpenImageIO} namespace.
41\apiend
42
43\apiitem{AGGREGATE}
44The {\cf AGGREGATE} enum corresponds to the C++ {\cf TypeDesc::AGGREGATE} and
45contains the following values: \\
46{\cf SCALAR VEC2 VEC3 VEC4 MATRIX33 MATRIX44} \\
47These names are also exported to the {\cf OpenImageIO} namespace.
48\apiend
49
50\apiitem{VECSEMANTICS}
51The {\cf VECSEMANTICS} enum corresponds to the C++ {\cf TypeDesc::VECSEMANTICS} and
52contains the following values: \\
53{\cf NOSEMANTICS COLOR POINT VECTOR NORMAL TIMECODE KEYCODE RATIONAL} \\
54These names are also exported to the {\cf OpenImageIO} namespace.
55\apiend
56
57\apiitem{TypeDesc.{\ce TypeDesc} (typename='unknown')}
58
59Construct a {\cf TypeDesc} object the easy way: from a string description.
60If the type name is omitted, it will default to {\cf UNKNOWN}.
61
62\noindent Examples:
63\begin{code}
64    import OpenImageIO as oiio
65
66    # make a default (UNKNOWN) TypeDesc
67    t = TypeDesc()
68
69    # make a TypeDesc describing an unsigned 8 bit int
70    t = TypeDesc("uint8")
71
72    # make a TypeDesc describing an array of 14 'float' values
73    t = TypeDesc("float[14]")
74
75    # make a TypeDesc describing 3-vector with point semantics
76    t = TypeDesc("point")
77\end{code}
78\apiend
79
80\apiitem{TypeDesc.{\ce TypeDesc} (basetype=oiio.UNKNOWN, aggregate=oiio.SCALAR, \\
81\bigspc\spc\spc vecsemantics=NOSEMANTICS, arraylen=0)}
82
83Construct a {\cf TypeDesc} object the hard way: from individual enum tokens
84describing the base type, aggregate class, semantic hints, and array length.
85
86\noindent Examples:
87\begin{code}
88    import OpenImageIO as oiio
89
90    # make a default (UNKNOWN) TypeDesc
91    t = TypeDesc()
92
93    # make a TypeDesc describing an unsigned 8 bit int
94    t = TypeDesc(oiio.UINT8)
95
96    # make a TypeDesc describing an array of 14 'float' values
97    t = TypeDesc(oiio.FLOAT, oiio.SCALAR, oiio.NOSEMANTICS, 14)
98
99    # make a TypeDesc describing a float point
100    t = TypeDesc(oiio.FLOAT, oiio.VEC3, oiio.POINT)
101\end{code}
102\apiend
103
104\apiitem{TypeUnknown TypeString \\
105TypeFloat TypeHalf \\
106TypeInt TypeUInt TypeInt16 TypeUInt16 \\
107TypeColor TypePoint TypeVector TypeNormal TypeFloat4 \\
108TypeMatrix TypeMatrix33 \\
109TypeTimeCode TypeKeyCode \\
110TypeRational \\
111}
112Pre-constructed \TypeDesc objects for some common types, available in the
113outer OpenImageIO scope.
114
115\noindent Example:
116\begin{code}
117    t = TypeFloat
118\end{code}
119\apiend
120
121\apiitem{string {\ce str} (TypeDesc)}
122Returns a string that describes the \TypeDesc.
123
124\noindent Example:
125\begin{code}
126    print str(TypeDesc(oiio.UINT16))
127
128    > int16
129\end{code}
130\apiend
131
132\apiitem{TypeDesc.{\ce basetype} \\
133TypeDesc.{\ce aggregate} \\
134TypeDesc.{\ce vecsemantics} \\
135TypeDesc.{\ce arraylen}}
136Access to the raw fields in the \TypeDesc.
137
138\noindent Example:
139\begin{code}
140    t = TypeDesc(...)
141    if t.basetype == oiio.FLOAT :
142        print "It's made of floats"
143\end{code}
144\apiend
145
146\apiitem{int TypeDesc.{\ce size} () \\
147int TypeDesc.{\ce basesize} () \\
148TypeDesc TypeDesc.{\ce elementtype} () \\
149int TypeDesc.{\ce numelements} () \\
150int TypeDesc.{\ce elementsize} ()}
151The {\cf size()} is the size in bytes, of the type described.  The
152{\cf basesize()} is the size in bytes of the {\cf basetype}.
153
154The {\cf elementtype()} is the type of each array element, if it is an
155array, or just the full type if it is not an array.  The {\cf elementsize()}
156is the size, in bytes, of the {\cf elementtype} (thus, returning the same
157value as {\cf size()} if the type is not an array).  The {\cf numelements()}
158method returns {\cf arraylen} if it is an array, or {\cf 1} if it is not
159an array.
160
161\noindent Example:
162\begin{code}
163    t = TypeDesc("point[2]")
164    print "size =", t.size()
165    print "elementtype =", t.elementtype()
166    print "elementsize =", t.elementsize()
167
168    > size = 24
169    > elementtype = point
170    > elementsize = 12
171\end{code}
172\apiend
173
174\apiitem{bool typedesc {\ce ==} typedesc \\
175bool typedesc {\ce !=} typedesc \\
176bool TypeDesc.{\ce equivalent} (typedesc) \\}
177Test for equality or inequality.  The {\cf equivalent()} method is more
178forgiving than {\cf ==}, in that it considers {\cf POINT}, {\cf VECTOR},
179and {\cf NORMAL} vector semantics to not constitute a difference from one
180another.
181
182\noindent Example:
183\begin{code}
184    f = TypeDesc("float")
185    p = TypeDesc("point")
186    v = TypeDesc("vector")
187    print "float==point?", (f == p)
188    print "vector==point?", (v == p)
189    print "float.equivalent(point)?", f.equivalent(p)
190    print "vector.equivalent(point)?", v.equivalent(p)
191
192    > float==point? False
193    > vector==point? False
194    > float.equivalent(point)? False
195    > vector.equivalent(point)? True
196\end{code}
197\apiend
198
199
200\section{ROI}
201\label{sec:pythonroi}
202
203The \ROI class that describes an image extent or region of interest,
204explained in deail in Section~\ref{sec:ROI}, is replicated for Python.
205
206\apiitem{{\ce ROI} () \\
207{\ce ROI} (xbegin, xend, ybegin, yend) \\
208{\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend) \\
209{\ce ROI} (xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend)}
210Construct an \ROI with the given bounds.  The constructor with no
211arguments makes an \ROI that is ``undefined.''
212
213\noindent Example:
214\begin{code}
215    import OpenImageIO as oiio
216    ...
217    roi = ROI (0, 640, 0, 480, 0, 1, 0, 4)   # video res RGBA
218\end{code}
219\apiend
220
221\apiitem{int ROI.{\ce xbegin} \\
222int ROI.{\ce xend} \\
223int ROI.{\ce ybegin} \\
224int ROI.{\ce yend} \\
225int ROI.{\ce zbegin} \\
226int ROI.{\ce zend} \\
227int ROI.{\ce chbegin} \\
228int ROI.{\ce chend}}
229The basic fields of the \ROI.
230\apiend
231
232\apiitem{ROI ROI.{\ce All}}
233A pre-constructed undefined \ROI.
234\apiend
235
236\apiitem{bool ROI.{\ce defined}}
237{\cf True} if the \ROI is defined, {\cf False} if the \ROI is undefined.
238\apiend
239
240\apiitem{int ROI.{\ce width} \\
241int ROI.{\ce height} \\
242int ROI.{\ce depth} \\
243int ROI.{\ce nchannels}}
244The number of pixels in each dimension, and the number of channels,
245as described by the \ROI.
246\apiend
247
248\apiitem{int ROI.{\ce npixels}}
249The total number of pixels in the region described by the \ROI.
250\apiend
251
252\apiitem{int ROI.{\ce contains} (x, y, z=0, ch=0)}
253Returns {\cf True} if the ROI contains the coordinate.
254\apiend
255
256\apiitem{int ROI.{\ce contains} (other)}
257Returns {\cf True} if the ROI {\cf other} is entirel contained within
258this ROI.
259\apiend
260
261
262\apiitem{ROI {\ce get_roi} (imagespec) \\
263ROI {\ce get_roi_full} (imagespec)}
264Returns the \ROI corresponding to the pixel data window of the given
265\ImageSpec, or the display/full window, respectively.
266
267\noindent Example:
268\begin{code}
269    spec = ImageSpec(...)
270    roi = oiio.get_roi(spec)
271\end{code}
272\apiend
273
274\apiitem{{\ce set_roi} (imagespec, roi) \\
275{\ce set_roi_full} (imagespec, roi)}
276Alter the \ImageSpec's resolution and offset to match the passed \ROI.
277
278\noindent Example:
279\begin{code}
280    # spec is an ImageSpec
281    # The following sets the full (display) window to be equal to the
282    # pixel data window:
283    oiio.set_roi_full (spec, oiio.get_roi(spec))
284\end{code}
285\apiend
286
287
288\section{ImageSpec}
289\label{sec:pythonimagespec}
290
291The \ImageSpec class that describes an image, explained in deail in
292Section~\ref{sec:ImageSpec}, is replicated for Python.
293
294\apiitem{{\ce ImageSpec} ()\\
295{\ce ImageSpec} (typedesc) \\
296{\ce ImageSpec} (xres, yres, nchannels, typedesc) \\
297{\ce ImageSpec} (roi, typedesc)}
298Constructors of an \ImageSpec. These correspond directly to the constructors
299in the C++ bindings.
300
301\noindent Example:
302\begin{code}
303    import OpenImageIO as oiio
304    ...
305
306    # default ctr
307    s = ImageSpec()
308
309    # construct with known pixel type, unknown resolution
310    s = ImageSpec(oiio.UINT8)
311
312    # construct with known resolution, channels, pixel data type
313    s = ImageSpec(640, 480, 4, "half")
314
315    # construct from an ROI
316    s = ImageSpec (ROI(0,640,0,480,0,1,0,3), TypeFloat)
317\end{code}
318\apiend
319
320\apiitem{ImageSpec.{\ce width}, ImageSpec.{\ce height}, ImageSpec.{\ce depth} \\
321ImageSpec.{\ce x}, ImageSpec.{\ce y}, ImageSpec.{\ce z}}
322Resolution and offset of the image data ({\cf int} values).
323
324\noindent Example:
325\begin{code}
326    s = ImageSpec (...)
327    print "Data window is ({},{})-({},{})".format (s.x, s.x+s.width-1,
328                                                   s.y, s.y+s.height-1)
329\end{code}
330\apiend
331
332\apiitem{ImageSpec.{\ce full_width}, ImageSpec.{\ce full_height}, ImageSpec.{\ce full_depth} \\
333ImageSpec.{\ce full_x}, ImageSpec.{\ce full_y}, ImageSpec.{\ce full_z}}
334Resolution and offset of the ``full'' display window ({\cf int} values).
335\apiend
336
337\apiitem{ImageSpec.{\ce tile_width}, ImageSpec.{\ce tile_height}, ImageSpec.{\ce tile_depth}}
338For tiled images, the resolution of the tiles ({\cf int} values).  Will be
339{\cf 0} for  untiled images.
340\apiend
341
342\apiitem{typedesc ImageSpec.{\ce format}}
343A \TypeDesc describing the pixel data.
344\apiend
345
346\apiitem{int ImageSpec.{\ce nchannels}}
347An {\cf int} giving the number of color channels in the image.
348\apiend
349
350\apiitem{ImageSpec.{\ce channelnames}}
351A tuple of strings containing the names of each color channel.
352\apiend
353
354\apiitem{ImageSpec.{\ce channelformats}}
355If all color channels have the same format, that will be {\cf ImageSpec.format},
356and {\cf channelformats} will be {\cf None}.  However, if there are different
357formats per channel, they will be stored in {\cf channelformats} as a tuple
358of {\cf TypeDesc} objects.
359
360\noindent Example:
361\begin{code}
362    if spec.channelformats == None:
363        print "All color channels are", str(spec.format)
364    else:
365        print "Channel formats: "
366        for t in spec.channelformats:
367            print "\t", t
368\end{code}
369\apiend
370
371\apiitem{ImageSpec.{\ce alpha_channel} \\
372ImageSpec.{\ce z_channel}}
373The channel index containing the alpha or depth channel, respectively, or
374-1 if either one does not exist or cannot be identified.
375\apiend
376
377\apiitem{ImageSpec.{\ce deep}}
378Hold {\cf True} if the image is a \emph{deep} (multiple samples per pixel)
379image, of {\cf False} if it is an ordinary image.
380\apiend
381
382\apiitem{ImageSpec.{\ce extra_attribs}}
383Direct access to the {\cf extra_attribs} named metadata, appropriate for
384iterating over the entire list rather than searching for a particular named
385value.
386
387\vspace{-10pt}
388\apiitem{len(extra_attribs)}
389\vspace{10pt}
390Returns the number of extra attributes.
391\apiend
392\vspace{-24pt}
393\apiitem{extra_attribs[i].name}
394\vspace{10pt}
395The name of the indexed attribute.
396\apiend
397\vspace{-24pt}
398\apiitem{extra_attribs[i].type}
399\vspace{10pt}
400The type of the indexed attribute, as a \TypeDesc.
401\apiend
402\vspace{-24pt}
403\apiitem{extra_attribs[i].value}
404\vspace{10pt}
405The value of the indexed attribute.
406\apiend
407
408\noindent Example:
409\begin{code}
410    s = ImageSpec(...)
411    ...
412    print "extra_attribs size is", len(s.extra_attribs)
413    for i in range(len(s.extra_attribs)) :
414        print i, s.extra_attribs[i].name, str(s.extra_attribs[i].type), " :"
415        print "\t", s.extra_attribs[i].value
416    print
417\end{code}
418\apiend
419
420\apiitem{Imagespec.{\ce roi}}
421The ROI describing the pixel data window.
422\apiend
423
424\apiitem{ImageSpec.{\ce roi_full}}
425The ROI describing the ``display window'' (or ``full size'').
426\apiend
427
428\apiitem{ImageSpec.{\ce set_format} (typedesc)}
429Given a \TypeDesc, sets the {\cf format} field and
430clear any per-channel formats in {\cf channelformats}.
431
432\noindent Example:
433\begin{code}
434    s = ImageSpec ()
435    s.set_format (TypeDesc("uint8"))
436\end{code}
437\apiend
438
439\apiitem{ImageSpec.{\ce default_channel_names} ()}
440Sets {\cf channel_names} to the default names given the value of
441the {\cf nchannels} field.
442\apiend
443
444\apiitem{int ImageSpec.{\ce channelindex} (name)}
445Return (as an int) the index of the channel with the given name, or -1
446if it does not exist.
447\apiend
448
449\apiitem{ImageSpec.{\ce channel_bytes} () \\
450ImageSpec.{\ce channel_bytes} (channel, native=False)}
451Returns the size of a single channel value, in bytes (as an
452{\cf int}).
453(Analogous to the C++ member functions, see
454Section~\ref{sec:ImageSpecMemberFuncs} for details.)
455\apiend
456
457\apiitem{ImageSpec.{\ce pixel_bytes} () \\
458ImageSpec.{\ce pixel_bytes} (native=False) \\
459ImageSpec.{\ce pixel_bytes} (chbegin, chend, native=False)}
460Returns the size of a pixel, in bytes (as an {\cf int}).
461(Analogous to the C++ member functions, see
462Section~\ref{sec:ImageSpecMemberFuncs} for details.)
463\apiend
464
465\apiitem{ImageSpec.{\ce scanline_bytes} (native=False) \\
466ImageSpec.{\ce tile_bytes} (native=False) \\
467ImageSpec.{\ce image_bytes} (native=False)}
468Returns the size of a scanline, tile, or the full image, in bytes (as an
469{\cf int}). (Analogous to the C++ member functions, see
470Section~\ref{sec:ImageSpecMemberFuncs} for details.)
471\apiend
472
473\apiitem{ImageSpec.{\ce tile_pixels} () \\
474ImageSpec.{\ce image_pixels} ()}
475Returns the number of pixels in a tile or the full image, respectively
476(as an {\cf int}). (Analogous to the C++ member functions, see
477Section~\ref{sec:ImageSpecMemberFuncs} for details.)
478\apiend
479
480\apiitem{ImageSpec.{\ce erase_attribute} (name, searchtype=TypeUnknown,\\
481\bigspc\bigspc\spc casesensitive=False)}
482Remove any specified attributes matching the regular expression {\cf name}
483from the list of extra_attribs.
484\apiend
485
486\apiitem{ImageSpec.{\ce attribute} (name, int) \\
487ImageSpec.{\ce attribute} (name, float) \\
488ImageSpec.{\ce attribute} (name, string) \\
489ImageSpec.{\ce attribute} (name, typedesc, data) \\}
490Sets a metadata value in the {\cf extra_attribs}.  If the metadata item
491is a single {\cf int}, {\cf float}, or {\cf string}, you can pass it
492directly. For other types, you must pass the \TypeDesc and then the
493data (for aggregate types or arrays, pass multiple values as a tuple).
494
495\noindent Example:
496\begin{code}
497    s = ImageSpec (...)
498    s.attribute ("foo_str", "blah")
499    s.attribute ("foo_int", 14)
500    s.attribute ("foo_float", 3.14)
501    s.attribute ("foo_vector", TypeDesc.TypeVector, (1, 0, 11))
502    s.attribute ("foo_matrix", TypeDesc.TypeMatrix,
503                 (1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1))
504\end{code}
505\apiend
506
507\apiitem{ImageSpec.{\ce getattribute} (name) \\
508ImageSpec.{\ce getattribute} (name, typedesc)}
509Retrieves a named metadata value from {\cf extra_attribs}.  The generic
510{\cf getattribute()} function returns it regardless of type, or {\cf None}
511if the attribute does not exist.  The typed variety will only succeed
512if the attribute is actually of that type specified.
513
514\noindent Example:
515\begin{code}
516    foo = s.getattribute ("foo")   # None if not found
517    foo = s.getattribute ("foo", oiio.FLOAT)  # None if not found AND float
518\end{code}
519\apiend
520
521\apiitem{ImageSpec.{\ce get_int_attribute} (name, defaultval=0) \\
522ImageSpec.{\ce get_float_attribute} (name, defaultval=0.0) \\
523ImageSpec.{\ce get_string_attribute} (name, defaultval="")}
524Retrieves a named metadata value from {\cf extra_attribs}, if it is
525found and is of the given type; returns the default value (or a passed
526value) if not found.
527
528\noindent Example:
529\begin{code}
530    # If "foo" is not found, or if it's not an int, return 0
531    foo = s.get_int_attribute ("foo")
532
533    # If "foo" is not found, or if it's not a string, return "blah"
534    foo = s.get_string_attribute ("foo", "blah")
535\end{code}
536\apiend
537
538\apiitem{ImageSpec{\ce [name]}}
539\NEW % 2.1
540Retrieve or set metadata using a dictionary-like syntax, rather than
541{\cf attribute()} and {\cf getattribute()}. This is best illustrated by
542example:
543
544\begin{code}
545    comp = spec["Compression"]
546    # Same as:  comp = spec.getattribute("Compression")
547
548    spec["Compression"] = comp
549    # Same as: spec.attribute("Compression", comp)
550\end{code}
551\apiend
552
553%\apiitem{static ImageSpec.{\ce metadata_val} (paramval, human=False)}
554%For a \ParamValue, format its value as a string.
555%\apiend
556
557\apiitem{ImageSpec.{\ce serialize} (format="text", verbose="Detailed")}
558Return a string containing the serialization of the \ImageSpec. The {\cf format}
559may be either \qkw{text} or \qkw{XML}. The {\cf verbose} may be one of
560\qkw{brief}, \qkw{detailed}, or \qkw{detailedhuman}.
561\apiend
562
563\apiitem{ImageSpec.{\ce to_xml} ()}
564Equivalent to {\cf serialize ("xml", "detailedhuman")}.
565\apiend
566
567\apiitem{ImageSpec.{\ce from_xml} (xml)}
568Initializes the \ImageSpec from the information in the string {\cf xml}
569containing an XML-serialized \ImageSpec.
570\apiend
571
572\apiitem{ImageSpec.{\ce channel_name} (chan)}
573Returns a string containing the name of the channel with index {\cf chan}.
574\apiend
575
576\apiitem{ImageSpec.{\ce channelindex} (name)}
577Return the integer index of the channel with the given {\cf name}, or
578-1 if the name is not a name of one of the channels.
579\apiend
580
581\apiitem{ImageSpec.{\ce channelformat} (chan)}
582Returns a \TypeDesc of the channel with index {\cf chan}.
583\apiend
584
585\apiitem{ImageSpec.{\ce get_channelformats} ()}
586Returns a tuple containing all the channel formats.
587\apiend
588
589\apiitem{ImageSpec.{\ce valid_tile_range} (xbegin, xend, ybegin, yend, zbegin, zend)}
590Returns {\cf True} if the given tile range exactly covers a set of tiles, or
591{\cf False} if it isn't (or if the image is not tiled).
592\apiend
593
594\apiitem{ImageSpec.{\ce copy_dimensions} (other)}
595Copies from \ImageSpec {\cf other} only the fields describing the size
596and data types, but not the arbitrary named metadata or channel names.
597\apiend
598
599\apiitem{ImageSpec.{\ce undefined}()}
600Returns {\cf True} for a newly initialized (undefined) \ImageSpec.
601\apiend
602
603\newpage
604\subsection*{Example: Header info}
605
606Here is an illustrative example of the use of \ImageSpec, a working Python
607function that opens a file and prints all the relevant header
608information:
609
610\begin{tinycode}
611#!/usr/bin/env python
612import OpenImageIO as oiio
613
614# Print the contents of an ImageSpec
615def print_imagespec (spec, subimage=0, mip=0) :
616    if spec.depth <= 1 :
617        print ("  resolution %dx%d%+d%+d" % (spec.width, spec.height, spec.x, spec.y))
618    else :
619        print ("  resolution %dx%d%x%d+d%+d%+d" %
620               (spec.width, spec.height, spec.depth, spec.x, spec.y, spec.z))
621    if (spec.width != spec.full_width or spec.height != spec.full_height
622        or spec.depth != spec.full_depth) :
623        if spec.full_depth <= 1 :
624            print ("  full res   %dx%d%+d%+d" %
625                   (spec.full_width, spec.full_height, spec.full_x, spec.full_y))
626        else :
627            print ("  full res   %dx%d%x%d+d%+d%+d" %
628                   (spec.full_width, spec.full_height, spec.full_depth,
629                    spec.full_x, spec.full_y, spec.full_z))
630    if spec.tile_width :
631        print ("  tile size  %dx%dx%d" %
632               (spec.tile_width, spec.tile_height, spec.tile_depth))
633    else :
634        print "  untiled"
635    if mip >= 1 :
636        return
637    print "  " + str(spec.nchannels), "channels:", spec.channelnames
638    print "  format = ", str(spec.format)
639    if len(spec.channelformats) > 0 :
640        print "  channelformats = ", spec.channelformats
641    print "  alpha channel = ", spec.alpha_channel
642    print "  z channel = ", spec.z_channel
643    print "  deep = ", spec.deep
644    for i in spec.extra_attribs) :
645        if type(i.value) == str :
646            print " ", i.name, "= \"" + i.value + "\""
647        else :
648            print " ", i.name, "=", i.value
649
650
651def poor_mans_iinfo (filename) :
652    input = ImageInput.open (filename)
653    if not input :
654        print 'Could not open "' + filename + '"'
655        print "\tError: ", oiio.geterror()
656        return
657    print 'Opened "' + filename + '" as a ' + input.format_name()
658    sub = 0
659    mip = 0
660    while True :
661        if sub > 0 or mip > 0 :
662            print "Subimage", sub, "MIP level", mip, ":"
663        print_imagespec (input.spec(), mip=mip)
664        mip = mip + 1
665        if input.seek_subimage (sub, mip) :
666            continue    # proceed to next MIP level
667        else :
668            sub = sub + 1
669            mip = 0
670            if input.seek_subimage (sub, mip) :
671                continue    # proceed to next subimage
672        break  # no more MIP levels or subimages
673    input.close ()
674\end{tinycode}
675
676
677\section{DeepData}
678\label{sec:pythondeepdata}
679
680The \DeepData class describing ``deep'' image data (multiple depth
681sample per pixel), which is explained in deail in
682Section~\ref{sec:imageinput:deepdata}, is replicated for Python.
683
684\apiitem{{\ce DeepData} ()}
685Constructs a \DeepData object. It needs to have its {\cf init()} and
686{\cf alloc()} methods called before it can hold any meaningful data.
687\apiend
688
689\apiitem{DeepData.{\ce init} (npixels, nchannels, channeltypes, channelnames)}
690Initializes this \DeepData to hold {\cf npixels} total pixels, with
691{\cf nchannels} color channels. The data types of the channels are
692described by {\cf channeltypes}, a tuple of \TypeDesc values (one per
693channel), and the names are provided in a tuple of {\cf string}s
694{\cf channelnames}. After calling {\cf init}, you still need to set the number of
695samples for each pixel (using {\cf set_nsamples}) and then call {\cf alloc()}
696to actually allocate the sample memory.
697\apiend
698
699\apiitem{bool {\ce DeepData}.initialized ()}
700Returns {\cf True} if the \DeepData is initialized at all.
701\apiend
702
703\apiitem{bool {\ce DeepData}.allocated ()}
704Returns {\cf True} if the \DeepData has already had pixel memory allocated.
705\apiend
706
707\apiitem{DeepData.{\ce pixels}}
708This {\cf int} field constains the total number of pixels in this
709collection of deep data.
710\apiend
711
712\apiitem{DeepData.{\ce channels}}
713This {\cf int} field constains the number of channels.
714\apiend
715
716\apiitem{int DeepData.{\ce A_channel} \\
717int DeepData.{\ce AR_channel} \\
718int DeepData.{\ce AG_channel} \\
719int DeepData.{\ce AB_channel} \\
720int DeepData.{\ce Z_channel} \\
721int DeepData.{\ce Zback_channel}}
722The channel index of certain named channels, or -1 if they don't exist. For
723{\cf AR_channel}, {\cf AG_channel}, {\cf AB_channel}, if they don't exist,
724they will contain the value of {\cf A_channel}, and {\cf Zback_channel} will
725contain the value of {\cf Z_channel} if there is no actual {\cf Zback}.
726\apiend
727
728\apiitem{string DeepData.{\ce channelname} (c)}
729Retrieve the name of channel {\cf c}.
730\apiend
731
732\apiitem{TypeDesc DeepData.{\ce channeltype} (c)}
733Retrieve the data type of channel {\cf c}.
734\apiend
735
736\apiitem{int DeepData.{\ce channelsize} (c)}
737Retrieve the size (in bytes) of one datum of channel {\cf c}.
738\apiend
739
740\apiitem{int DeepData.{\ce samplesize} ()}
741Retrieve the packed size (in bytes) of all channels of one sample.
742\apiend
743
744
745\apiitem{DeepData.{\ce set_samples} (pixel, nsamples) \\
746int DeepData.{\ce samples} (pixel)}
747Set or get the number of samples for a given pixel (specified by integer
748index).
749\apiend
750
751\apiitem{DeepData.{\ce insert_samples} (pixel, samplepos, n) \\
752int DeepData.{\ce erase_samples} (pixel, samplepos, n)}
753Insert or erase \emph{n} samples starting at the given position of an
754indexed pixel.
755\apiend
756
757\apiitem{DeepData.{\ce set_deep_value} (pixel, channel, sample, value) \\
758DeepData.{\ce set_deep_value_uint} (pixel, channel, sample, value)}
759Set specific float or unsigned int value of a given pixel, channel, and
760sample index.
761\apiend
762
763\apiitem{DeepData.{\ce deep_value} (pixel, channel, sample, value) \\
764int DeepData.{\ce deep_value_uint} (pixel, channel, sample)}
765Retrieve the specific value of a given pixel,
766channel, and sample index (for float or uint channels, respectively).
767\apiend
768
769\apiitem{DeepData.{\ce copy_deep_sample} (pixel, sample, src, srcpixel, srcsample)}
770Copy a deep sample from \DeepData {\cf src} into this \DeepData.
771\apiend
772
773\apiitem{DeepData.{\ce copy_deep_pixel} (pixel, src, srcpixel)}
774Copy a deep pixel from \DeepData {\cf src} into this \DeepData.
775\apiend
776
777\apiitem{bool DeepData.{\ce split} (pixel, depth)}
778Split any samples of the pixel that cross {\cf depth}. Return {\cf True} if
779any splits occurred, {\cf False} if the pixel was unmodified.
780\apiend
781
782\apiitem{DeepData.{\ce sort} (pixel)}
783Sort the samples of the pixel by their Z depth.
784\apiend
785
786\apiitem{DeepData.{\ce merge_overlaps} (pixel)}
787Merge any adjacent samples in the pixel that exactly overlap in $z$
788range. This is only useful if the pixel has previously been split at
789all sample starts and ends, and sorted by depth.
790\apiend
791
792\apiitem{DeepData.{\ce merge_deep_pixels} (pixel, src, srcpixel)}
793Merge the samples of {\cf src}'s pixel into this \DeepData's pixel.
794\apiend
795
796\apiitem{DeepData.{\ce occlusion_cull} (pixel)}
797Eliminate any samples beyond an opaque sample.
798\apiend
799
800\apiitem{float DeepData.{\ce opaque_z} (pixel)}
801For the given pixel index. return the $z$ value at which the pixel reaches
802full opacity.
803\apiend
804
805
806
807\section{ImageInput}
808\label{sec:pythonimageinput}
809
810See Chapter~\ref{chap:imageinput} for detailed explanations of the
811C++ \ImageInput class APIs. The Python APIs are very similar. The biggest
812difference is that in C++, the various {\cf read_*} functions write the
813pixel values into an already-allocated array that belongs to the caller,
814whereas the Python versions allocate and return an array holding the pixel
815values (or {\cf None} if the read failed).
816
817
818\apiitem{ImageInput.{\ce open} (filename) \\
819ImageInput.{\ce open} (filename, config_imagespec)}
820Creates an \ImageInput object and opens the named file.  Returns the
821open \ImageInput upon success, or {\cf None} if it failed to open the
822file (after which, {\cf OpenImageIO.geterror()} will contain an error
823message).  In the second form, the optional \ImageSpec argument
824{\cf config} contains attributes that may set certain options when opening
825the file.
826
827\noindent Example:
828\begin{code}
829    input = ImageInput.open ("tahoe.jpg")
830    if input == None :
831        print "Error:", oiio.geterror()
832        return
833\end{code}
834\apiend
835
836\apiitem{bool ImageInput.{\ce close} ()}
837Closes an open image file, returning {\cf True} if successful, {\cf False}
838otherwise.
839
840\noindent Example:
841\begin{code}
842    input = ImageInput.open (filename)
843    ...
844    input.close ()
845\end{code}
846\apiend
847
848
849\apiitem{str ImageInput.{\ce format_name} ()}
850Returns the format name of the open file.
851
852\noindent Example:
853\begin{code}
854    input = ImageInput.open (filename)
855    if input :
856        print filename, "was a", input.format_name(), "file."
857        input.close ()
858
859\end{code}
860\apiend
861
862\apiitem{ImageSpec ImageInput.{\ce spec} ()}
863Returns the \ImageSpec corresponding to the currently open subimage and
864MIP level of the file.
865
866\noindent Example:
867\begin{code}
868    input = ImageInput.open (filename)
869    spec = input.spec()
870    print "resolution ", spec.width, "x", spec.height
871\end{code}
872\apiend
873
874\apiitem{ImageSpec ImageInput.{\ce spec} (subimage, miplevel=0) \\
875ImageSpec ImageInput.{\ce spec_dimensions} (subimage, miplevel=0)}
876Returns a copy of the \ImageSpec corresponding to the designated subimage
877and MIP level. Note that {\cf spec()} copies the entire \ImageSpec including
878all metadata, whereas {\cf spec_dimensions()} only copies the dimension
879fields and not any of the arbitrary named metadata (and is thus much less
880expensive).
881\apiend
882
883\apiitem{int ImageInput.{\ce current_subimage} () \\
884int ImageInput.{\ce current_miplevel} ()}
885Returns the current subimage and/or MIP level of the file.
886\apiend
887
888\apiitem{bool ImageInput.{\ce seek_subimage} (subimage, miplevel)}
889Repositions the file pointer to the given subimage and MIP level within the
890file (starting with {\cf 0}).  This function returns {\cf True} upon success,
891{\cf False} upon failure (which may include the file not having the
892specified subimage or MIP level).
893
894\noindent Example:
895\begin{code}
896    input = ImageInput.open (filename)
897    mip = 0
898    while True :
899        ok = input.seek_subimage (0, mip)
900        if not ok :
901            break
902        spec = input.spec()
903        print "MIP level", mip, "is", spec.width, "x", spec.height
904\end{code}
905\apiend
906
907\apiitem{ImageInput.{\ce read_image} (format="float") \\
908ImageInput.{\ce read_image} (chbegin, chend, format="float") \\
909ImageInput.{\ce read_image} (subimage, miplevel, chbegin, chend, format="float")}
910
911Read the entire image and return the pixels as a NumPy array of values of
912the given {\cf type} (described by a \TypeDesc or a string, float by
913default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be
914returned in the native format of the file. If an error occurs, {\cf None}
915will be returned.
916
917For a normal (2D) image, the array returned will be 3D indexed as
918{\cf [y][x][channel]}. For 3D volumetric images, the array returned will be
9194D with shape indexed as {\cf [z][y][x][channel]}.
920
921\noindent Example:
922\begin{code}
923    input = ImageInput.open (filename)
924    spec = input.spec ()
925    pixels = input.read_image ()
926    print "The first pixel is", pixels[0][0]
927    print "The second pixel is", pixels[0][1]
928    input.close ()
929\end{code}
930\apiend
931
932\apiitem{ndarray ImageInput.{\ce read_scanline} (y, z, format="float")}
933Read scanline number {\cf y} from depth plane {\cf z} from the open file,
934returning the pixels as a NumPy array of values of
935the given {\cf type} (described by a \TypeDesc or a string, float by
936default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be
937returned in the native format of the file. If an error occurs, {\cf None}
938will be returned.
939
940The pixel array returned be 2D, indexed as {\cf [x][channel]}.
941
942\noindent Example:
943\begin{code}
944    input = ImageInput.open (filename)
945    spec = input.spec ()
946    if spec.tile_width == 0 :
947        for y in range(spec.y, spec.y+spec.height) :
948            pixels = input.read_scanline (y, spec.z, "float")
949            # process the scanline
950    else :
951        print "It's a tiled file"
952    input.close ()
953\end{code}
954\apiend
955
956\apiitem{ndarray ImageInput.{\ce read_tile} (x, y, z, format="float")}
957Read the tile whose upper left corner is pixel {\cf (x,y,z)} from the open
958file, returning the pixels as a NumPy array of values of
959the given {\cf type} (described by a \TypeDesc or a string, float by
960default). If the {\cf type} is {\cf TypeUnknown}, the pixels will be
961returned in the native format of the file. If an error occurs, {\cf None}
962will be returned.
963
964For a normal (2D) image, the array of tile pixels returned will be 3D
965indexed as {\cf [y][x][channel]}. For 3D volumetric images, the array
966returned will be 4D with shape indexed as {\cf [z][y][x][channel]}.
967
968\noindent Example:
969\begin{code}
970    input = ImageInput.open (filename)
971    spec = input.spec ()
972    if spec.tile_width > 0 :
973        for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) :
974            for y in range(spec.y, spec.y+spec.height, spec.tile_height) :
975                for x in range(spec.x, spec.x+spec.width, spec.tile_width) :
976                    pixels = input.read_tile (x, y, z, oiio.FLOAT)
977                    # process the tile
978    else :
979        print "It's a scanline file"
980    input.close ()
981\end{code}
982\apiend
983
984\apiitem{ndarray ImageInput.{\ce read_scanlines} (subimage, miplevel, \\
985\bigspc\bigspc\spc ybegin, yend, z, chbegin, chend, format="float") \\
986ndarray ImageInput.{\ce read_scanlines} (ybegin, yend, z, chbegin, chend, \\
987\bigspc\bigspc\spc format="float") \\
988ndarray ImageInput.{\ce read_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, \\
989    \bigspc\bigspc\spc chbegin, chend, format="float") \\
990ndarray ImageInput.{\ce read_tiles} (subimage, miplevel, \\
991    \bigspc\bigspc\spc xbegin, xend, ybegin, yend, zbegin, zend, format="float")}
992Similar to the C++ routines, these functions read multiple scanlines or
993tiles at once, which in some cases may be more efficient than reading
994each scanline or tile separately.  Additionally, they allow you to read only
995a subset of channels.
996
997For normal 2D images, both {\cf read_scanlines} and {\cf read_tiles} will
998return a 3D array indexed as {\cf [z][y][x][channel]}.
999
1000For 3D volumetric images, both {\cf read_scanlines} will return a 3D array
1001indexed as {\cf [y][x][channel]}, and {\cf read_tiles} will return a 4D
1002array indexed as {\cf [z][y][x][channel]},
1003
1004\noindent Example:
1005\begin{code}
1006    input = ImageInput.open (filename)
1007    spec = input.spec ()
1008
1009    # Read the whole image, the equivalent of
1010    #     pixels = input.read_image (type)
1011    # but do it using read_scanlines or read_tiles:
1012    if spec.tile_width == 0 :
1013        pixels = input.read_scanlines (spec.y, spec.y+spec.height, 0,
1014                                       0, spec.nchannels)
1015    else :
1016        pixels = input.read_tiles (spec.x, spec.x+spec.width,
1017                                   spec.y, spec.y+spec.height,
1018                                   spec.z, spec.z+spec.depth,
1019                                   0, spec.nchannels)
1020\end{code}
1021\apiend
1022
1023\apiitem{DeepData ImageInput.{\ce read_native_deep_scanlines} (subimage, miplevel, \\
1024\bigspc\bigspc ybegin, yend, z, chbegin, chend) \\
1025DeepData ImageInput.{\ce read_native_deep_tiles} (subimage, miplevel, \\
1026\bigspc\bigspc xbegin, xend, ybegin, yend, zbegin, zend, chbegin, chend) \\
1027DeepData ImageInput.{\ce read_native_deep_image} (subimage=0, miplevel=0)}
1028Read a collection of scanlines, tiles, or an entire image of ``deep'' pixel
1029data from the specified subimage and MIP level. The begin/end coordinates
1030are all integer values. The value returned will be a \DeepData if the read
1031succeeds, or {\cf None} if the read fails.
1032
1033These methods are guaranteed to be thread-safe against simultaneous calls to
1034any of the other other {\cf read_native} calls that take an explicit
1035subimage/miplevel.
1036\apiend
1037
1038\apiitem{str ImageInput.{\ce geterror} ()}
1039Retrieves the error message from the latest failed operation on an
1040ImageInput.
1041
1042\noindent Example:
1043\begin{code}
1044    input = ImageInput.open (filename)
1045    if not input :
1046        print "Open error:", oiio.geterror()
1047        # N.B. error on open must be retrieved with the global geterror(),
1048        # since there is no ImageInput object!
1049    else :
1050        pixels = input.read_image (oiio.FLOAT)
1051        if not pixels :
1052            print "Read_image error:", input.geterror()
1053        input.close ()
1054\end{code}
1055\apiend
1056
1057\newpage
1058\subsection*{Example: Reading pixel values from a file to find min/max}
1059
1060\begin{code}
1061#!/usr/bin/env python
1062import OpenImageIO as oiio
1063
1064def find_min_max (filename) :
1065    input = ImageInput.open (filename)
1066    if not input :
1067        print 'Could not open "' + filename + '"'
1068        print "\tError: ", oiio.geterror()
1069        return
1070    spec = input.spec()
1071    nchans = spec.nchannels
1072    pixels = input.read_image()
1073    if not pixels :
1074        print "Could not read:", input.geterror()
1075        return
1076    input.close()    # we're done with the file at this point
1077    minval = pixels[0][0]   # initialize to the first pixel value
1078    maxval = pixels[0][0]
1079    for y in range(spec.height) :
1080        for x in range(spec.width) :
1081            p = pixels[y][x]
1082            for c in range(nchans) :
1083                if p[c] < minval[c] :
1084                    minval[c] = p[c]
1085                if p[c] > maxval[c] :
1086                    maxval[c] = p[c]
1087    print "Min values per channel were", minval
1088    print "Max values per channel were", maxval
1089\end{code}
1090\newpage
1091
1092
1093\section{ImageOutput}
1094\label{sec:pythonimageoutput}
1095
1096See Chapter~\ref{chap:imageoutput} for detailed explanations of the
1097C++ \ImageOutput class APIs. The Python APIs are very similar.
1098
1099\apiitem{ImageOutput ImageOutput.{\ce create} (filename, plugin_searchpath="")}
1100
1101Create a new \ImageOutput capable of writing the named file format (which may
1102also be a file name, with the type deduced from the extension).  There
1103is an optional parameter giving an colon-separated search path for finding
1104\ImageOutput plugins.  The function returns an \ImageOutput object, or
1105{\cf None} upon error (in which case, {OpenImageIO.geterror()} may be used
1106to retrieve the error message).
1107
1108\noindent Example:
1109\begin{code}
1110    import OpenImageIO as oiio
1111    output = ImageOutput.create ("myfile.tif")
1112    if not output :
1113        print "Error:", oiio.geterror()
1114\end{code}
1115\apiend
1116
1117\apiitem{str ImageOutput.{\ce format_name} ()}
1118The file format name of a created \ImageOutput.
1119
1120\noindent Example:
1121\begin{code}
1122    output = ImageOutput.create (filename)
1123    if output :
1124        print "Created output", filename, "as a", output.format_name()
1125\end{code}
1126\apiend
1127
1128\apiitem{int ImageOutput.{\ce supports} (feature)}
1129For a created \ImageOutput, returns {\cf True} if the file format supports
1130the named feature (such as \qkw{tiles}, \qkw{mipmap}, etc., see
1131Section~\ref{sec:supportsfeaturelist} for the full list), or {\cf False}
1132if this file format does not support the feature.
1133
1134\noindent Example:
1135\begin{code}
1136    output = ImageOutput.create (filename)
1137    if output :
1138        print output.format_name(), "supports..."
1139        print "tiles?", output.supports("tiles")
1140        print "multi-image?", output.supports("multiimage")
1141        print "MIP maps?", output.supports("mipmap")
1142        print "per-channel formats?", output.supports("channelformats")
1143\end{code}
1144\apiend
1145
1146\apiitem{bool ImageOutput.{\ce open} (filename, spec, mode="Create")}
1147Opens the named output file, with an \ImageSpec describing the image to
1148be output.  The {\cf mode} may be one of \qkw{create}, \qkw{AppendSubimage},
1149or \qkw{AppendMIPLevel}.
1150See Section~\ref{sec:imageoutputopen} for details.  Returns {\cf True}
1151upon success, {\cf False} upon failure (error messages retrieved via
1152{\cf ImageOutput.geterror()}.)
1153
1154\noindent Example:
1155\begin{code}
1156    output = ImageOutput.create (filename)
1157    if not output :
1158        print "Error:", oiio.geterror()
1159    spec = ImageSpec (640, 480, 3, "uint8")
1160    ok = output.open (filename, spec)
1161    if not ok :
1162        print "Could not open", filename, ":", output.geterror()
1163\end{code}
1164\apiend
1165
1166\apiitem{bool ImageOutput.{\ce open} (filename, (imagespec, ...))}
1167This variety of {\cf open()} is used specifically for multi-subimage files.
1168A \emph{tuple} of \ImageSpec objects is passed, one for each subimage
1169that will be written to the file.  After each subimage is written, then
1170a regular call to {\cf open(name, newspec, {\ce AppendSubimage})} moves
1171on to the next subimage.
1172\apiend
1173
1174\apiitem{bool ImageOutput.{\ce close} ()}
1175Closes an open output.
1176\apiend
1177
1178\apiitem{ImageSpec ImageOutput.{\ce spec} ()}
1179Retrieves the \ImageSpec of the currently-open output image.
1180\apiend
1181
1182\apiitem{bool ImageOutput.{\ce write_image} (pixels)}
1183Write the currently opened image all at once.  The {\cf pixels} parameter
1184should be a Numpy {\cf ndarray} containing data elements indexed as
1185{\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images,
1186as {\cf [z][y][x][channel]}, in other words, exactly matching the shape of
1187array returned by {\cf ImageInput.read_image}. (It will also work fine if
1188the array is 1D ``flattened'' version, as long as it contains the correct
1189total number of values.) The data type is deduced from the contents of the
1190array itself. Returns {\cf True} upon success, {\cf False} upon failure.
1191
1192\noindent Example:
1193\begin{code}
1194    # This example reads a scanline file, then converts it to tiled
1195    # and writes to the same name.
1196
1197    input = ImageInput.open (filename)
1198    spec = input.spec ()
1199    pixels = input.read_image ()
1200    input.close ()
1201
1202    output = ImageOutput.create (filename)
1203    if output.supports("tiles") :
1204        spec.tile_width = 64
1205        spec.tile_height = 64
1206        output.open (filename, spec)
1207        output.write_image (pixels)
1208        output.close ()
1209\end{code}
1210\apiend
1211
1212\apiitem{bool ImageOutput.{\ce write_scanline} (y, z, pixels) \\
1213bool ImageOutput.{\ce write_scanlines} (ybegin, yend, z, pixels)}
1214
1215Write one or many scanlines to the currently open file.
1216Returns {\cf True} upon success, {\cf False} upon failure.
1217
1218The {\cf pixels} parameter
1219should be a Numpy {\cf ndarray} containing data elements indexed as
1220{\cf [x][channel]} for {\cf write_scanline} or as {\cf [y][x][channels}
1221for {\cf write_scanlines}, exactly matching the shape returned by
1222{\cf ImageInput.read_scanline} or {\cf ImageInput.read_scanlines}.
1223(It will also work fine if the array is 1D ``flattened'' version, as long
1224as it contains the correct total number of values.)
1225
1226\noindent Example:
1227\begin{code}
1228    # Copy a TIFF image to JPEG by copying scanline by scanline.
1229    input = ImageInput.open ("in.tif")
1230    spec = input.spec ()
1231    output = ImageOutput.create ("out.jpg")
1232    output.open (filename, spec)
1233    for z in range(spec.z, spec.z+spec.depth) :
1234        for y in range(spec.y, spec.y+spec.height) :
1235            pixels = input.read_scanline (y, z)
1236            output.write_scanline (y, z, pixels)
1237    output.close ()
1238    input.close ()
1239
1240    # The same example, but copying a whole "plane" of scanlines at a time:
1241    ...
1242    for z in range(spec.z, spec.z+spec.depth) :
1243        pixels = input.read_scanlines (spec.y, spec.y+spec.height, z)
1244        output.write_scanlines (spec.y, spec.y+spec.height, z, pixels)
1245    ...
1246\end{code}
1247\apiend
1248
1249\apiitem{bool ImageOutput.{\ce write_tile} (x, y, z, pixels) \\
1250bool ImageOutput.{\ce write_tiles} (xbegin, xend, ybegin, yend, zbegin, zend, pixels)}
1251
1252Write one or many tiles to the currently open file.
1253Returns {\cf True} upon success, {\cf False} upon failure.
1254
1255The {\cf pixels} parameter
1256should be a Numpy {\cf ndarray} containing data elements indexed as
1257{\cf [y][x][channel]} for normal 2D images, or as {\cf [z][y][x][channels}
12583D volumetric images, exactly matching the shape returned by
1259{\cf ImageInput.read_tile} or {\cf ImageInput.read_tiles}.
1260(It will also work fine if the array is 1D ``flattened'' version, as long
1261as it contains the correct total number of values.)
1262
1263\noindent Example:
1264\begin{code}
1265    input = ImageInput.open (in_filename)
1266    spec = input.spec ()
1267    output = ImageOutput.create (out_filename)
1268    output.open (out_filename, spec)
1269    for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) :
1270        for y in range(spec.y, spec.y+spec.height, spec.tile_height) :
1271            for x in range(spec.x, spec.x+spec.width, spec.tile_width) :
1272                pixels = input.read_tile (x, y, z)
1273                output.write_tile (x, y, z, pixels)
1274    output.close ()
1275    input.close ()
1276
1277    # The same example, but copying a whole row of of tiles at a time:
1278    ...
1279    for z in range(spec.z, spec.z+spec.depth, spec.tile_depth) :
1280        for y in range(spec.y, spec.y+spec.height, spec.tile_height) :
1281            pixels = input.read_tiles (spec.x, spec.x+spec.width,
1282                                       y, y+tile_width, z, z+tile_width)
1283            output.write_tiles (spec.x, spec.x+spec.width,
1284                                y, y+tile_width, z, z+tile_width, pixels)
1285    ...
1286\end{code}
1287\apiend
1288
1289\apiitem{bool ImageOutput.{\ce write_deep_scanlines} (ybegin, yend, z, deepdata) \\
1290bool ImageOutput.{\ce write_deep_tiles} (xbegin, xend, ybegin, yend, \\
1291\bigspc\bigspc\bigspc zbegin, zend, deepdata) \\
1292bool ImageOutput.{\ce write_deep_image} (deepdata)}
1293
1294Write a collection of scanlines, tiles, or an entire image of ``deep''
1295pixel data. The begin/end coordinates are all integer values, and
1296{\cf deepdata} should be a \DeepData.
1297\apiend
1298
1299\apiitem{bool ImageOutput.{\ce copy_image} (imageinput)}
1300Copy the current image of the open input to the open output. (The reason
1301this may be preferred in some circumstances is that, if input and
1302output were the same kind of input file format, they may have a special
1303efficient technique to copy pixels unaltered, for example by avoiding the
1304decompression/recompression round trip.)
1305
1306\noindent Example:
1307\begin{code}
1308    input = ImageInput.open (in_filename)
1309    spec = input.spec ()
1310    output = ImageOutput.create (out_filename)
1311    output.open (filename, spec)
1312    output.copy_image (input)
1313    output.close ()
1314    input.close ()
1315\end{code}
1316\apiend
1317
1318\apiitem{str ImageOuput.{\ce geterror} ()}
1319Retrieves the error message from the latest failed operation on an open
1320file.
1321
1322\noindent Example:
1323\begin{code}
1324    output = ImageOutput.create (filename)
1325    if not output :
1326        print "Create error:", oiio.geterror()
1327        # N.B. error on create must be retrieved with the global geterror(),
1328        # since there is no ImageOutput object!
1329    else :
1330        ok = output.open (filename, spec)
1331        if not ok :
1332            print "Open error:", output.geterror()
1333        ok = output.write_image (pixels)
1334        if not ok :
1335            print "Write error:", output.geterror()
1336        output.close ()
1337\end{code}
1338\apiend
1339
1340
1341
1342\section{ImageBuf}
1343\label{sec:pythonimagebuf}
1344
1345See Chapter~\ref{chap:imagebuf} for detailed explanations of the
1346C++ \ImageBuf class APIs. The Python APIs are very similar.
1347
1348\apiitem{ImageBuf {\ce ImageBuf} ()}
1349Construct a new, empty \ImageBuf. The \ImageBuf is uninitialized and is
1350awaiting a call to {\cf reset()} or {\cf copy()} before it is useful.
1351\apiend
1352
1353\apiitem{ImageBuf {\ce ImageBuf} (filename) \\
1354ImageBuf {\ce ImageBuf} (filename, subimage, miplevel)}
1355
1356Construct a read-only \ImageBuf that will read from the named file.
1357Optionally, a specific subimage or MIP level may be specified (defaulting to
13580).
1359
1360\noindent Example:
1361\begin{code}
1362    import OpenImageIO as oiio
1363    ...
1364    buf = ImageBuf ("grid.tif")
1365\end{code}
1366\apiend
1367
1368\apiitem{ImageBuf {\ce ImageBuf} (imagespec, zero = True)}
1369
1370Construct a writable \ImageBuf of the dimensions and data format specified
1371by an \ImageSpec. The pixels will be initialized to black/empty values if
1372{\cf zero} is True, otherwise the pixel values will remain uninitialized.
1373
1374\noindent Example:
1375\begin{code}
1376    spec = ImageSpec (640, 480, 3, "float")
1377    buf = ImageBuf (spec)
1378\end{code}
1379\apiend
1380
1381\apiitem{ImageBuf.{\ce clear} ()}
1382Resets the \ImageBuf to a pristine state identical to that of a freshly
1383constructed \ImageBuf using the default constructor.
1384
1385\noindent Example:
1386\begin{code}
1387    buf = ImageBuf (...)
1388
1389    # The following two commands are equivalent:
1390    buf = ImageBuf()     # 1 - assign a new blank ImageBuf
1391    buf.clear()          # 2 - clear the existing ImageBuf
1392\end{code}
1393\apiend
1394
1395\apiitem{ImageBuf.{\ce reset} (filename, subimage=0, miplevel=0, config=ImageSpec())}
1396Restore the \ImageBuf to a newly-constructed state, to read from
1397a filename (optionally specifying a subimage, MIP level, and/or
1398a ``configuration'' \ImageSpec).
1399\apiend
1400
1401\apiitem{ImageBuf.{\ce reset} (imagespec, zero = True)}
1402Restore the \ImageBuf to the newly-constructed state of a writable
1403\ImageBuf specified by an \ImageSpec.
1404The pixels will be iniialized to black/empty if {\cf zero} is True,
1405otherwise the pixel values will remain uninitialized.
1406\apiend
1407
1408\apiitem{bool ImageBuf.{\ce read} (subimage=0, miplevel=0, force=False, convert=oiio.UNKNOWN) \\
1409bool ImageBuf.{\ce read} (subimage, miplevel, chbegin, chend, force, convert)}
1410Explicitly read the image from the file (of a file-reading \ImageBuf), optionally
1411specifying a particular subimage, MIP level, and channel range.  If {\cf force} is {\cf True},
1412will force an allocation of memory and a full read (versus the default of
1413relying on an underlying \ImageCache).  If {\cf convert} is not
1414the default of {\cf UNKNOWN}, it will force the \ImageBuf to convert the
1415image to the specified data format (versus keeping it in the native
1416format or relying on the \ImageCache to make a data formatting decision).
1417
1418Note that a call to {\cf read()} is not necessary --- any \ImageBuf API call
1419that accesses pixel values will trigger a file read if it has not yet been
1420done. An explicit {\cf read()} is generally only needed to change the
1421subimage or miplevel, or to force an in-buffer read or format conversion.
1422
1423The {\cf read()} method will return {\cf True} for success, or {\cf False}
1424if the read could not be performed (in which case, a {\cf geterror()} call
1425will retrieve the specific error message).
1426
1427\noindent Example:
1428\begin{code}
1429    buf = ImageBuf ("mytexture.exr")
1430    buf.read (0, 2, True)
1431    # That forces an allocation and read of MIP level 2
1432\end{code}
1433\apiend
1434
1435\apiitem{bool ImageBuf.{\ce init_spec} (filename, subimage=0, miplevel=0)}
1436
1437Explicitly read just the header from a file-reading \ImageBuf (if the header
1438has not yet been read), optionally specifying a particular subimage and MIP
1439level. The {\cf init_spec()} method will return {\cf True} for success, or
1440{\cf False} if the read could not be performed (in which case, a {\cf
1441geterror()} call will retrieve the specific error message).
1442
1443Note that a call to {\cf init_spec()} is not necessary --- any \ImageBuf API
1444call that accesses the spec will read it automatically it has not yet been
1445done.
1446\apiend
1447
1448\apiitem{bool ImageBuf.{\ce write} (filename, dtype="", fileformat="")}
1449Write the contents of the \ImageBuf to the named file.  Optionally,
1450{\cf dtype} can override the pixel data type (by default, the pixel data
1451type of the buffer), and {\cf fileformat} can specify a particular file
1452format to use (by default, it will infer it from the extension of the file
1453name).
1454
1455\noindent Example:
1456\begin{code}
1457    # No-frills conversion of a TIFF file to JPEG
1458    buf = ImageBuf ("in.tif")
1459    buf.write ("out.jpg")
1460
1461    # Convert to uint16 TIFF
1462    buf = ImageBuf ("in.exr")
1463    buf.write ("out.tif", "uint16")
1464\end{code}
1465\apiend
1466
1467\apiitem{bool ImageBuf.{\ce make_writable} (keep_cache_type = false)}
1468Force the \ImageBuf to be writable. That means that if it was previously
1469backed by an \ImageCache (storage was {\cf IMAGECACHE}), it will force a
1470full read so that the whole image is in local memory.
1471\apiend
1472
1473
1474\apiitem{bool ImageBuf.{\ce set_write_format} (format=oiio.UNKNOWN) \\
1475bool ImageBuf.{\ce set_write_tiles} (width=0, height=0, depth=0)}
1476Override the data format or tile size in a subsequent call to {\cf write()}.
1477The {\cf format}argument to {\cf set_write_format} may be either a single
1478data type description for all channels, or a tuple giving the data type for
1479each channel in order.
1480
1481\noindent Example:
1482\begin{code}
1483    # Conversion to a tiled unsigned 16 bit integer file
1484    buf = ImageBuf ("in.tif")
1485    buf.set_write_format ("uint16")
1486    buf.set_write_tiles (64, 64)
1487    buf.write ("out.tif")
1488\end{code}
1489\apiend
1490
1491\apiitem{ImageSpec ImageBuf.{\ce spec}() \\
1492ImageSpec ImageBuf.{\ce nativespec}()}
1493{\cf ImageBuf.spec()} returns the \ImageSpec that describes the contents of
1494the \ImageBuf.  {\cf ImageBuf.nativespec()} returns an \ImageSpec that
1495describes the contents of the file that the \ImageBuf was read from (this
1496may differ from {\cf ImageBuf.spec()} due to format conversions, or any
1497changes made to the \ImageBuf after the file was read, such as adding
1498metadata).
1499
1500Handy rule of thumb: {\cf spec()} describes the buffer, {\cf nativespec()}
1501describes the original file it came from.
1502
1503\noindent Example:
1504\begin{code}
1505    buf = ImageBuf ("in.tif")
1506    print "Resolution is", buf.spec().width, "x", buf.spec().height
1507\end{code}
1508\apiend
1509
1510\apiitem{ImageSpec ImageBuf.{\ce specmod}()}
1511{\cf ImageBuf.specmod()} provides writable access to the \ImageSpec that
1512describes the contents of the \ImageBuf.  Be very careful!  It is safe
1513to modify certain metadata, but if you change the data format or resolution
1514fields, you will get the chaos you deserve.
1515
1516\noindent Example:
1517\begin{code}
1518    # Read an image, add a caption metadata, write it back out in place
1519    buf = ImageBuf ("file.tif")
1520    buf.specmod().attribute ("ImageDescription", "my photo")
1521    buf.write ("file.tif")
1522\end{code}
1523\apiend
1524
1525\apiitem{str ImageBuf.{\ce name} \\
1526str ImageBuf.{\ce file_format_name}}
1527The file name and name of the file format of the image.
1528\apiend
1529
1530\apiitem{int ImageBuf.{\ce subimage} \\
1531int ImageBuf.{\ce miplevel} \\
1532int ImageBuf.{\ce nsubimages} \\
1533int ImageBuf.{\ce nmiplevels}}
1534Several fields giving information about the current subimage and MIP
1535level, and the total numbers thereof in the file.
1536\apiend
1537
1538\apiitem{int ImageBuf.{\ce xbegin} \\
1539int ImageBuf.{\ce xend} \\
1540int ImageBuf.{\ce ybegin} \\
1541int ImageBuf.{\ce yend} \\
1542int ImageBuf.{\ce zbegin} \\
1543int ImageBuf.{\ce zend}}
1544The range of valid pixel data window. Remember that the {\cf end} is
1545\emph{one past} the last pixel.
1546\apiend
1547
1548\apiitem{int ImageBuf.{\ce xmin} \\
1549int ImageBuf.{\ce xmax} \\
1550int ImageBuf.{\ce ymin} \\
1551int ImageBuf.{\ce ymax} \\
1552int ImageBuf.{\ce zmin} \\
1553int ImageBuf.{\ce zmax}}
1554The minimum and maximum (inclusive) coordinates of the pixel data window.
1555\apiend
1556
1557\apiitem{int ImageBuf.{\ce orientation} \\
1558int ImageBuf.{\ce oriented_width} \\
1559int ImageBuf.{\ce oriented_height} \\
1560int ImageBuf.{\ce oriented_x} \\
1561int ImageBuf.{\ce oriented_y} \\
1562int ImageBuf.{\ce oriented_full_width} \\
1563int ImageBuf.{\ce oriented_full_height} \\
1564int ImageBuf.{\ce oriented_full_x} \\
1565int ImageBuf.{\ce oriented_full_y}}
1566The {\cf orientation} field gives the suggested display oriententation of
1567the image (see Section~\ref{metadata:orientation}).
1568
1569The other fields are helpers that give the width, height, and origin
1570(as well as ``full'' or ``display'' resolution and origin), taking the
1571intended orientation into consideration.
1572\apiend
1573
1574\apiitem{ROI ImageBuf.{\ce roi} \\
1575ROI ImageBuf.{\ce roi_full}}
1576These fields return an \ROI description of the pixel data window
1577({\cf roi}) and the full (a.k.a.\ ``display'') window ({\cf roi_full}).
1578
1579\noindent Example:
1580\begin{code}
1581    buf = ImageBuf ("tahoe.jpg")
1582    print "Resolution is", buf.roi.width, "x", buf.roi.height
1583\end{code}
1584\apiend
1585
1586\apiitem{ImageBuf.{\ce set_origin} (x, y, z=0)}
1587Changes the ``origin'' of the data pixel data window to the specified
1588coordinates.
1589
1590\noindent Example:
1591\begin{code}
1592    # Shift the pixel data so the upper left is at pixel (10, 10)
1593    buf.set_origin (10, 10)
1594\end{code}
1595\apiend
1596
1597\apiitem{ImageBuf.{\ce set_full} (roi)}
1598Changes the ``full'' (a.k.a. ``display'') window to the specified ROI.
1599
1600\noindent Example:
1601\begin{code}
1602    newroi = ROI (0, 1024, 0, 768)
1603    buf.set_full (newroi)
1604\end{code}
1605\apiend
1606
1607\apiitem{bool ImageBuf.{\ce pixels_valid}}
1608Will be {\cf True} if the file has already been read and the pixels are
1609valid. (It is always {\cf True} for writable \ImageBuf's.)
1610There should be few good reasons to access these, since the spec and pixels
1611will be automatically be read when they are needed.
1612\apiend
1613
1614\apiitem{TypeDesc ImageBuf.{\ce pixeltype}}
1615Returns the description of the data type of the pixels stored within the
1616\ImageBuf.
1617\apiend
1618
1619\apiitem{ImageBuf.{\ce copy_metadata} (other_imagebuf)}
1620Replaces the metadata (all \ImageSpec items, except for the data format
1621and pixel data window size) with the corresponding metadata from the
1622other \ImageBuf.
1623\apiend
1624
1625\apiitem{ImageBuf.{\ce copy_pixels} (other_imagebuf)}
1626Replace the pixels in this \ImageBuf with the values from the other
1627\ImageBuf.
1628\apiend
1629
1630\apiitem{ImageBuf ImageBuf.{\ce copy} (format=TypeUnknown)}
1631Return a full copy of this \ImageBuf (with optional data format conversion,
1632if {\cf format} is supplied).
1633
1634\noindent Example:
1635\begin{code}
1636    A = ImageBuf("A.tif")
1637
1638    # Make a separate, duplicate copy of A
1639    B = A.copy()
1640
1641    # Make another copy of A, but converting to float pixels
1642    C = A.copy ("float")
1643\end{code}
1644\apiend
1645
1646\apiitem{ImageBuf.{\ce copy} (other_imagebuf, format=TypeUnknown)}
1647Make this \ImageBuf a complete copy of the other \ImageBuf.
1648If a {\cf format} is provided, {\cf this} will get the specified pixel
1649data type rather than using the same pixel format as the source \ImageBuf.
1650
1651\noindent Example:
1652\begin{code}
1653    A = ImageBuf("A.tif")
1654
1655    # Make a separate, duplicate copy of A
1656    B = ImageBuf()
1657    B.copy (A)
1658
1659    # Make another copy of A, but converting to float pixels
1660    C = ImageBuf()
1661    C.copy (A, oiio.FLOAT)
1662\end{code}
1663\apiend
1664
1665\apiitem{ImageBuf.{\ce swap} (other_imagebuf)}
1666Swaps the content of this \ImageBuf and the other \ImageBuf.
1667
1668\noindent Example:
1669\begin{code}
1670    A = ImageBuf("A.tif")
1671    B = ImageBuf("B.tif")
1672    A.swap (B)
1673    # Now B contains the "A.tif" image and A contains the "B.tif" image
1674\end{code}
1675\apiend
1676
1677\apiitem{tuple ImageBuf.{\ce getpixel} (x, y, z=0, wrap="black")}
1678Retrieves pixel $(x,y,z)$ from the buffer and return it as a tuple of
1679{\cf float} values, one for each color channel.  The {\cf x, y, z} values
1680are {\cf int} pixel coordinates.  The optional {\cf wrap} parameter
1681describes what should happen if the coordinates are outside the pixel data
1682window (and may be: \qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}).
1683
1684\noindent Example:
1685\begin{code}
1686    buf = ImageBuf ("tahoe.jpg")
1687    p = buf.getpixel (50, 50)
1688    print p
1689
1690    > (0.37, 0.615, 0.97)
1691\end{code}
1692\apiend
1693
1694\apiitem{float ImageBuf.{\ce getchannel} (x, y, z, channel, wrap="black")}
1695Retrieves just a single channel value from pixel $(x,y,z)$ from the buffer
1696and returns it as a {\cf float} value.  The optional {\cf wrap} parameter
1697describes what should happen if the coordinates are outside the pixel data
1698window (and may be: \qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}).
1699
1700\noindent Example:
1701\begin{code}
1702    buf = ImageBuf ("tahoe.jpg")
1703    green = buf.getchannel (50, 50, 0, 1)
1704\end{code}
1705\apiend
1706
1707\apiitem{tuple ImageBuf.{\ce interppixel} (x, y, wrap="black") \\
1708tuple ImageBuf.{\ce interppixel_bicubic} (x, y, wrap="black")}
1709Interpolates the image value (bilinearly or bicubically)
1710at coordinates $(x,y)$ and return it as a tuple
1711of {\cf float} values, one for each color channel.  The {\cf x, y} values
1712are continuous {\cf float} coordinates in ``pixel space.''   The optional
1713{\cf wrap} parameter describes what should happen if the coordinates are
1714outside the pixel data window (and may be:
1715\qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}).
1716
1717\noindent Example:
1718\begin{code}
1719    buf = ImageBuf ("tahoe.jpg")
1720    midx = float(buf.xbegin + buf.xend) / 2.0
1721    midy = float(buf.ybegin + buf.yend) / 2.0
1722    p = buf.interpixel (midx, midy)
1723    # Now p is the interpolated value from right in the center of
1724    # the data window
1725\end{code}
1726\apiend
1727
1728\apiitem{tuple ImageBuf.{\ce interppixel_NDC} (x, y, wrap="black") \\
1729tuple ImageBuf.{\ce interppixel_bicubic_NDC} (x, y, wrap="black")}
1730
1731Interpolates the image value (bilinearly or bicubically)
1732at coordinates $(x,y)$ and return it as a tuple
1733of {\cf float} values, one for each color channel.  The {\cf x, y} values
1734are continuous, normalized {\cf float} coordinates in ``NDC space,'' where
1735{\cf (0,0)} is the upper left corner of the full (a.k.a.\ ``display'')
1736window, and {\cf (1,1)} is the lower right corner of the full/display
1737window. The  {\cf wrap} parameter describes what should happen if the
1738coordinates are outside the pixel data window (and may be:
1739\qkw{black}, \qkw{clamp}, \qkw{periodic}, \qkw{mirror}).
1740
1741\noindent Example:
1742\begin{code}
1743    buf = ImageBuf ("tahoe.jpg")
1744    p = buf.interpixel_NDC (0.5, 0.5)
1745    # Now p is the interpolated value from right in the center of
1746    # the display window
1747\end{code}
1748\apiend
1749
1750\apiitem{ImageBuf.{\ce setpixel} (x, y, pixel_value) \\
1751ImageBuf.{\ce setpixel} (x, y, z, pixel_value)}
1752Sets pixel $(x,y,z)$ to be the {\cf pixel_value}, expressed as a tuple of
1753{\cf float}s (one for each color channel).
1754
1755\noindent Example:
1756\begin{code}
1757    buf = ImageBuf (ImageSpec (640, 480, 3, oiio.UINT8))
1758
1759    # Set the whole image to red (the dumb slow way, but it works):
1760    for y in range(buf.ybegin, buf.yend) :
1761        for x in range(buf.xbegin, buf.xend) :
1762            buf.setpixel (x, y, (1.0, 0.0, 0.0))
1763\end{code}
1764\apiend
1765
1766\apiitem{array ImageBuf.{\ce get_pixels} (format=TypeFloat, roi=ROI.All)}
1767
1768Retrieves the rectangle of pixels (and channels) specified by {\cf roi} from
1769the image and returns them as an array of values with type specified by
1770{\cf format}.
1771
1772As with the {\cf ImageInput} read functions, the return value is a NumPy
1773{\cf ndarray} containing data elements indexed as
1774{\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images,
1775as {\cf [z][y][x][channel]}).
1776Returns {\cf True} upon success, {\cf False} upon failure.
1777
1778\noindent Example:
1779\begin{code}
1780    buf = ImageBuf ("tahoe.jpg")
1781    pixels = buf.get_pixels (oiio.FLOAT)  # no ROI means the whole image
1782\end{code}
1783\apiend
1784
1785\apiitem{ImageBuf.{\ce set_pixels} (roi, data)}
1786
1787Sets the rectangle of pixels (and channels) specified by {\cf roi} with
1788values in the {\cf data}, which is a NumPy {\cf ndarray} of values
1789indexed as {\cf [y][x][channel]} for normal 2D images, or for 3D volumetric images,
1790as {\cf [z][y][x][channel]}. (It will also work fine if
1791the array is 1D ``flattened'' version, as long as it contains the correct
1792total number of values.) The data type is deduced from the contents of the
1793array itself.
1794
1795\noindent Example:
1796\begin{code}
1797    buf = ImageBuf (...)
1798    pixels = (....)
1799    buf.set_pixels (ROI(), pixels)
1800\end{code}
1801\apiend
1802
1803\apiitem{bool ImageBuf.{\ce has_error} \\
1804str ImageBuf.{\ce geterror} ()}
1805The {\cf ImageBuf.has_error} field will be {\cf True} if an error has
1806occurred in the \ImageBuf, in which case the {\cf geterror()} method will
1807retrieve the error message (and clear it afterwards).
1808
1809\noindent Example:
1810\begin{code}
1811    buf = ImageBuf ("in.tif")
1812    buf.read ()   # force a read
1813    if buf.has_error :
1814        print "Error reading the file:", buf.geterror()
1815    buf.write ("out.jpg")
1816    if buf.has_error :
1817        print "Could not convert the file:", buf.geterror()
1818\end{code}
1819\apiend
1820
1821\apiitem{int ImageBuf.{\ce pixelindex} (x, y, z, check_range=False)}
1822Return the index of pixel (x,y,z).
1823\apiend
1824
1825\apiitem{bool ImageBuf.{\ce deep}}
1826Will be {\cf True} if the file contains ``deep'' pixel data, or {\cf False}
1827for an ordinary images.
1828\apiend
1829
1830\apiitem{int ImageBuf.{\ce deep_samples} (x, y, z=0)}
1831Return the number of deep samples for pixel (x,y,z).
1832\apiend
1833
1834\apiitem{ImageBuf.{\ce set_deep_samples} (x, y, z, nsamples)}
1835Set the number of deep samples for pixel (x,y,z).
1836\apiend
1837
1838\apiitem{ImageBuf.{\ce deep_insert_samples} (x, y, z, samplepos, nsamples) \\
1839int ImageBuf.{\ce deep_erase_samples} (x, y, z, samplepos, nsamples)}
1840Insert or erase \emph{nsamples} samples starting at the given position of
1841pixel {\cf (x,y,z)}.
1842\apiend
1843
1844\apiitem{float ImageBuf.{\ce deep_value} (x, y, z, channel, sample) \\
1845uint ImageBuf.{\ce deep_value_uint} (x, y, z, channel, sample)}
1846Return the value of the given deep sample (particular pixel, channel, and
1847sample number) for a channel that is a float or an unsigned integer type,
1848respectively.
1849\apiend
1850
1851\apiitem{ImageBuf.{\ce set_deep_value} (x, y, z, channel, sample, value) \\
1852ImageBuf.{\ce set_deep_value_uint} (x, y, z, channel, sample, value)}
1853Set the value of the given deep sample (particular pixel, channel, and
1854sample number) for a channel that is a float or an unsigned integer type,
1855respectively.
1856\apiend
1857
1858\apiitem{DeepData ImageBuf.{\ce deepdata}}
1859Returns a reference to the underlying {\cf DeepData} of the image.
1860\apiend
1861
1862
1863
1864
1865\newpage
1866\section{ImageBufAlgo}
1867\label{sec:pythonimagebufalgo}
1868
1869The C++ \IBA functions are described in detail in
1870Chapter~\ref{chap:imagebufalgo}.  They are also exposed to Python.
1871For the majority of \IBA functions, their use in Python is identical
1872to C++; in those cases, we will keep our descriptions of the Python
1873bindings minimal and refer you to Chapter~\ref{chap:imagebufalgo}, saving
1874the extended descriptions for those functions that differ from the C++
1875counterparts.
1876
1877A few things about the paramters of the \IBA function calls are identical
1878among the functions, so we will explain once here rather than separately for
1879each function:
1880
1881\begin{itemize}
1882\item {\cf dst} is an existing \ImageBuf, which will be modified (it may be
1883an uninitialized \ImageBuf, but it must be an \ImageBuf).
1884\item {\cf src} parameter is an initialized \ImageBuf, which will not be
1885modified (unless it happens to refer to the same image as {\cf dst}.
1886\item {\cf roi}, if supplied, is an {\cf ROI} specifying a region of interst
1887over which to operate. If omitted, the region will be the entire size of the
1888source image(s).
1889\item {\cf nthreads} is the maximum number of threads to use. If not
1890supplied, it defaults to 0, meaning to use as many threads as hardware cores
1891available.
1892\end{itemize}
1893
1894Just as with the C++ \IBA functions, if {\cf dst} is an uninitialized
1895\ImageBuf, it will be sized to reflect the {\cf roi} (which, in turn, if
1896undefined, will be sized to be the union of the ROI's of the source
1897images).
1898
1899\subsection{Pattern generation}
1900\label{sec:iba:py:patterns}
1901
1902\apiitem{ImageBuf ImageBufAlgo.{\ce zero} (roi, nthreads=0) \\
1903bool ImageBufAlgo.{\ce zero} (dst, roi=ROI.All, nthreads=0)}
1904\index{ImageBufAlgo!zero} \indexapi{zero}
1905
1906Zero out the destination buffer (or a specific region of it).
1907
1908\smallskip
1909\noindent Example:
1910\begin{code}
1911    # Initialize buf to a 640x480 3-channel FLOAT buffer of 0 values
1912    buf = ImageBufAlgo.zero (ROI(0, 640, 0, 480, 0, 1, 0, 3))
1913\end{code}
1914\apiend
1915
1916\apiitem{ImageBuf ImageBufAlgo.{\ce fill} (values, roi=ROI.All, nthreads=0) \\
1917ImageBuf ImageBufAlgo.{\ce fill} (top, bottom, roi=ROI.All, nthreads=0) \\
1918ImageBuf ImageBufAlgo.{\ce fill} (topleft, topright, \\
1919\bigspc bottomleft, bottomright, roi=ROI.All, nthreads=0) \\[0.5ex]
1920bool ImageBufAlgo.{\ce fill} (dst, values, roi=ROI.All, nthreads=0) \\
1921bool ImageBufAlgo.{\ce fill} (dst, top, bottom, roi=ROI.All, nthreads=0) \\
1922bool ImageBufAlgo.{\ce fill} (dst, topleft, topright, \\
1923\bigspc bottomleft, bottomright, roi=ROI.All, nthreads=0)}
1924\index{ImageBufAlgo!fill} \indexapi{fill}
1925
1926Return a filled float image of size ROI, or set the the pixels of image
1927{\cf dst} within the ROI to a color or gradient.
1928
1929Three fill optins are available: (a) if one color tuple is supplied, the
1930whole ROI will be filled with that constant value, (b) if two color tuples
1931are supplied, a linear gradient will be applied from top to bottom, (c) if
1932four color cuples are supplied, the ROI will be be filled with values
1933bilinearly interpolated from the four corner colors supplied.
1934
1935\smallskip
1936\noindent Examples:
1937\begin{code}
1938    # Draw a red rectangle into buf
1939    buf = ImageBuf (ImageSpec(640, 480, 3, TypeDesc.FLOAT)
1940    ImageBufAlgo.fill (buf, (1,0,0), ROI(50, 100, 75, 85))
1941\end{code}
1942\apiend
1943
1944
1945\apiitem{ImageBuf ImageBufAlgo.{\ce checker} (width, height, depth,
1946 color1, color2, \\ \bigspc xoffset=0, yoffset=0, zoffset=0,
1947 roi=ROI.All, nthreads=0) \\
1948 bool ImageBufAlgo.{\ce checker} (dst, width, height, depth,
1949 color1, color2, \\ \bigspc xoffset=0, yoffset=0, zoffset=0,
1950 roi=ROI.All, nthreads=0)}
1951\index{ImageBufAlgo!checker} \indexapi{checker}
1952
1953Return (or copy into {\cf dst}) a checkerboard pattern. The colors are specified as
1954tuples giving the values for each color channel.
1955
1956\smallskip
1957\noindent Examples:
1958\begin{code}
1959    buf = ImageBuf(ImageSpec(640, 480, 3, oiio.UINT8))
1960    ImageBufAlgo.checker (buf, 64, 64, 1, (0.1,0.1,0.1), (0.4,0.4,0.4))
1961\end{code}
1962\apiend
1963
1964
1965\apiitem{ImageBuf ImageBufAlgo.{\ce noise} (noisetype, A=0.0, B=0.1, \\
1966\bigspc\bigspc mono=False, seed=0, roi=ROI.All, nthreads=0)\\
1967bool ImageBufAlgo.{\ce noise} (dst, noisetype, A=0.0, B=0.1,\\
1968\bigspc\bigspc mono=False, seed=0, roi=ROI.All, nthreads=0)}
1969\index{ImageBufAlgo!noise} \indexapi{noise}
1970
1971Return an image of pseudorandom noise, or add pseudorandom noise
1972to the specified region of existing region {\cf dst}.
1973
1974For noise type \qkw{uniform}, the noise is uniformly distributed on the
1975range {\cf [A,B)}. For noise \qkw{gaussian}, the noise will have a normal
1976distribution with mean A and standard deviation B. For noise \qkw{salt}, the
1977value A will be stored in a random set of pixels whose proportion (of the
1978overall image) is B. For all noise types, choosing different {\cf seed}
1979values will result in a different pattern. If the {\cf mono} flag is {\cf
1980true}, a single noise value will be applied to all channels specified by
1981{\cf roi}, but if {\cf mono} is {\cf false}, a separate noise value will be
1982computed for each channel in the region.
1983
1984\smallskip
1985\noindent Examples:
1986\begin{code}
1987    buf = ImageBuf(ImageSpec(640, 480, 3, oiio.UINT8))
1988    ImageBufAlgo.zero (buf)
1989    ImageBufAlgo.noise (buf, 'uniform', 0.25, 0.75)
1990\end{code}
1991\apiend
1992
1993
1994
1995\apiitem{bool ImageBufAlgo.{\ce render_point} (dst, x, y, color=(1,1,1,1))}
1996\index{ImageBufAlgo!render_point} \indexapi{render_point}
1997
1998Render a point at pixel $(x,y)$ of {\cf dst}.  The {\cf color} (if supplied)
1999is a tuple giving the per-channel colors.
2000
2001\smallskip
2002\noindent Examples:
2003\begin{code}
2004    buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT))
2005    ImageBufAlgo.render_point (buf, 10, 20, (1,0,0,1))
2006\end{code}
2007\apiend
2008
2009
2010\apiitem{bool ImageBufAlgo.{\ce render_line} (dst, x1, y1, x2, y2, \\
2011\bigspc\bigspc color=(1,1,1,1), skip_first_point=False)}
2012\index{ImageBufAlgo!render_line} \indexapi{render_line}
2013
2014Render a line from pixel $(x_1,y_1)$ to $(x_2,y_2)$ into {\cf dst}.  The
2015{\cf color} (if supplied) is a tuple giving the per-channel colors.
2016
2017\smallskip
2018\noindent Examples:
2019\begin{code}
2020    buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT))
2021    ImageBufAlgo.render_line (buf, 10, 10, 500, 20, (1,0,0,1))
2022\end{code}
2023\apiend
2024
2025
2026\apiitem{bool ImageBufAlgo.{\ce render_box} (dst, x1, y1, x2, y2, \\
2027\bigspc\bigspc color=(1,1,1,1), filled=False)}
2028\index{ImageBufAlgo!render_box} \indexapi{render_box}
2029
2030Render a filled or unfilled box with corners at pixels $(x_1,y_1)$ and
2031$(x_2,y_2)$ into {\cf dst}.  The {\cf color} (if supplied) is a tuple giving
2032the per-channel colors.
2033
2034\smallskip
2035\noindent Examples:
2036\begin{code}
2037    buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT))
2038    ImageBufAlgo.render_box (buf, 150, 100, 240, 180, (0,1,1,1))
2039    ImageBufAlgo.render_box (buf, 100, 50, 180, 140, (0.5, 0.5, 0, 0.5), True)
2040\end{code}
2041\apiend
2042
2043
2044\apiitem{bool ImageBufAlgo.{\ce render_text} (dst, x, y, text, fontsize=16, \\
2045  \bigspc\bigspc  fontname="", textcolor=(1,1,1,1),\\
2046  \bigspc\bigspc  alignx="left", aligny="baseline", shadow=0,\\
2047  \bigspc\bigspc  roi=ROI.All, nthreads=0}
2048\index{ImageBufAlgo!render_text} \indexapi{render_text}
2049
2050Render antialiased text into {\cf dst}.  The {\cf textcolor} (if supplied)
2051is a tuple giving the per-channel colors. Choices for {\cf alignx} are
2052\qkw{left}, \qkw{right}, and \qkw{center}, and choices for {\cf aligny} are
2053\qkw{baseline}, \qkw{top}, \qkw{bottom}, and \qkw{center}.
2054
2055\smallskip
2056\noindent Examples:
2057\begin{code}
2058    buf = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT))
2059    ImageBufAlgo.render_text (buf, 50, 100, "Hello, world")
2060    ImageBufAlgo.render_text (buf, 100, 200, "Go Big Red!",
2061                              60, "Arial Bold", (1,0,0,1))
2062\end{code}
2063% \spc \includegraphics[width=2.5in]{figures/text.jpg}
2064\apiend
2065
2066
2067\apiitem{ROI ImageBufAlgo.{\ce text_size} (text, fontsize=16, fontname="")}
2068\index{ImageBufAlgo!text_size} \indexapi{text_size}
2069
2070Compute the size that will be needed for the text as an ROI and return it.
2071The size will not be {\cf defined} if an error occurred (such as not being a
2072valid font name).
2073
2074\smallskip
2075\noindent Examples:
2076\begin{code}
2077    A = ImageBuf(ImageSpec (640, 480, 4, oiio.FLOAT))
2078    Aroi = A.roi
2079    size = ImageBufAlgo.text_size ("Centered", 40, "Courier New")
2080    if size.defined :
2081        x = Aroi.xbegin + Aroi.width/2  - (size.xbegin + size.width/2)
2082        y = Aroi.ybegin + Aroi.height/2 - (size.ybegin + size.height/2)
2083        ImageBufAlgo.render_text (A, x, y, "Centered", 40, "Courier New")
2084
2085    # Note: this was for illustration. An easier way to do this is:
2086    #   render_text (A, x, y, "Centered", 40, "Courier New", alignx="center")
2087\end{code}
2088% \spc \includegraphics[width=2.5in]{figures/textcentered.jpg}
2089\apiend
2090
2091
2092
2093\subsection{Image transformations and data movement}
2094\label{sec:iba:py:transforms}
2095
2096\apiitem{ImageBuf ImageBufAlgo.{\ce channels} (src, channelorder, newchannelnames=(), \\
2097        \bigspc\bigspc shuffle_channel_names=False, nthreads=0) \\
2098bool ImageBufAlgo.{\ce channels} (dst, src, channelorder, newchannelnames=(), \\
2099        \bigspc\bigspc shuffle_channel_names=False, nthreads=0)}
2100\index{ImageBufAlgo!channels} \indexapi{channels}
2101
2102Return (or store in {\cf dst}) shuffled channels of {\cf src}, with channels in
2103the order specified by the tuple {\cf channelorder}.
2104The length of {\cf channelorder} specifies the number of channels to copy.
2105Each element in the tuple {\cf channelorder} may be one of the following:
2106\begin{itemize}
2107\item {}
2108\item {\cf int} : specifies the index (beginning at 0) of the channel
2109    to copy.
2110\item {\cf str} : specifies the name of the channel to copy.
2111\item {\cf float} : specifies a constant value to use for that channel.
2112\end{itemize}
2113
2114If {\cf newchannelnames} is supplied, it is a tuple of new channel
2115names. (See the C++ version for more full explanation.)
2116
2117\smallskip
2118\noindent Examples:
2119\begin{code}
2120    # Copy the first 3 channels of an RGBA, drop the alpha
2121    RGBA = ImageBuf("rgba.tif")
2122    RGB = ImageBufAlgo.channels (RGBA, (0,1,2))
2123
2124    # Copy just the alpha channel, making a 1-channel image
2125    Alpha = ImageBufAlgo.channels (RGBA, ("A",))
2126
2127    # Swap the R and B channels
2128    BGRA = ImageBufAlgo.channels (RGBA, (2, 1, 0, 3))
2129
2130    # Add an alpha channel with value 1.0 everywhere to an RGB image
2131    RGBA = ImageBufAlgo.channels (RGB, ("R", "G", "B", 1.0),
2132                                  ("R", "G", "B", "A"))
2133\end{code}
2134\apiend
2135
2136
2137\apiitem{ImageBuf ImageBufAlgo.{\ce channel_append} (A, B, roi=ROI.All, nthreads=0)\\
2138bool ImageBufAlgo.{\ce channel_append} (dst, A, B, roi=ROI.All, nthreads=0)}
2139\index{ImageBufAlgo!channel_append} \indexapi{channel_append}
2140Append the channels of images {\cf A} and {\cf B} together into one image.
2141
2142\smallskip
2143\noindent Examples:
2144\begin{code}
2145    RGBA = ImageBuf ("rgba.exr")
2146    Z = ImageBuf ("z.exr")
2147    RGBAZ = ImageBufAlgo.channel_append (RGBA, Z)
2148\end{code}
2149\apiend
2150
2151
2152\apiitem{ImageBuf ImageBufAlgo.{\ce copy} (src, convert=TypeDesc.UNKNOWN, \\
2153        \bigspc roi=ROI.All, nthreads=0)\\
2154bool ImageBufAlgo.{\ce copy} (dst, src, convert=TypeDesc.UNKNOWN, \\
2155        \bigspc roi=ROI.All, nthreads=0)}
2156\index{ImageBufAlgo!copy} \indexapi{copy}
2157Copy the specified region of pixels of {\cf src} at the same
2158locations, optionally with the pixel
2159type overridden by {\cf convert} (if it is not {\cf UNKNOWN}).
2160
2161\smallskip
2162\noindent Examples:
2163\begin{code}
2164    # Copy A's upper left 200x100 region into B
2165    B = ImageBufAlgo.copy (A, ROI(0,200,0,100))
2166\end{code}
2167\apiend
2168
2169
2170\apiitem{ImageBuf ImageBufAlgo.{\ce crop} (src, roi=ROI.All, nthreads=0)\\
2171bool ImageBufAlgo.{\ce crop} (dst, src, roi=ROI.All, nthreads=0)}
2172\index{ImageBufAlgo!crop} \indexapi{crop}
2173Reset {\cf dst} to be the specified region of {\cf src}.
2174
2175\smallskip
2176\noindent Examples:
2177\begin{code}
2178    # Set B to be the upper left 200x100 region of A
2179    A = ImageBuf ("a.tif")
2180    B = ImageBufAlgo.crop (A, ROI(0,200,0,100))
2181\end{code}
2182\apiend
2183
2184
2185\apiitem{ImageBuf ImageBufAlgo.{\ce cut} (src, roi=ROI.All, nthreads=0)\\
2186bool ImageBufAlgo.{\ce cut} (dst, src, roi=ROI.All, nthreads=0)}
2187\index{ImageBufAlgo!cut} \indexapi{cut}
2188Reset {\cf dst} to be the specified region of {\cf src}, but moved so
2189that the resulting new image has its pixel data at the image plane origin.
2190
2191\smallskip
2192\noindent Examples:
2193\begin{code}
2194    # Set B to be the lower left 200x100 region of A, moved to the origin
2195    A = ImageBuf ("a.tif")
2196    B = ImageBufAlgo.cut (A, ROI(0,200,380,480))
2197\end{code}
2198\apiend
2199
2200
2201\apiitem{bool ImageBufAlgo.{\ce paste} (dst, xbegin, ybegin, zbegin, chbegin, \\
2202  \bigspc\bigspc src, ROI srcroi=ROI.All, nthreads=0)}
2203\index{ImageBufAlgo!paste} \indexapi{paste}
2204Copy the specified region of {\cf src} into {\cf dst} beginning at
2205offset {\cf (xbegin, ybegin, zbegin)}.
2206
2207\smallskip
2208\noindent Examples:
2209\begin{code}
2210    # Paste small.exr on top of big.exr at offset (100,100)
2211    Big = ImageBuf ("big.exr")
2212    Small = ImageBuf ("small.exr")
2213    ImageBufAlgo.paste (Big, 100, 100, 0, 0, Small)
2214\end{code}
2215\apiend
2216
2217
2218\apiitem{ImageBuf ImageBufAlgo.{\ce rotate90} (src, roi=ROI.All, nthreads=0) \\
2219ImageBuf ImageBufAlgo.{\ce rotate180} (src, roi=ROI.All, nthreads=0) \\
2220ImageBuf ImageBufAlgo.{\ce rotate270} (src, roi=ROI.All, nthreads=0) \\[1.0ex]
2221bool ImageBufAlgo.{\ce rotate90} (dst, src, roi=ROI.All, nthreads=0) \\
2222bool ImageBufAlgo.{\ce rotate180} (dst, src, roi=ROI.All, nthreads=0) \\
2223bool ImageBufAlgo.{\ce rotate270} (dst, src, roi=ROI.All, nthreads=0)}
2224\index{ImageBufAlgo!roate90} \indexapi{roate90}
2225\index{ImageBufAlgo!rotate180} \indexapi{rotate180}
2226\index{ImageBufAlgo!rotate270} \indexapi{rotate270}
2227Copy while rotating the image by a multiple of 90 degrees.
2228
2229\smallskip
2230\noindent Examples:
2231\begin{code}
2232    A = ImageBuf ("tahoe.exr")
2233    B = ImageBufAlgo.rotate90 (A)
2234\end{code}
2235\apiend
2236
2237
2238
2239\apiitem{ImageBuf ImageBufAlgo.{\ce flip} (src, roi=ROI.All, nthreads=0) \\
2240ImageBuf ImageBufAlgo.{\ce flop} (src, roi=ROI.All, nthreads=0) \\
2241ImageBuf ImageBufAlgo.{\ce transpose} (src, roi=ROI.All, nthreads=0) \\[1.0ex]
2242bool ImageBufAlgo.{\ce flip} (dst, src, roi=ROI.All, nthreads=0) \\
2243bool ImageBufAlgo.{\ce flop} (dst, src, roi=ROI.All, nthreads=0) \\
2244bool ImageBufAlgo.{\ce transpose} (dst, src, roi=ROI.All, nthreads=0)}
2245\index{ImageBufAlgo!flip} \indexapi{flip}
2246\index{ImageBufAlgo!flop} \indexapi{flop}
2247\index{ImageBufAlgo!transpose} \indexapi{transpose}
2248Copy while reversing orientation vertically (flip) or horizontally (flop),
2249or diagonally (transpose).
2250
2251\smallskip
2252\noindent Examples:
2253\begin{code}
2254    A = ImageBuf ("tahoe.exr")
2255    B = ImageBufAlgo.flip (A)
2256\end{code}
2257\apiend
2258
2259
2260\apiitem{ImageBuf ImageBufAlgo.{\ce reorient} (src, nthreads=0) \\
2261bool ImageBufAlgo.{\ce reorient} (dst, src, nthreads=0)}
2262\index{ImageBufAlgo!reorient} \indexapi{reorient}
2263
2264Copy {\cf src}, applying whatever seties of rotations, flips,
2265or flops are necessary to transform the pixels into the configuration
2266suggested by the \qkw{Orientation} metadata of the image (and the
2267\qkw{Orientation} metadata is then set to 1, ordinary orientation).
2268
2269\smallskip
2270\noindent Examples:
2271\begin{code}
2272    A = ImageBuf ("tahoe.jpg")
2273    ImageBufAlgo.reorient (A, A)
2274\end{code}
2275\apiend
2276
2277
2278
2279\apiitem{ImageBuf ImageBufAlgo.{\ce circular_shift} (src, xshift, yshift, zshift=0, \\
2280        \bigspc  roi=ROI.All, nthreads=0)\\
2281bool ImageBufAlgo.{\ce circular_shift} (dst, src, xshift, yshift, zshift=0, \\
2282        \bigspc  roi=ROI.All, nthreads=0)}
2283\index{ImageBufAlgo!circular_shift} \indexapi{circular_shift}
2284
2285Copy while circularly shifting by the given amount.
2286
2287\smallskip
2288\noindent Examples:
2289\begin{code}
2290    A = ImageBuf ("tahoe.exr")
2291    B = ImageBufAlgo.circular_shift (A, 200, 100)
2292\end{code}
2293\apiend
2294
2295
2296\apiitem{ImageBuf ImageBufAlgo.{\ce rotate} (src, angle, filtername="", filtersize=0.0, \\
2297        \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) \\
2298ImageBuf ImageBufAlgo.{\ce rotate} (src, angle, \\
2299        \bigspc\bigspc center_x, center_y, filtername="", filtersize=0.0, \\
2300        \bigspc\bigspc  recompute_roi=False, roi=ROI.All, nthreads=0) \\[1.0ex]
2301bool ImageBufAlgo.{\ce rotate} (dst, src, angle, filtername="", filtersize=0.0, \\
2302        \bigspc\bigspc recompute_roi=False, roi=ROI.All, nthreads=0) \\
2303bool ImageBufAlgo.{\ce rotate} (dst, src, angle, \\
2304        \bigspc\bigspc center_x, center_y, filtername="", filtersize=0.0, \\
2305        \bigspc\bigspc  recompute_roi=False, roi=ROI.All, nthreads=0) }
2306\index{ImageBufAlgo!rotate} \indexapi{rotate}
2307
2308Copy arotated version of the
2309corresponding portion of {\cf src}.  The angle is in radians, with positive
2310values indicating clockwise rotation. If the filter and size are not
2311specified, an appropriate default will be chosen.
2312
2313\smallskip
2314\noindent Examples:
2315\begin{code}
2316    Src = ImageBuf ("tahoe.exr")
2317    Dst = ImageBufAlgo.rotate (Src, math.radians(45.0))
2318\end{code}
2319\apiend
2320
2321
2322\apiitem{ImageBuf ImageBufAlgo.{\ce warp} (src, M, filtername="", filtersize=0.0, \\
2323        \bigspc\bigspc wrap="default", recompute_roi=False, \\
2324        \bigspc\bigspc roi=ROI.All, nthreads=0)\\
2325bool ImageBufAlgo.{\ce warp} (dst, src, M, filtername="", filtersize=0.0, \\
2326        \bigspc\bigspc wrap="default", recompute_roi=False, \\
2327        \bigspc\bigspc roi=ROI.All, nthreads=0)}
2328\index{ImageBufAlgo!warp} \indexapi{warp}
2329
2330Compute a warped (transformed) copy of {\cf src},
2331with the warp specified by {\cf M} consisting of 9 floating-point numbers
2332representing a $3 \times 3$ transformation matrix.  If the filter and size
2333are not specified, an appropriate default will be chosen.
2334
2335\smallskip
2336\noindent Examples:
2337\begin{code}
2338    M = (0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 20, -8.284271, 1)
2339    Src = ImageBuf ("tahoe.exr")
2340    Dst = ImageBufAlgo.warp (Src, M)
2341\end{code}
2342\apiend
2343
2344
2345\apiitem{ImageBuf ImageBufAlgo.{\ce resize} (src, filtername="", filtersize=0.0, \\
2346        \bigspc\bigspc  roi=ROI.All, nthreads=0) \\
2347bool ImageBufAlgo.{\ce resize} (dst, src, filtername="", filtersize=0.0, \\
2348        \bigspc\bigspc  roi=ROI.All, nthreads=0)}
2349\index{ImageBufAlgo!resize} \indexapi{resize}
2350Compute a high-quality resized version of the
2351corresponding portion of {\cf src}.  If the filter and size are not
2352specified, an appropriate default will be chosen.
2353
2354\smallskip
2355\noindent Examples:
2356\begin{code}
2357    # Resize the image to 640x480, using the default filter
2358    Src = ImageBuf ("tahoe.exr")
2359    Dst = ImageBufAlgo.resize (Src, roi=ROI(0,640,0,480,0,1,0,3))
2360\end{code}
2361\apiend
2362
2363
2364\apiitem{ImageBuf ImageBufAlgo.{\ce resample} (src, interpolate=True, \\
2365        \bigspc\bigspc roi=ROI.All, nthreads=0)\\
2366bool ImageBufAlgo.{\ce resample} (dst, src, interpolate=True, \\
2367        \bigspc\bigspc roi=ROI.All, nthreads=0)}
2368\index{ImageBufAlgo!resample} \indexapi{resample}
2369Set {\cf dst}, over the ROI, to be a low-quality (but fast) resized version
2370of the corresponding portion of {\cf src}, either using a simple ``closest
2371pixel'' choice or by bilinaerly interpolating (depending on {\cf
2372interpolate}).
2373
2374\smallskip
2375\noindent Examples:
2376\begin{code}
2377    # Resample quickly to 320x240 to make a low-quality thumbnail
2378    Src = ImageBuf ("tahoe.exr")
2379    Dst = ImageBufAlgo.resample (Src, roi=ROI(0,640,0,480,0,1,0,3))
2380\end{code}
2381\apiend
2382
2383
2384\apiitem{ImageBuf ImageBufAlgo.{\ce fit} (src, filtername="", filtersize=0.0, \\
2385        \bigspc\bigspc  exact=false, roi=ROI.All, nthreads=0) \\
2386bool ImageBufAlgo.{\ce fit} (dst, src, filtername="", filtersize=0.0, \\
2387        \bigspc\bigspc  exact=false, roi=ROI.All, nthreads=0)}
2388\index{ImageBufAlgo!fit} \indexapi{fit}
2389Fit {\cf src} into the {\cf roi} while preserving the
2390original aspect ratio, without stretching.  If the filter and size are not
2391specified, an appropriate default will be chosen.
2392
2393\smallskip
2394\noindent Examples:
2395\begin{code}
2396    # Resize to fit into a max of 640x480, preserving the aspect ratio
2397    Src = ImageBuf ("tahoe.exr")
2398    Dst = ImageBufAlgo.fit (Src, roi=ROI(0,640,0,480,0,1,0,3))
2399\end{code}
2400\apiend
2401
2402
2403
2404\subsection{Image arithmetic}
2405\label{sec:iba:py:arith}
2406
2407\apiitem{ImageBuf ImageBufAlgo.{\ce add} (A, B, roi=ROI.All, nthreads=0)\\
2408bool ImageBufAlgo.{\ce add} (dst, A, B, roi=ROI.All, nthreads=0)}
2409\index{ImageBufAlgo!add} \indexapi{add}
2410
2411Compute {\cf A + B}.  {\cf A} and {\cf B} each may
2412be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a
2413{\cf float} for each color channel.
2414
2415\smallskip
2416\noindent Examples:
2417\begin{code}
2418    # Add two images
2419    buf = ImageBufAlgo.add (ImageBuf("a.exr"), ImageBuf("b.exr"))
2420
2421    # Add 0.2 to channels 0-2
2422    ImageBufAlgo.add (buf, buf, (0.2,0.2,0.2,0))
2423\end{code}
2424\apiend
2425
2426
2427\apiitem{ImageBuf ImageBufAlgo.{\ce sub} (A, B, roi=ROI.All, nthreads=0)\\
2428bool ImageBufAlgo.{\ce sub} (dst, A, B, roi=ROI.All, nthreads=0)}
2429\index{ImageBufAlgo!sub} \indexapi{sub}
2430
2431Compute {\cf A - B}.  {\cf A} and {\cf B} each may
2432be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a
2433{\cf float} for each color channel.
2434
2435\smallskip
2436\noindent Examples:
2437\begin{code}
2438    buf = ImageBufAlgo.sub (ImageBuf("a.exr"), ImageBuf("b.exr"))
2439\end{code}
2440\apiend
2441
2442
2443\apiitem{ImageBuf ImageBufAlgo.{\ce absdiff} (A, B, roi=ROI.All, nthreads=0)\\
2444bool ImageBufAlgo.{\ce absdiff} (dst, A, B, roi=ROI.All, nthreads=0)}
2445\index{ImageBufAlgo!absdiff} \indexapi{absdiff}
2446
2447Compute {\cf abs(A - B)}.  {\cf A} and {\cf B} each may
2448be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a
2449{\cf float} for each color channel.
2450
2451\smallskip
2452\noindent Examples:
2453\begin{code}
2454    buf = ImageBufAlgo.absdiff (ImageBuf("a.exr"), ImageBuf("b.exr"))
2455\end{code}
2456\apiend
2457
2458
2459\apiitem{ImageBuf ImageBufAlgo.{\ce abs} (A, roi=ROI.All, nthreads=0)\\
2460bool ImageBufAlgo.{\ce abs} (dst, A, roi=ROI.All, nthreads=0)}
2461\index{ImageBufAlgo!abs} \indexapi{abs}
2462
2463Compute {\cf abs(A)}.  {\cf A} is an \ImageBuf.
2464
2465\smallskip
2466\noindent Examples:
2467\begin{code}
2468    buf = ImageBufAlgo.abs (ImageBuf("a.exr"))
2469\end{code}
2470\apiend
2471
2472
2473\apiitem{ImageBuf ImageBufAlgo.{\ce mul} (A, B, roi=ROI.All, nthreads=0)\\
2474bool ImageBufAlgo.{\ce mul} (dst, A, B, roi=ROI.All, nthreads=0)}
2475\index{ImageBufAlgo!mul} \indexapi{mul}
2476
2477Compute {\cf A * B} (channel-by-channel multiplication). {\cf A} and {\cf B}
2478each may be an \ImageBuf, a {\cf float} value (for all channels) or a tuple
2479giving a {\cf float} for each color channel.
2480
2481\smallskip
2482\noindent Examples:
2483\begin{code}
2484    # Multiply the two images
2485    buf = ImageBufAlgo.mul (ImageBuf("a.exr"), ImageBuf("b.exr"))
2486
2487    # Reduce intensity of buf's channels 0-2 by 50%, in place
2488    ImageBufAlgo.mul (buf, buf, (0.5, 0.5, 0.5, 1.0))
2489\end{code}
2490\apiend
2491
2492
2493\apiitem{ImageBuf ImageBufAlgo.{\ce div} (A, B, roi=ROI.All, nthreads=0)\\
2494bool ImageBufAlgo.{\ce div} (dst, A, B, roi=ROI.All, nthreads=0)}
2495\index{ImageBufAlgo!div} \indexapi{div}
2496
2497Compute {\cf A / B} (channel-by-channel division), where $x/0$
2498is defined to be $0$.  {\cf A} and {\cf B} each may
2499be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a
2500{\cf float} for each color channel.
2501
2502\smallskip
2503\noindent Examples:
2504\begin{code}
2505    # Divide a.exr by b.exr
2506    buf = ImageBufAlgo.div (ImageBuf("a.exr"), ImageBuf("b.exr"))
2507
2508    # Reduce intensity of buf's channels 0-2 by 50%, in place
2509    ImageBufAlgo.div (buf, buf, (2.0, 2.0, 2.0, 1.0))
2510\end{code}
2511\apiend
2512
2513
2514\apiitem{ImageBuf ImageBufAlgo.{\ce mad} (A, B, C, roi=ROI.All, nthreads=0)\\
2515bool ImageBufAlgo.{\ce mad} (dst, A, B, C, roi=ROI.All, nthreads=0)}
2516\index{ImageBufAlgo!mad} \indexapi{mad}
2517
2518Compute {\cf A * B + C} (channel-by-channel multiplication
2519and addition).  {\cf A}, {\cf B}, and {\cf C} each may
2520be an \ImageBuf, a {\cf float} value (for all channels) or a tuple giving a
2521{\cf float} for each color channel.
2522
2523\smallskip
2524\noindent Examples:
2525\begin{code}
2526    # Multiply a and b, then add c
2527    buf = ImageBufAlgo.mad (ImageBuf("a.exr"),
2528                            (1.0f, 0.5f, 0.25f), ImageBuf("c.exr"))
2529\end{code}
2530\apiend
2531
2532
2533
2534\apiitem{ImageBuf ImageBufAlgo.{\ce invert} (A, roi=ROI.All, nthreads=0)\\
2535bool ImageBufAlgo.{\ce invert} (dst, A, roi=ROI.All, nthreads=0)}
2536\index{ImageBufAlgo!invert} \indexapi{invert}
2537
2538Compute {\cf 1-A} (channel by channel color inverse).
2539{\cf A} is an \ImageBuf.
2540
2541\smallskip
2542\noindent Examples:
2543\begin{code}
2544    buf = ImageBufAlgo.invert (ImageBuf("a.exr"))
2545\end{code}
2546\apiend
2547
2548
2549\apiitem{ImageBuf ImageBufAlgo.{\ce pow} (A, B, roi=ROI.All, nthreads=0)\\
2550bool ImageBufAlgo.{\ce pow} (dst, A, B, roi=ROI.All, nthreads=0)}
2551\index{ImageBufAlgo!pow} \indexapi{pow}
2552
2553Compute {\cf pow (A, B} (channel-by-channel exponentiation).
2554{\cf A} is an \ImageBuf, and {\cf B} may be a {\cf float} (a single power
2555for all channels) or a tuple giving a {\cf float} for each color channel.
2556
2557\smallskip
2558\noindent Examples:
2559\begin{code}
2560    # Linearize a 2.2 gamma-corrected image (channels 0-2 only)
2561    img = ImageBuf ("a.exr")
2562    buf = ImageBufAlgo.pow (img, (2.2, 2.2, 2.2, 1.0))
2563\end{code}
2564\apiend
2565
2566
2567\apiitem{ImageBuf ImageBufAlgo.{\ce channel_sum} (src, weights=(), roi=ROI.All, nthreads=0)\\
2568bool ImageBufAlgo.{\ce channel_sum} (dst, src, weights=(), roi=ROI.All, nthreads=0)}
2569\index{ImageBufAlgo!channel_sum} \indexapi{channel_sum}
2570Converts a multi-channel image into a 1-channel image via a weighted sum
2571of channels. The {\cf weights} is a tuple providing the weight for each
2572channel (if not supplied, all channels will have weight 1.0).
2573
2574\smallskip
2575\noindent Examples:
2576\begin{code}
2577    # Compute luminance via a weighted sum of R,G,B
2578    # (assuming Rec709 primaries and a linear scale)
2579    ImageBuf()
2580    weights = (.2126, .7152, .0722)
2581    luma = ImageBufAlgo.channel_sum (ImageBuf("a.exr"), weights)
2582\end{code}
2583\apiend
2584
2585
2586\apiitem{ImageBuf ImageBufAlgo.{\ce contrast_remap} (src, \\
2587        \bigspc\spc black=0.0, white=1.0, min=0.0, max=1.0, \\
2588        \bigspc\spc sthresh=0.0, scontrast=1.0, \\
2589        \bigspc\spc ROI roi=\{\}, int nthreads=0) \\
2590bool ImageBufAlgo.{\ce contrast_remap} (ImageBuf \&dst, src,\\
2591        \bigspc\spc black=0.0, white=1.0, min=0.0, max=1.0, \\
2592        \bigspc\spc sthresh=0.0, scontrast=1.0, \\
2593        \bigspc\spc ROI roi=\{\}, int nthreads=0)}
2594\index{ImageBufAlgo!contrast_remap} \indexapi{contrast_remap}
2595
2596Return (or copy into {\cf dst}) pixel values that are a contrast-remap
2597of the corresponding values of the {\cf src} image, transforming pixel
2598value domain [black, white] to range [min, max], either linearly or with
2599optional application of a smooth sigmoidal remapping (if scontrast != 1.0).
2600
2601\smallskip
2602\noindent Examples:
2603\begin{code}
2604    A = ImageBuf('tahoe.tif');
2605
2606    # Simple linear remap that stretches input 0.1 to black, and input
2607    # 0.75 to white.
2608    linstretch = ImageBufAlgo.contrast_remap (A, black=0.1, white=0.75)
2609
2610    // Remapping 0->1 and 1->0 inverts the colors of the image,
2611    // equivalent to ImageBufAlgo.invert().
2612    inverse = ImageBufAlgo.contrast_remap (A, black=1.0, white=0.0)
2613
2614    // Use a sigmoid curve to add contrast but without any hard cutoffs.
2615    // Use a contrast parameter of 5.0.
2616    sigmoid = ImageBufAlgo.contrast_remap (a, contrast=5.0)
2617\end{code}
2618\apiend
2619
2620\apiitem{ImageBuf ImageBufAlgo.{\ce color_map} (src, srcchannel, \\
2621\bigspc\bigspc        nknots, channels, knots, roi=ROI.All, nthreads=0) \\
2622ImageBuf ImageBufAlgo.{\ce color_map} (src, srcchannel, \\
2623\bigspc\bigspc        mapname, roi=ROI.All, nthreads=0) \\[1.0ex]
2624bool ImageBufAlgo.{\ce color_map} (dst, src, srcchannel, \\
2625\bigspc\bigspc        nknots, channels, knots, roi=ROI.All, nthreads=0) \\
2626bool ImageBufAlgo.{\ce color_map} (dst, src, srcchannel, \\
2627\bigspc\bigspc        mapname, roi=ROI.All, nthreads=0)}
2628\index{ImageBufAlgo!color_map} \indexapi{color_map}
2629Return an image (or copy into {\cf dst}) pixel values determined by applying
2630the color map to the values of {\cf src}, using either the channel specified
2631by {\cf srcchannel}, or the luminance of {\cf src}'s RGB if {\cf srcchannel}
2632is -1.
2633
2634In the first variant, the values linearly-interpolated color map are
2635given by the tuple {\cf knots[nknots*channels]}.
2636
2637In the second variant, just the name of a color map is specified. Recognized
2638map names include: \qkw{inferno}, \qkw{viridis},\qkw{magma}, \qkw{plasma},
2639all of which are perceptually uniform, strictly increasing in luminance,
2640look good when converted to grayscale, and work for people with all types of
2641colorblindness. Also supported are the following color maps that do not have
2642those desirable qualities (and are this not recommended): \qkw{blue-red},
2643\qkw{spectrum}, and \qkw{heat}. In all cases, the implied {\cf channels} is
26443.
2645
2646\smallskip
2647\noindent Examples:
2648\begin{code}
2649    heatmap = ImageBufAlgo.color_map (ImageBuf("a.jpg"), -1, "inferno")
2650
2651    heatmap = ImageBufAlgo.color_map (ImageBuf("a.jpg"), -1, 3, 3,
2652                            (0.25, 0.25, 0.25,  0, 0.5, 0,  1, 0, 0))
2653\end{code}
2654\apiend
2655
2656
2657\apiitem{ImageBuf ImageBufAlgo.{\ce clamp} (src, min, max,
2658  bool clampalpha01=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)\\
2659bool ImageBufAlgo.{\ce clamp} (dst, src, min, max,
2660  bool clampalpha01=False, \\ \bigspc\bigspc roi=ROI.All, nthreads=0)}
2661\index{ImageBufAlgo!clamp} \indexapi{clamp}
2662
2663Copy pixels while clamping
2664between the {\cf min} and {\cf max} values.  The {\cf min} and {\cf max}
2665may either be tuples (one min and max value per channel), or single
2666{\cf floats} (same value for all channels).  Additionally, if
2667{\cf clampalpha01} is {\cf True}, then any alpha
2668channel is clamped to the 0--1 range.
2669
2670\smallskip
2671\noindent Examples:
2672\begin{code}
2673    # Clamp image buffer A in-place to the [0,1] range for all channels.
2674    ImageBufAlgo.clamp (A, A, 0.0, 1.0)
2675\end{code}
2676\apiend
2677
2678
2679\apiitem{ImageBuf ImageBufAlgo.{\ce rangecompress} (src, useluma=False, \\
2680   \bigspc\bigspc     roi=ROI.All, nthreads=0) \\
2681bool ImageBufAlgo.{\ce rangecompress} (dst, src, useluma=False, \\
2682   \bigspc\bigspc     roi=ROI.All, nthreads=0) \\[1.0ex]
2683ImageBuf ImageBufAlgo.{\ce rangeexpand} (src, useluma=False, \\
2684    \bigspc\bigspc    roi=ROI.All, nthreads=0)\\
2685bool ImageBufAlgo.{\ce rangeexpand} (dst, src, useluma=False, \\
2686    \bigspc\bigspc    roi=ROI.All, nthreads=0)}
2687\index{ImageBufAlgo!rangecompress} \indexapi{rangecompress}
2688\index{ImageBufAlgo!rangeexpand} \indexapi{rangeexpand}
2689
2690Copy from {\cf src}, compressing (logarithmically) or expanding
2691(by the inverse of the compressive transformation) the range of pixel
2692values.  Alpha and z channels are copied but not transformed.
2693
2694If {\cf useluma} is {\cf True}, the luma of the first three channels (presumed
2695to be R, G, and B) are used to compute a single scale factor for all
2696color channels, rather than scaling all channels individually (which
2697could result in a big color shift when performing {\cf rangecompress}
2698and {\cf rangeexpand}).
2699
2700\smallskip
2701\noindent Examples:
2702\begin{code}
2703    # Resize the image to 640x480, using a Lanczos3 filter, which
2704    # has negative lobes. To prevent those negative lobes from
2705    # producing ringing or negative pixel values for HDR data,
2706    # do range compression, then resize, then re-expand the range.
2707
2708    # 1. Read the original image
2709    Src = ImageBuf ("tahoeHDR.exr")
2710
2711    # 2. Range compress to a logarithmic scale
2712    Compressed = ImageBufAlgo.rangecompress (Src)
2713
2714    # 3. Now do the resize
2715    roi = ROI (0, 640, 0, 480, 0, 1, 0, Compressed.nchannels)
2716    Dst = ImageBufAlgo.resize (Compressed, "lanczos3", 6.0, roi)
2717
2718    # 4. Expand range to be linear again (operate in-place)
2719    ImageBufAlgo.rangeexpand (Dst, Dst)
2720\end{code}
2721\apiend
2722
2723
2724\apiitem{ImageBuf ImageBufAlgo.{\ce over} (A, B, roi=ROI.All, nthreads=0)\\
2725bool ImageBufAlgo.{\ce over} (dst, A, B, roi=ROI.All, nthreads=0)}
2726\index{ImageBufAlgo!over} \indexapi{over}
2727
2728Composite \ImageBuf\ {\cf A} \emph{over} \ImageBuf\ {\cf B}.
2729
2730\smallskip
2731\noindent Examples:
2732\begin{code}
2733    Comp = ImageBufAlgo.over (ImageBuf("fg.exr"), ImageBuf("bg.exr"))
2734\end{code}
2735\apiend
2736
2737
2738\apiitem{ImageBuf ImageBufAlgo.{\ce zover} (A, B, bool z_zeroisinf=False,\\
2739        \bigspc\bigspc roi=ROI.All, nthreads=0\\
2740bool ImageBufAlgo.{\ce zover} (dst, A, B, bool z_zeroisinf=False,\\
2741        \bigspc\bigspc roi=ROI.All, nthreads=0)}
2742\index{ImageBufAlgo!zover} \indexapi{zover}
2743
2744Composite \ImageBuf\ {\cf A} and \ImageBuf\ {\cf B} using their respective
2745$Z$ channels to decide which is in front on a pixel-by-pixel basis.
2746
2747\smallskip
2748\noindent Examples:
2749\begin{code}
2750    Comp = ImageBufAlgo.zover (ImageBuf("fg.exr"), ImageBuf("bg.exr"))
2751\end{code}
2752\apiend
2753
2754
2755
2756\subsection{Image comparison and statistics}
2757\label{sec:iba:py:stats}
2758
2759
2760\apiitem{PixelStats ImageBufAlgo.{\ce computePixelStats} (src, roi=ROI.All, nthreads=0)}
2761\index{ImageBufAlgo!computePixelStats} \indexapi{computePixelStats}
2762
2763Compute statistics about the ROI of the image {\cf src}.
2764The {\cf PixelStats} structure is defined as contining the following
2765data fields: {\cf min}, {\cf max}, {\cf avg}, {\cf stddev},
2766{\cf nancount}, {\cf infcount}, {\cf finitecount}, {\cf sum}, {\cf sum2},
2767each of which is a \emph{tuple} with one value for each channel of the image.
2768
2769\smallskip
2770\noindent Examples:
2771\begin{code}
2772    A = ImageBuf("a.exr")
2773    stats = ImageBufAlgo.computePixelStats (A)
2774    print "   min = ", stats.min
2775    print "   max = ", stats.max
2776    print "   average = ", stats.avg
2777    print "   standard deviation  = ", stats.stddev
2778    print "   # NaN values    = ", stats.nancount
2779    print "   # Inf values    = ", stats.infcount
2780    print "   # finite values = ", stats.finitecount
2781\end{code}
2782\apiend
2783
2784
2785\apiitem{CompareResults ImageBufAlgo.{\ce compare} (A, B, failthresh, warnthresh,
2786   \\ \bigspc\bigspc roi=ROI.All, nthreads=0)}
2787\index{ImageBufAlgo!compare} \indexapi{compare}
2788
2789Numerically compare two \ImageBuf's, {\cf A} and {\cf B}. The {\cf failthresh}
2790and {\cf warnthresh} supply failure and warning difference thresholds.
2791The return value is a {\cf CompareResults} object,
2792which is defined as a class having the following members:
2793\begin{code}
2794    meanerror, rms_error, PSNR, maxerror  # error statistics
2795    maxx, maxy, maxz, maxc                # pixel of biggest difference
2796    nwarn, nfail                          # number of warnings and failures
2797    error                                 # True if there was an error
2798\end{code}
2799
2800\smallskip
2801\noindent Examples:
2802\begin{code}
2803    A = ImageBuf ("a.exr")
2804    B = ImageBuf ("b.exr")
2805    comp = ImageBufAlgo.compare (A, B, 1.0/255.0, 0.0)
2806    if comp.nwarn == 0 and comp.nfail == 0 :
2807        print "Images match within tolerance"
2808    else :
2809        print comp.nfail, "failures,", comp.nwarn, " warnings."
2810        print "Average error was " , comp.meanerror
2811        print "RMS error was" , comp.rms_error
2812        print "PSNR was" , comp.PSNR
2813        print "largest error was ", comp.maxerror
2814        print "  on pixel", (comp.maxx, comp.maxy, comp.maxz)
2815        print "  channel", comp.maxc
2816\end{code}
2817\apiend
2818
2819
2820\apiitem{tuple ImageBufAlgo.{\ce isConstantColor} (src, threshold=0.0, roi=ROI.All, nthreads=0)}
2821\index{ImageBufAlgo!isConstantColor} \indexapi{isConstantColor}
2822
2823If all pixels of {\cf src} within the ROI have the same values (for the
2824subset of channels described by {\cf roi}), return a tuple giving that
2825color (one {\cf float} for each channel), otherwise return {\cf None}.
2826
2827\smallskip
2828\noindent Examples:
2829\begin{code}
2830    A = ImageBuf ("a.exr")
2831    color = ImageBufAlgo.isConstantColor (A)
2832    if color != None :
2833        print "The image has the same value in all pixels:", color
2834    else :
2835        print "The image is not a solid color."
2836\end{code}
2837\apiend
2838
2839
2840\apiitem{bool ImageBufAlgo.{\ce isConstantChannel} (src, channel, val, \\
2841 \bigspc\bigspc         threshold=0.0, roi=ROI.All, nthreads=0)}
2842\index{ImageBufAlgo!isConstantChannel} \indexapi{isConstantChannel}
2843
2844Returns {\cf True} if all pixels of {\cf src} within the ROI have the
2845given {\cf channel} value {\cf val}.
2846
2847\smallskip
2848\noindent Examples:
2849\begin{code}
2850    A = ImageBuf ("a.exr")
2851    alpha = A.spec.alpha_channel
2852    if alpha < 0 :
2853        print "The image does not have an alpha channel"
2854    elif ImageBufAlgo.isConstantChannel (A, alpha, 1.0) :
2855        print "The image has alpha = 1.0 everywhere"
2856    else :
2857        print "The image has alpha < 1 in at least one pixel"
2858\end{code}
2859\apiend
2860
2861
2862\apiitem{bool ImageBufAlgo.{\ce isMonochrome} (src, threshold=0.0,
2863          roi=ROI.All, nthreads=0)}
2864\index{ImageBufAlgo!isMonochrome} \indexapi{isMonochrome}
2865
2866Returns {\cf True} if the image is monochrome within the ROI.
2867
2868\smallskip
2869\noindent Examples:
2870\begin{code}
2871    A = ImageBuf ("a.exr")
2872    roi = A.roi
2873    roi.chend = min (3, roi.chend)  # only test RGB, not alpha
2874    if ImageBufAlgo.isMonochrome (A, roi) :
2875        print "a.exr is really grayscale"
2876\end{code}
2877\apiend
2878
2879
2880\begin{comment}
2881\apiitem{bool ImageBufAlgo.{\ce color_count} (src, imagesize_t *count,\\
2882        \bigspc  int ncolors, const float *color, const float *eps=NULL,  \\
2883        \bigspc  roi=ROI.All, nthreads=0)}
2884\index{ImageBufAlgo!color_count} \indexapi{color_count}
2885
2886Count how many pixels in the image (within the ROI) match a list of colors.
2887The colors to match are in:
2888
2889\begin{code}
2890  colors[0 ... nchans-1]
2891  colors[nchans ... 2*nchans-1]
2892  ...
2893  colors[(ncolors-1)*nchans ... (ncolors*nchans)-1]
2894\end{code}
2895
2896\noindent and so on, a total of {\cf ncolors} consecutively stored
2897colors of {\cf nchans} channels each ({\cf nchans} is the number of
2898channels in the image, itself, it is not passed as a parameter).
2899
2900
2901The values in {\cf eps[0..nchans-1]} are the error tolerances for a
2902match, for each channel.  Setting {\cf eps[c]} to
2903{\cf numeric_limits<float>::max()} will effectively make it ignore the
2904channel.  Passing {\cf eps == NULL} will be interpreted as a tolerance
2905of 0.001 for all channels (requires exact matches for 8 bit images, but
2906allows a wee bit of imprecision for {\cf float} images.
2907
2908\smallskip
2909\noindent Examples:
2910\begin{code}
2911    A = ImageBuf ("a.exr")
2912    n = A.nchannels
2913
2914    # Try to match two colors: pure red and green
2915    std::vector<float> colors (2*n, numeric_limits<float>::max());
2916    colors[0] = 1.0; colors[1] = 0.0; colors[2] = 0.0;
2917    colors[n+0] = 0.0; colors[n+1] = 1.0; colors[n+2] = 0.0;
2918
2919    const int ncolors = 2;
2920    imagesize_t count[ncolors];
2921    ImageBufAlgo.color_count (A, count, ncolors);
2922    print "Number of red pixels   : ", count[0]
2923    print "Number of green pixels : ", count[1]
2924\end{code}
2925\apiend
2926
2927
2928\apiitem{bool {\ce color_range_check} (src,
2929   imagesize_t *lowcount, \\ \bigspc imagesize_t *highcount, imagesize_t
2930  *inrangecount, \\
2931  \bigspc const float *low, const float *high, \\
2932        \bigspc  roi=ROI.All, nthreads=0)}
2933\index{ImageBufAlgo!color_range_check} \indexapi{color_range_check}
2934
2935Count how many pixels in the image (within the ROI) are outside the
2936value range described by {\cf low[roi.chbegin..roi.chend-1]} and
2937{\cf high[roi.chbegin..roi.chend-1]}
2938as the low and high acceptable values for each color channel.
2939
2940The number of pixels containing values that fall below the lower bound
2941will be stored in {\cf *lowcount}, the number of pixels containing
2942values that fall above the upper bound will be stored in
2943{\cf *highcount}, and the number of pixels for which all channels fell
2944within the bounds will be stored in {\cf *inrangecount}.  Any of these
2945may be NULL, which simply means that the counts need not be collected or
2946stored.
2947
2948\smallskip
2949\noindent Examples:
2950\begin{code}
2951    A = ImageBuf ("a.exr")
2952    ROI roi = get_roi (A.spec())
2953    roi.chend = std::min (roi.chend, 4);  # only compare RGBA
2954
2955    float low[] = {0, 0, 0, 0};
2956    float high[] = {1, 1, 1, 1};
2957
2958    imagesize_t lowcount, highcount, inrangecount;
2959    ImageBufAlgo.color_range_check (A, &lowcount, &highcount, &inrangecount,
2960                                     low, high, roi);
2961    print lowcount, " pixels had components < 0"
2962    print highcount, " pixels had components > 1"
2963    print inrangecount, " pixels were fully within [0,1] range"
2964\end{code}
2965\apiend
2966\end{comment}
2967
2968
2969\apiitem{std::string ImageBufAlgo.{\ce computePixelHashSHA1} (src,
2970  extrainfo = "", \\
2971  \bigspc\bigspc  roi=ROI.All, blocksize=0, nthreads=0)}
2972\index{ImageBufAlgo!computePixelHashSHA1} \indexapi{computePixelHashSHA1}
2973
2974Compute the SHA-1 byte hash for all the pixels in the ROI of {\cf src}.
2975
2976\smallskip
2977\noindent Examples:
2978\begin{code}
2979    A = ImageBuf ("a.exr")
2980    hash = ImageBufAlgo.computePixelHashSHA1 (A, blocksize=64)
2981\end{code}
2982\apiend
2983
2984
2985\apiitem{tuple {\ce histogram} (src, channel=0, bins=256, min=0.0, max=1.0, \\
2986\bigspc ignore_empty=False, roi=ROI.All, nthreads=0)}
2987\index{ImageBufAlgo!histogram} \indexapi{histogram}
2988\apiend
2989
2990Computes a histogram of the given {\cf channel} of image {\cf src}, within
2991the ROI, returning a tuple of length {\cf bins} containing count of pixels
2992whose value was in each of the equally-sized range bins between {\cf min}
2993and {\cf max}. If {\cf ignore_empty} is {\cf True}, pixels that are empty
2994(all channels 0 including alpha) will not be counted in the total.
2995
2996
2997
2998\subsection{Convolutions}
2999\label{sec:iba:py:convolutions}
3000
3001\apiitem{ImageBuf ImageBufAlgo.{\ce make_kernel} (name, width, height, \\
3002  \bigspc\bigspc depth=1.0, normalize=True)}
3003\index{ImageBufAlgo!make_kernel} \indexapi{make_kernel}
3004Create a 1-channel {\cf float} image of the named kernel
3005and dimensions.  If {\cf normalize} is {\cf True}, the values will be
3006normalized so that they sum to $1.0$.
3007
3008If {\cf depth} $> 1$, a volumetric kernel will be created.  Use with
3009caution!
3010
3011Kernel names can be: \qkw{gaussian}, \qkw{sharp-gaussian}, \qkw{box},
3012\qkw{triangle}, \qkw{mitchell}, \qkw{blackman-harris}, \qkw{b-spline},
3013\qkw{catmull-rom}, \qkw{lanczos3}, \qkw{cubic}, \qkw{keys}, \qkw{simon},
3014\qkw{rifman}, \qkw{disk}, \qkw{binomial}, \qkw{laplacian}. Note that
3015\qkw{catmull-rom} and \qkw{lanczos3} are fixed-size kernels that don't
3016scale with the width, and are therefore probably less useful in most
3017cases.
3018
3019\smallskip
3020\noindent Examples:
3021\begin{code}
3022    K = ImageBufAlgo.make_kernel ("gaussian", 5.0, 5.0)
3023\end{code}
3024\apiend
3025
3026
3027\apiitem{ImageBuf ImageBufAlgo.{\ce convolve} (src, kernel, normalize=True, \\
3028  \bigspc\bigspc  roi=ROI.All, nthreads=0)\\
3029bool ImageBufAlgo.{\ce convolve} (dst, src, kernel, normalize=True, \\
3030  \bigspc\bigspc  roi=ROI.All, nthreads=0)}
3031\index{ImageBufAlgo!convolve} \indexapi{convolve}
3032Replace the given ROI of {\cf dst} with the convolution of {\cf src} and
3033a kernel (also an \ImageBuf).
3034
3035\smallskip
3036\noindent Examples:
3037\begin{code}
3038    # Blur an image with a 5x5 Gaussian kernel
3039    Src = ImageBuf ("tahoe.exr")
3040    K = ImageBufAlgo.make_kernel (K, "gaussian", 5.0, 5.0)
3041    Blurred = ImageBufAlgo.convolve (Src, K)
3042\end{code}
3043\apiend
3044
3045
3046\apiitem{ImageBuf ImageBufAlgo.{\ce laplacian} (src, roi=ROI.All, nthreads=0)\\
3047bool ImageBufAlgo.{\ce laplacian} (dst, src, roi=ROI.All, nthreads=0)}
3048\index{ImageBufAlgo!laplacian} \indexapi{laplacian}
3049Replace the given ROI of {\cf dst} with the Laplacian of the corresponding
3050part of {\cf src}.
3051
3052\smallskip
3053\noindent Examples:
3054\begin{code}
3055    Src = ImageBuf ("tahoe.exr")
3056    L = ImageBufAlgo.laplacian (Src)
3057\end{code}
3058\apiend
3059
3060
3061\apiitem{ImageBuf ImageBufAlgo.{\ce fft} (src, roi=ROI.All, nthreads=0) \\
3062bool ImageBufAlgo.{\ce fft} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex]
3063ImageBuf ImageBufAlgo.{\ce ifft} (src, roi=ROI.All, nthreads=0) \\
3064bool ImageBufAlgo.{\ce ifft} (dst, src, roi=ROI.All, nthreads=0)}
3065\index{ImageBufAlgo!fft} \indexapi{fft}
3066\index{ImageBufAlgo!ifft} \indexapi{ifft}
3067
3068Compute the forward or inverse discrete Fourier Transform.
3069
3070\smallskip
3071\noindent Examples:
3072\begin{code}
3073    Src = ImageBuf ("tahoe.exr")
3074
3075    # Take the DFT of the first channel of Src
3076    Freq = ImageBufAlgo.fft (Src)
3077
3078    # At this point, Freq is a 2-channel float image (real, imag)
3079    # Convert it back from frequency domain to a spatial iamge
3080    Spatial = ImageBufAlgo.ifft (Freq)
3081\end{code}
3082\apiend
3083
3084
3085\apiitem{ImageBuf ImageBufAlgo.{\ce complex_to_polar} (src, roi=ROI.All, nthreads=0) \\
3086bool ImageBufAlgo.{\ce complex_to_polar} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex]
3087ImageBuf ImageBufAlgo.{\ce polar_to_complex} (src, roi=ROI.All, nthreads=0) \\
3088bool ImageBufAlgo.{\ce polar_to_complex} (dst, src, roi=ROI.All, nthreads=0)}
3089\index{ImageBufAlgo!polar_to_complex} \indexapi{polar_to_complex}
3090\index{ImageBufAlgo!complex_to_polar} \indexapi{complex_to_polar}
3091
3092Transform a 2-channel image from complex (real, imaginary) representation
3093to polar (amplitude, phase), or vice versa.
3094
3095\smallskip
3096\noindent Examples:
3097\begin{code}
3098    Polar = ImageBuf ("polar.exr")
3099
3100    Complex = ImageBufAlgo.polar_to_complex (Polar)
3101
3102    # At this point, Complex is a 2-channel complex image (real, imag)
3103    # Convert it back from frequency domain to a spatial iamge
3104    Spatial = ImageBufAlgo.ifft (Complex)
3105\end{code}
3106\apiend
3107
3108
3109
3110\subsection{Image Enhancement / Restoration}
3111\label{sec:iba:py:enhance}
3112
3113\apiitem{ImageBuf ImageBufAlgo.{\ce fixNonFinite} (src,
3114  mode=NONFINITE_BOX3, \\ \bigspc\bigspc\spc roi=ROI.All, nthreads=0)\\
3115bool ImageBufAlgo.{\ce fixNonFinite} (dst, src,
3116  mode=NONFINITE_BOX3, \\ \bigspc\bigspc\spc roi=ROI.All, nthreads=0)}
3117\index{ImageBufAlgo!fixNonFinite} \indexapi{fixNonFinite}
3118
3119Copy pixel values from {\cf src} and repair any non-finite ({\cf NaN} or {\cf
3120Inf}) pixels.
3121
3122How the non-finite values are repaired is specified by one of the
3123following modes: \\
3124{\cf OpenImageIO.NONFINITE_NONE}, \\
3125{\cf OpenImageIO.NONFINITE_BLACK} \\
3126{\cf OpenImageIO.NONFINITE_BOX3}
3127
3128\smallskip
3129\noindent Examples:
3130\begin{code}
3131    Src = ImageBuf ("tahoe.exr")
3132    ImageBufAlgo.fixNonFinite (Src, Src, OpenImageIO.NONFINITE_BOX3)
3133\end{code}
3134\apiend
3135
3136
3137\apiitem{ImageBuf ImageBufAlgo.{\ce fillholes_pushpull} (src, roi=ROI.All, nthreads=0) \\
3138bool ImageBufAlgo.{\ce fillholes_pushpull} (dst, src, roi=ROI.All, nthreads=0)}
3139\index{ImageBufAlgo!fillholes_pushpull} \indexapi{fillholes_pushpull}
3140
3141Copy the specified ROI of {\cf src} and fill any
3142holes (pixels where alpha $< 1$) with plausible values using a push-pull
3143technique.  The {\cf src} image must have
3144an alpha channel.  The {\cf dst} image will end up with a copy of src, but
3145will have an alpha of 1.0 everywhere, and any place where the alpha
3146of src was < 1, dst will have a pixel color that is a plausible
3147``filling'' of the original alpha hole.
3148
3149\smallskip
3150\noindent Examples:
3151\begin{code}
3152    Src = ImageBuf ("holes.exr")
3153    Filled = ImageBufAlgo.fillholes_pushpull (Src)
3154\end{code}
3155\apiend
3156
3157
3158\apiitem{bool ImageBufAlgo.{\ce median_filter} (dst, src, width=3, height=-1, \\
3159  \bigspc\spc  roi=ROI.All, nthreads=0)}
3160\index{ImageBufAlgo!median_filter} \indexapi{median_filter}
3161
3162
3163Replace the given ROI of {\cf dst} with the
3164${\mathit width} \times {\mathit height}$ median filter of the corresponding
3165region of {\cf src} using the ``unsharp mask'' technique.
3166
3167\smallskip
3168\noindent Examples:
3169\begin{code}
3170    Noisy = ImageBuf ("tahoe.exr")
3171    Clean = ImageBuf ()
3172    ImageBufAlgo.median_filter (Clean, Noisy, 3, 3)
3173\end{code}
3174\apiend
3175
3176
3177\apiitem{ImageBuf ImageBufAlgo.{\ce dilate} (src, width=3, height=-1, roi=ROI.All, nthreads=0) \\
3178bool ImageBufAlgo.{\ce dilate} (dst, src, width=3, height=-1, roi=ROI.All, nthreads=0) \\[1.0ex]
3179ImageBuf ImageBufAlgo.{\ce erode} (src, width=3, height=-1, roi=ROI.All, nthreads=0) \\
3180bool ImageBufAlgo.{\ce erode} (dst, src, width=3, height=-1, roi=ROI.All, nthreads=0) }
3181\index{ImageBufAlgo!dilate} \indexapi{dilate}
3182\index{ImageBufAlgo!erode} \indexapi{erode}
3183
3184Compute a dilated or eroded version of the corresponding region of {\cf src}.
3185
3186\smallskip
3187\noindent Examples:
3188\begin{code}
3189    Source = ImageBuf ("source.tif")
3190    Dilated = ImageBufAlgo.dilate (Source, 3, 3)
3191\end{code}
3192\apiend
3193
3194
3195\apiitem{ImageBuf ImageBufAlgo.{\ce unsharp_mask} (src, kernel="gaussian", width=3.0, \\
3196  \bigspc\spc contrast=1.0, threshold=0.0, roi=ROI.All, nthreads=0)\\
3197bool ImageBufAlgo.{\ce unsharp_mask} (dst, src, kernel="gaussian", width=3.0, \\
3198  \bigspc\spc contrast=1.0, threshold=0.0, roi=ROI.All, nthreads=0)}
3199\index{ImageBufAlgo!unsharp_mask} \indexapi{unsharp_mask}
3200
3201Compute a sharpened version of the corresponding region of {\cf src} using
3202the ``unsharp mask'' technique.
3203
3204\smallskip
3205\noindent Examples:
3206\begin{code}
3207    Blurry = ImageBuf ("tahoe.exr")
3208    Sharp = ImageBufAlgo.unsharp_mask (Blurry, "gaussian", 5.0)
3209\end{code}
3210\apiend
3211
3212
3213
3214\subsection{Color manipulation}
3215\label{sec:iba:py:color}
3216
3217\apiitem{ImageBuf ImageBufAlgo.{\ce colorconvert} (src, fromspace, tospace, unpremult=True, \\
3218  \bigspc\bigspc context_key="", context_value="", \\
3219  \bigspc\bigspc  colorconfig="", roi=ROI.All, nthreads=0) \\
3220bool ImageBufAlgo.{\ce colorconvert} (dst, src, fromspace, tospace, unpremult=True, \\
3221  \bigspc\bigspc context_key="", context_value="", \\
3222  \bigspc\bigspc  colorconfig="", roi=ROI.All, nthreads=0)
3223}
3224\index{ImageBufAlgo!colorconvert} \indexapi{colorconvert}
3225Apply a color transform to the pixel values.
3226
3227\smallskip
3228\noindent Examples:
3229\begin{code}
3230    Src = ImageBuf ("tahoe.jpg")
3231    Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "linear")
3232\end{code}
3233\apiend
3234
3235
3236\apiitem{ImageBuf ImageBufAlgo.{\ce colormatrixtransform} (src, M, unpremult=True, \\
3237  \bigspc\bigspc  roi=ROI.All, nthreads=0) \\
3238bool ImageBufAlgo.{\ce colormatrixtransform} (dst, src, M, unpremult=True, \\
3239  \bigspc\bigspc  roi=ROI.All, nthreads=0)
3240}
3241\index{ImageBufAlgo!colormatrixtransform} \indexapi{colormatrixtransform}
3242\NEW % 2.1
3243Apply a $4 \times 4$ matrix color transform to the pixel values. The matrix
3244can be any tuple of 16 float values.
3245
3246\smallskip
3247\noindent Examples:
3248\begin{code}
3249    Src = ImageBuf ("tahoe.jpg")
3250    M = ( .8047379,  .5058794, -.3106172, 0,
3251         -.3106172,  .8047379,  .5058794, 0,
3252          .5058794, -.3106172,  .8047379, 0,
3253          0,         0,         0,       1)
3254    Dst = ImageBufAlgo.colormatrixtransform (Src, M)
3255\end{code}
3256\apiend
3257
3258
3259\apiitem{ImageBuf ImageBufAlgo.{\ce ociolook} (src, looks, fromspace, tospace,  \\
3260  \bigspc\bigspc  inverse=False, unpremult=True, \\
3261  \bigspc\bigspc context_key="", context_value="", colorconfig="", \\
3262  \bigspc\bigspc roi=ROI.All, nthreads=0)\\
3263bool ImageBufAlgo.{\ce ociolook} (dst, src, looks, fromspace, tospace,  \\
3264  \bigspc\bigspc  inverse=False, unpremult=True, \\
3265  \bigspc\bigspc context_key="", context_value="", colorconfig="", \\
3266  \bigspc\bigspc roi=ROI.All, nthreads=0)}
3267\index{ImageBufAlgo!ociolook} \indexapi{ociolook}
3268Apply an OpenColorIO ``look'' transform to the pixel values.
3269
3270\smallskip
3271\noindent Examples:
3272\begin{code}
3273    Src = ImageBuf ("tahoe.jpg")
3274    Dst = ImageBufAlgo.ociolook (Src, "look", "vd8", "lnf",
3275                            context_key="SHOT", context_value="pe0012")
3276\end{code}
3277\apiend
3278
3279
3280\apiitem{ImageBuf ImageBufAlgo.{\ce ociodisplay} (src, display, view, \\
3281  \bigspc\bigspc fromspace="", looks="", unpremult=True, \\
3282  \bigspc\bigspc context_key="", context_value="", colorconfig="", \\
3283  \bigspc\bigspc roi=ROI.All, nthreads=0) \\
3284bool ImageBufAlgo.{\ce ociodisplay} (dst, src, display, view, \\
3285  \bigspc\bigspc fromspace="", looks="", unpremult=True, \\
3286  \bigspc\bigspc context_key="", context_value="", colorconfig="", \\
3287  \bigspc\bigspc roi=ROI.All, nthreads=0)}
3288\index{ImageBufAlgo!ociodisplay} \indexapi{ociodisplay}
3289Apply an OpenColorIO ``display'' transform to the pixel values.
3290
3291\smallskip
3292\noindent Examples:
3293\begin{code}
3294    Src = ImageBuf ("tahoe.exr")
3295    Dst = ImageBufAlgo.ociodisplay (Src, "sRGB", "Film", "lnf",
3296                              context_key="SHOT", context_value="pe0012")
3297\end{code}
3298\apiend
3299
3300
3301\apiitem{ImageBuf ImageBufAlgo.{\ce ociofiletransform} (src, name, \\
3302  \bigspc\bigspc unpremult=True, invert=False, colorconfig="", \\
3303  \bigspc\bigspc roi=ROI.All, nthreads=0) \\
3304bool ImageBufAlgo.{\ce ociofiletransform} (dst, src, name, \\
3305  \bigspc\bigspc unpremult=True, invert=False, colorconfig="", \\
3306  \bigspc\bigspc roi=ROI.All, nthreads=0)}
3307\index{ImageBufAlgo!ociofiletransform} \indexapi{ociofiletransform}
3308Apply an OpenColorIO ``file'' transform to the pixel values.
3309In-place operations ({\cf dst} and {\cf src} being the same image)
3310are supported.
3311
3312\smallskip
3313\noindent Examples:
3314\begin{code}
3315    Src = ImageBuf ("tahoe.exr")
3316    Dst = ImageBufAlgo.ociofiletransform (Src, "foottransform.csp")
3317\end{code}
3318\apiend
3319
3320
3321\apiitem{ImageBuf ImageBufAlgo.{\ce unpremult} (src, roi=ROI.All, nthreads=0) \\
3322bool ImageBufAlgo.{\ce unpremult} (dst, src, roi=ROI.All, nthreads=0) \\[1.0ex]
3323ImageBuf ImageBufAlgo.{\ce premult} (src, roi=ROI.All, nthreads=0) \\
3324bool ImageBufAlgo.{\ce premult} (dst, src, roi=ROI.All, nthreads=0)}
3325\index{ImageBufAlgo!unpremult} \indexapi{unpremult}
3326\index{ImageBufAlgo!premult} \indexapi{premult}
3327Copy pixels from {\cf src} to {\cf dst}, and un-premultiply (or
3328premultiply) the colors by alpha.
3329
3330\smallskip
3331\noindent Examples:
3332\begin{code}
3333    # Convert in-place from associated alpha to unassociated alpha
3334    A = ImageBuf ("a.exr")
3335    ImageBufAlgo.unpremult (A, A)
3336\end{code}
3337\apiend
3338
3339
3340
3341\subsection{Import / export}
3342\label{sec:iba:py:importexport}
3343
3344\apiitem{bool ImageBufAlgo.{\ce make_texture} (mode, input,\\
3345\bigspc\bigspc outputfilename, config=ImageSpec())}
3346\index{ImageBufAlgo!make_texture} \indexapi{make_texture}
3347
3348Turn an input image (either an \ImageBuf or a string giving a filename)
3349into a tiled, MIP-mapped, texture file and write to the
3350file named by ({\cf outputfilename}).  The {\cf mode} describes what type of texture file we
3351are creating and may be one of the following:
3352
3353\noindent \begin{tabular}{p{4in}}
3354{\cf OpenImageIO.MakeTxTexture} \\
3355{\cf OpenImageIO.MakeTxEnvLatl} \\
3356{\cf OpenImageIO.MakeTxEnvLatlFromLightProbe} \\
3357\end{tabular}
3358
3359The {\cf config}, if supplied, is an \ImageSpec that contains all the
3360information and special instructions for making the texture. The full list
3361of supported configuration options is given in
3362Section~\ref{sec:iba:importexport}.
3363
3364\smallskip
3365\noindent Examples:
3366\begin{code}
3367    # This command line:
3368    #    maketx in.exr --hicomp --filter lanczos3 --opaque-detect \
3369    #             -o texture.exr
3370    # is equivalent to:
3371
3372    Input = ImageBuf ("in.exr")
3373    config = ImageSpec()
3374    config.attribute ("maketx:highlightcomp", 1)
3375    config.attribute ("maketx:filtername", "lanczos3")
3376    config.attribute ("maketx:opaque_detect", 1)
3377    ImageBufAlgo.make_texture (oiio.MakeTxTexture, Input,
3378                               "texture.exr", config)
3379\end{code}
3380\apiend
3381
3382
3383\apiitem{ImageBuf ImageBufAlgo::{\ce capture_image} (cameranum, convert = OpenImageIO.UNKNOWN)}
3384\index{ImageBufAlgo!capture_image} \indexapi{capture_image}
3385Capture a still image from a designated camera.
3386
3387\smallskip
3388\noindent Examples:
3389\begin{code}
3390    WebcamImage = ImageBufAlgo.capture_image (0, OpenImageIO.UINT8)
3391    WebcamImage.write ("webcam.jpg")
3392\end{code}
3393\apiend
3394
3395
3396\subsection{Functions specific to deep images}
3397
3398\apiitem{ImageBuf ImageBufAlgo.{\ce deepen} (src, zvalue=1.0, roi=ROI.All, nthreads=0)\\
3399bool ImageBufAlgo.{\ce deepen} (dst, src, zvalue=1.0, roi=ROI.All, nthreads=0)}
3400\index{ImageBufAlgo!deepen} \indexapi{deepen} \index{deep images}
3401
3402Convert a flat image to a deep one that has one depth sample per pixel
3403(but no depth samples for the pixels corresponding to those in the source
3404image that have infinite \qkw{Z} or that had 0 for all color channels and no
3405\qkw{Z} channel).
3406
3407\smallskip
3408\noindent Examples:
3409\begin{code}
3410    Deep = ImageBufAlgo.deepen (ImageBuf("az.exr"))
3411\end{code}
3412\apiend
3413
3414
3415\apiitem{ImageBuf ImageBufAlgo.{\ce flatten} (src, roi=ROI.All, nthreads=0)\\
3416bool ImageBufAlgo.{\ce flatten} (dst, src, roi=ROI.All, nthreads=0)}
3417\index{ImageBufAlgo!flatten} \indexapi{flatten} \index{deep images}
3418
3419Composite the depth samples within each pixel of ``deep'' \ImageBuf\ {\cf
3420src} to produce a ``flat'' \ImageBuf.
3421
3422\smallskip
3423\noindent Examples:
3424\begin{code}
3425    Flat = ImageBufAlgo.flatten (ImageBuf("deepalpha.exr"))
3426\end{code}
3427\apiend
3428
3429\apiitem{ImageBuf ImageBufAlgo.{\ce deep_merge} (A, B, occlusion_cull, roi=ROI.All, nthreads=0) \\
3430bool ImageBufAlgo.{\ce deep_merge} (dst, A, B, occlusion_cull, roi=ROI.All, nthreads=0)}
3431\index{ImageBufAlgo!deep_merge} \indexapi{deep_merge} \index{deep images}
3432
3433Merge the samples of two \emph{deep} images {\cf A} and {\cf B} into a deep
3434result. If {\cf occlusion_cull} is {\cf True}, samples beyond
3435the first opaque sample will be discarded, otherwise they will be kept.
3436
3437\smallskip
3438\noindent Examples:
3439\begin{code}
3440    DeepA = ImageBuf("hardsurf.exr")
3441    DeepB = ImageBuf("volume.exr")
3442    Merged = ImageBufAlgo.deep_merge (DeepA, DeepB)
3443\end{code}
3444\apiend
3445
3446\apiitem{ImageBuf ImageBufAlgo.{\ce deep_holdout} (src, holdout, roi=ROI.All, nthreads=0) \\
3447bool ImageBufAlgo.{\ce deep_holdout} (dst, src, holdout, roi=ROI.All, nthreads=0)}
3448\index{ImageBufAlgo!deep_holdout} \indexapi{deep_holdout} \index{deep images}
3449
3450Return the pixels of {\cf src}, but only copying the
3451samples that are closer than the opaque frontier of image {\cf holdout}.
3452That is, {\cf holdout} will serve as a depth holdout mask, but no samples
3453from {\cf holdout} will actually be copied to {\cf dst}.
3454
3455\smallskip
3456\noindent Examples:
3457\begin{code}
3458    Img = ImageBuf("image.exr")
3459    Mask = ImageBuf("mask.exr")
3460    Thresholded = ImageBufAlgo.deep_holdout (Img, Mask)
3461\end{code}
3462\apiend
3463
3464
3465\subsection*{Other ImageBufAlgo methods that understand deep images}
3466
3467In addition to the previously described methods that are specific to
3468deep images, the following \ImageBufAlgo methods (described in their
3469respective sections) work with deep inputs:
3470
3471\medskip
3472
3473\noindent
3474{\cf ImageBufAlgo.add} \\
3475{\cf ImageBufAlgo.channels} \\
3476{\cf ImageBufAlgo.compare} \\
3477{\cf ImageBufAlgo.computePixelStats} \\
3478{\cf ImageBufAlgo.crop} \\
3479{\cf ImageBufAlgo.div} \\
3480{\cf ImageBufAlgo.fixNonFinite} \\
3481{\cf ImageBufAlgo.mul} \\
3482{\cf ImageBufAlgo.nonzero_region} \\
3483{\cf ImageBufAlgo.resample} \\
3484{\cf ImageBufAlgo.sub} \\
3485
3486
3487\newpage
3488\section{Miscellaneous Utilities}
3489\label{sec:pythonmiscapi}
3490
3491In the main {\cf OpenImageIO} module, there are a number of values and
3492functions that are useful.  These correspond to the C++ API functions
3493explained in Section~\ref{sec:miscapi}, please refer there for details.
3494
3495\apiitem{int {\ce openimageio_version}}
3496The \product version number, 10000 for each
3497major version, 100 for each minor version, 1 for each patch.  For
3498example, \product 1.2.3 would return a value of 10203.
3499\apiend
3500
3501\apiitem{str {\ce geterror} ()}
3502Retrieves the latest global error.
3503\apiend
3504
3505\apiitem{bool {\ce attribute} (name, typedesc, value) \\
3506bool {\ce attribute} (name, int_value) \\
3507bool {\ce attribute} (name, float_value) \\
3508bool {\ce attribute} (name, str_value)}
3509Sets a global attribute (see Section~\ref{sec:miscapi} for details),
3510returning {\cf True} upon success, or {\cf False} if it was not a
3511recognized attribute.
3512
3513\noindent Example:
3514\begin{code}
3515    oiio.attribute ("threads", 0)
3516\end{code}
3517\apiend
3518
3519\apiitem{{\ce getattribute} (name, typedesc) \\
3520{\ce get_int_attribute} (name, defaultval=0) \\
3521{\ce get_float_attribute} (name, defaultval=0.0) \\
3522{\ce get_string_attribute} (name, defaultval="")}
3523Retrieves an attribute value from the named set of global OIIO options. (See
3524Section~\ref{sec:globalattribute}.) The {\cf getattribute()} function
3525returns the value regardless of type, or {\cf None} if the attribute does
3526not exist.  The typed variety will only succeed if the attribute is actually
3527of that type specified. Type varity with the type in the name also takes a
3528default value.
3529
3530\noindent Example:
3531\begin{code}
3532    formats = oiio.get_string_attribute ("format_list")
3533\end{code}
3534\apiend
3535
3536
3537
3538\section{Python Recipes}
3539\label{sec:pythonrecipes}
3540
3541This section illustrates the Python syntax for doing many common image
3542operations from Python scripts, but that aren't already given as examples
3543in the earlier function descriptions.  All example code fragments assume the
3544following boilerplate:
3545
3546\begin{code}
3547    #!/usr/bin/env python
3548
3549    import OpenImageIO as oiio
3550    from OpenImageIO import ImageBuf, ImageSpec, ImageBufAlgo
3551\end{code}
3552
3553
3554\subsubsection*{Subroutine to create a constant-colored image}
3555\begin{code}
3556    # Create an ImageBuf holding a n image of constant color, given the
3557    # resolution, data format (defaulting to UINT8), fill value, and image
3558    # origin.
3559    def make_constimage (xres, yres, chans=3, format=oiio.UINT8, value=(0,0,0),
3560                         xoffset=0, yoffset=0) :
3561        spec = ImageSpec (xres,yres,chans,format)
3562        spec.x = xoffset
3563        spec.y = yoffset
3564        b = ImageBuf (spec)
3565        oiio.ImageBufAlgo.fill (b, value)
3566        return b
3567\end{code}
3568
3569\noindent The image is returned as an \ImageBuf, then up to the caller
3570what to do with it next.
3571
3572\subsubsection*{Subroutine to save an image to disk, printing errors}
3573\begin{code}
3574    # Save an ImageBuf to a given file name, with optional forced image format
3575    # and error handling.
3576    def write_image (image, filename, format=oiio.UNKNOWN) :
3577        if not image.has_error :
3578            image.write (filename, format)
3579        if image.has_error :
3580            print "Error writing", filename, ":", image.geterror()
3581\end{code}
3582
3583
3584\subsubsection*{Converting between file formats}
3585
3586\begin{code}
3587    img = ImageBuf ("input.png")
3588    write_image (img, "output.tif")
3589\end{code}
3590
3591
3592\subsubsection*{Comparing two images and writing a difference image}
3593
3594\begin{code}
3595    A = ImageBuf ("A.tif")
3596    B = ImageBuf ("B.tif")
3597    compresults = ImageBufAlgo.compare (A, B, 1.0e-6, 1.0e-6)
3598    if compresults.nfail > 0 :
3599        print "Images did not match, writing difference image diff.tif"
3600        diff = ImageBufAlgo.absdiff (A, B)
3601        image_write (diff, "diff.tif")
3602\end{code}
3603
3604
3605\subsubsection*{Changing the data format or bit depth}
3606
3607\begin{code}
3608    img = ImageBuf ("input.exr")
3609    # presume that it's a "half" OpenEXR file
3610    # write it back out as a "float" file:
3611    write_image (img, "output.exr", oiio.FLOAT)
3612\end{code}
3613
3614
3615\subsubsection*{Changing the compression}
3616
3617The following command converts writes a TIFF file, specifically using
3618LZW compression:
3619
3620\begin{code}
3621    img = ImageBuf ("in.tif")
3622    img.specmod().attribute ("compression", "lzw")
3623    write_image (img, "compressed.tif")
3624\end{code}
3625
3626The following command writes its results as a JPEG file at a
3627compression quality of 50 (pretty severe compression):
3628
3629\begin{code}
3630    img = ImageBuf ("big.jpg")
3631    img.specmod().attribute ("quality", 50)
3632    write_image (img, "small.jpg")
3633\end{code}
3634
3635
3636\subsubsection*{Converting between scanline and tiled images}
3637
3638\begin{code}
3639    img = ImageBuf ("scan.tif")
3640    img.set_write_tiles (16, 16)
3641    write_image (img, "tile.tif")
3642
3643    img = ImageBuf ("tile.tif")
3644    img.set_write_tiles (0, 0)
3645    write_image (img, "scan.tif")
3646\end{code}
3647
3648
3649\subsubsection*{Adding captions or metadata}
3650
3651\begin{code}
3652    img = ImageBuf ("foo.jpg")
3653    # Add a caption:
3654    img.specmod().attribute ("ImageDescription", "Hawaii vacation")
3655    # Add keywords:
3656    img.specmod().attribute ("keywords", "volcano,lava")
3657    write_image (img, "foo.jpg")
3658\end{code}
3659
3660
3661\subsubsection*{Changing image boundaries}
3662
3663\noindent Change the origin of the pixel data window:
3664\begin{code}
3665    img = ImageBuf ("in.exr")
3666    img.set_origin (256, 80)
3667    write_image (img, "offset.exr")
3668\end{code}
3669
3670\noindent Change the display window:
3671\begin{code}
3672    img = ImageBuf ("in.exr")
3673    img.set_full (16, 1040, 16, 784)
3674    write_image (img, "out.exr")
3675\end{code}
3676
3677\noindent Change the display window to match the data window:
3678\begin{code}
3679    img = ImageBuf ("in.exr")
3680    img.set_full (img.roi())
3681    write_image (img, "out.exr")
3682\end{code}
3683
3684\noindent Cut (trim and extract) a 128x128 region whose upper left corner
3685is at location (900,300), moving the result to the origin (0,0) of the image
3686plane and setting the display window to the new pixel data window:
3687\begin{code}
3688    img = ImageBuf ("in.exr")
3689    b = ImageBufAlgo.cut (img, oiio.ROI(900,1028,300,428))
3690    write_image (b, "out.exr")
3691\end{code}
3692
3693
3694\subsubsection*{Extract just the named channels from a complicted many-channel
3695image, and add an alpha channel that is 1 everywhere}
3696\begin{code}
3697    img = ImageBuf ("allmyaovs.exr")
3698    b = ImageBufAlgo.channels (img, ("spec.R", "spec.G", "spec.B", 1.0))
3699    write_image (b, "spec.tif")
3700\end{code}
3701
3702
3703\subsubsection*{Fade 30\% of the way between two images}
3704
3705\begin{code}
3706    a = ImageBufAlgo.mul (ImageBuf("A.exr"), 0.7)
3707    b = ImageBufAlgo.mul (ImageBuf("B.exr"), 0.3)
3708    fade = ImageBufAlgo.add (a, b)
3709    write_image (fade, "fade.exr")
3710\end{code}
3711
3712
3713\subsubsection*{Composite of small foreground over background, with offset}
3714
3715\begin{code}
3716    fg = ImageBuf ("fg.exr")
3717    fg.set_origin (512, 89)
3718    bg = ImageBuf ("bg.exr")
3719    comp = ImageBufAlgo.over (fg, bg)
3720    write_image (comp, "composite.exr")
3721\end{code}
3722
3723
3724
3725
3726\index{Python|)}
3727
3728\chapwidthend
3729