public class EXROutputFile extends Object implements AutoCloseable
EXROutputFile
provides an interface for writing scan line OpenEXR
images in a general way.
Note that this implementation is not synchronized. If multiple
threads access an EXROutputFile
instance and at least one thread
changes the frame buffer of writes pixels, it must be
synchronized externally.
Constructor and Description |
---|
EXROutputFile(EXROutputStream os,
Header hdr)
A constructor that attaches the new
EXROutputStream to a stream
that has already been open, writing the given header. |
EXROutputFile(EXROutputStream os,
Header hdr,
boolean closeStream)
A constructor that attaches the new
EXROutputStream to a stream
that has already been open, writing the given header, and allows to close
the output stream along with the output file. |
EXROutputFile(EXROutputStream os,
Header hdr,
boolean closeStream,
int numThreads)
A constructor that attaches the new
EXROutputStream to a stream
that has already been open, writing the given header, using a specific
number of threads for I/O and allows to close the output stream along
with the output file. |
EXROutputFile(EXROutputStream os,
Header hdr,
int numThreads)
A constructor that attaches the new
EXROutputStream to a stream
that has already been open, writing the given header, using a specific
number of threads for I/O. |
EXROutputFile(Path path,
Header hdr)
A constructor that opens the file denoted by the given path, writing
the given header.
|
EXROutputFile(Path path,
Header hdr,
int numThreads)
A constructor that opens the file denoted by the given path, writing
the given header, using a specific number of threads for I/O.
|
Modifier and Type | Method and Description |
---|---|
void |
close()
Closes the underlying stream, if one was used when the instance was
constructed, and destroys the underlying native object.
|
int |
currentScanLine()
Returns the current scan line.
|
FrameBuffer |
getFrameBuffer()
Returns a reference to the current frame buffer, or
null if it
has not been set yet. |
Header |
getHeader()
Returns a reference to the output file's header.
|
boolean |
isOpen()
Returns
true if the underlying input file is open for writing. |
void |
setFrameBuffer(FrameBuffer fBuffer)
Set the current frame buffer by doing a deep copy of the FrameBuffer
input object into this instance.
|
void |
updatePreviewImage(byte[] newPixels)
Updates the preview image attribute, it the header has such attribute.
|
void |
writePixels()
Write the next scan line from the frame buffer.
|
void |
writePixels(int numScanlines)
Write pixel data for the next group of consecutive scan lines.
|
public EXROutputFile(Path path, Header hdr) throws EXRIOException
Calling close
will close the file and destroy the underlying
native object. The image is written using the current number of threads
in the global pool.
Note that even though constructing an output file this way instead of
using an EXROutputStream
may yield higher throughput, there is
a limitation on the number of files that can be simultaneously open.
On Windows 7 this limit is about 500.
path
- the path to be opened for writinghdr
- the header of the fileEXRIOException
- if an I/O error occursThreading
public EXROutputFile(Path path, Header hdr, int numThreads) throws EXRIOException
Calling close
will close the file and destroy the underlying
native object. numThreads
determines the number of threads that
will be used to write and compress the file.
Note that even though constructing an output file this way instead of
using an EXROutputStream
may yield higher throughput, there is
a limitation on the number of files that can be simultaneously open.
On Windows 7 this limit is about 500.
path
- the path to be opened for writinghdr
- the header of the filenumThreads
- number of native threads to write and compress the
file, if zero all tasks run on the current thread.EXRIOException
- if an I/O error occursThreading
public EXROutputFile(EXROutputStream os, Header hdr) throws EXRIOException
EXROutputStream
to a stream
that has already been open, writing the given header.
Closing this instance will not close the stream, it will only destroy the underlying native object. The image is written using the current number of threads in the global pool.
Note that by using this constructor the writing performance may be lower than that attained by the constructors which explicitly get a path to open. This is due to the current implementation which relies on JNI calls to the OpenEXR C++ library.
os
- an already open output streamhdr
- the header of the fileEXRIOException
- if an I/O error occursThreading
public EXROutputFile(EXROutputStream os, Header hdr, int numThreads) throws EXRIOException
EXROutputStream
to a stream
that has already been open, writing the given header, using a specific
number of threads for I/O.
Closing this instance will not close the stream, it will only destroy
the underlying native object. numThreads
determines the number of
threads that will be used to write and compress the file.
Note that by using this constructor the writing performance may be lower than that attained by the constructors which explicitly get a path to open. This is due to the current implementation which relies on JNI calls to the OpenEXR C++ library.
os
- an already open output streamhdr
- the header of the filenumThreads
- number of native threads to write and compress the
file, if zero all tasks run on the current thread.EXRIOException
- if an I/O error occursThreading
public EXROutputFile(EXROutputStream os, Header hdr, boolean closeStream) throws EXRIOException
EXROutputStream
to a stream
that has already been open, writing the given header, and allows to close
the output stream along with the output file.
If closeStream
is true
closing this instance will
close the out stream as well (if it implements AutoCloseable
),
otherwise the stream will remain open and it will only destroy the
underlying native object. The image is written using the current
number of threads in the global pool.
Note that by using this constructor the writing performance may be lower than that attained by the constructors which explicitly get a path to open. This is due to the current implementation which relies on JNI calls to the OpenEXR C++ library.
os
- an already open output streamhdr
- the header of the filecloseStream
- if true
closing this output file will close
the stream as well.EXRIOException
- if an I/O error occursThreading
public EXROutputFile(EXROutputStream os, Header hdr, boolean closeStream, int numThreads) throws EXRIOException
EXROutputStream
to a stream
that has already been open, writing the given header, using a specific
number of threads for I/O and allows to close the output stream along
with the output file.
If closeStream
is true
closing this instance will
close the out stream as well (if it implements AutoCloseable
),
otherwise the stream will remain open and it will only destroy the
underlying native object. numThreads
determines the number of
threads that will be used to write and compress the file.
Note that by using this constructor the writing performance may be lower than that attained by the constructors which explicitly get a path to open. This is due to the current implementation which relies on JNI calls to the OpenEXR C++ library.
os
- an already open output streamhdr
- the header of the filecloseStream
- if true
closing this output file will close
the stream as well.numThreads
- number of native threads to write and compress the
file, if zero all tasks run on the current thread.EXRIOException
- if an I/O error occursThreading
public void close() throws EXRIOException
close
in interface AutoCloseable
EXRIOException
- if there is an error while closing either the
output file or the underlying streampublic boolean isOpen()
true
if the underlying input file is open for writing.true
if the underlying input file is open for writing.public Header getHeader()
For efficiency this function returns the actual header of this output
file thus callers ought not to modify the returned instance.
In contrast to C++, returning a completely read-only header would require
a lot of changes, including supporting only attributes with all-final
accessible fields and/or read-only aware setters. As a safety feature
the implementation caches the hash code of the header upon creating the
file and compares it against the current header's hash code. It they
do not match it throws an IllegalStateException
.
Because of the validation, clients which will use the header for
multiple operations should call getHeader
only once and then
use the validated reference.
IllegalStateException
- if the header has been modified externallypublic void setFrameBuffer(FrameBuffer fBuffer)
The current frame buffer is the source for the pixel
data written to the stream. The current frame buffer must be
set at least once before writeixels()
is called.
The current frame buffer can be changed after each call
to writePixels()
.
Note that there is no automatic conversion of neither pixel types or sampling factors for output files: for each slice with a matching channel in the header, their pixel types and x/y sampling factor must match.
fBuffer
- the source frame bufferIllegalArgumentException
- if fBuffer
does not
meet the required preconditionsIllegalStateException
- if the stream is not open or the header was
modified externallypublic FrameBuffer getFrameBuffer()
null
if it
has not been set yet.
For efficiency this function returns the actual frame buffer of this
output file, thus callers ought not to modify the returned
instance. In contrast to C++, returning a completely read-only frame
buffer would require a lot of changes, including supporting read-only
slices with only-final accessible fields and/or read-only aware setters.
As a safety feature the implementation caches the hash code of the
frame buffer after calling setFrameBuffer
and compares it
against the current frame buffer's hash code. It they
do not match it throws an IllegalStateException
.
Because of the validation, clients which will use the frame buffer for
multiple operations should call getFrameBuffer
only once and then
use the validated reference.
null
if it
has not been set yetIllegalStateException
- if the frame buffer has been modified
externallypublic void writePixels(int numScanlines) throws IllegalArgumentException, IndexOutOfBoundsException, IllegalStateException
writePixels(n)
retrieves the next n
scan lines worth
of data from the current frame buffer, starting with the scan line
indicated by currentScanLine()
, and stores the data in the
output file, and progressing in the direction indicated by
header.lineOrder()
.
To produce a complete and correct file, exactly m
scan lines
must be written, where m
is equal to:
header().dataWindow().max.y - header().dataWindow().min.y + 1
numScanlines
- number of the next consecutive scan lines to writeIllegalArgumentException
- if numScanLines
is less than
1IndexOutOfBoundsException
- if (currentScanline() + numScanlines - 1)
is outside
[header().dataWindow().min.y, header().dataWindow().max.y]
IllegalStateException
- if the file is not open for reading,
or if the frame buffer has not been set, or if either the header
or the current frame buffer have been modified externallysetFrameBuffer(edu.cornell.graphics.exr.FrameBuffer)
public void writePixels()
This implementations simply calls writePixels(1)
writePixels(int)
public int currentScanLine()
currentScanLine()
returns the y
coordinate of the
first scan line that will be read from the current frame buffer during
the next call to writePixels().
If header.lineOrder() == INCREASING_Y
:
The current scan line before the first call to writePixels()
is header().dataWindow().min.y
. After writing each scan line,
the current scan line is incremented by 1.
If header.lineOrder() == DECREASING_Y
:
The current scan line before the first call to writePixels()
is header().dataWindow().max.y
. After writing each scan line,
the current scan line is decremented by 1.
IllegalStateException
- if the file is already closedpublic void updatePreviewImage(byte[] newPixels)
updatePreviewImage()
supplies a new set of pixels for the
preview image attribute in the file's header. If the header
does not contain a preview image, updatePreviewImage()
throws
an IllegalArgumentException
.
Note: updatePreviewImage()
is necessary because images are
often stored in a file incrementally, a few scan lines at a
time, while the image is being generated. Since the preview
image is an attribute in the file's header, it gets stored in
the file as soon as the file is opened, but we may not know
what the preview image should look like until we have written
the last scan line of the main image.
newPixels
- the new interleaved RGBA8
pixelsIllegalArgumentException
- if the header does not have a preview
image attribute, or newPixels
is either null or
does not have enough data