The ‘DeepWrite’ node supports different file formats through the use of ‘DeepWriter’ plugins, in a similar way to the way the ‘Write’ node uses ‘Writer’ plugins.
A deep file writer inherits from the class DD::Image::DeepWriter, and registers itself in the symbol table by creating a DD::Image::DeepWriter::Description. For a full example, see cdfWriterDeep.cpp. The skeleton of this is:
class cdfWriter : public DeepWriter { public: cdfWriter(DeepWriterOwner* o) : DeepWriter(o) { } void knobs(Knob_Callback f) { } void execute() { input()->validate(true); const DeepInfo& di = input()->deepInfo(); const DD::Image::ChannelSet& channels = di.channels(); const int l = di.box().x(); const int r = di.box().r(); const int b = di.box().y(); const int t = di.box().t(); input()->deepRequest(di.box(), channels); input()->fillCache(); FILE* f = openFile(); for (int y = b; y < t; y++) { DeepPlane plane; if (!input()->deepEngine(y, l, r, channels, plane)) { closeFile(f); return; } // actually do something with the pixels from plane } closeFile(f); } }; static DeepWriter* build(DeepWriterOwner* iop) static const DeepWriter::Description d("cdf\0", build);
The function DeepWriter::execute() is invoked for each frame. DeepWriters (or Readers) do not currently support files containing more than one frame, so this will be to a new filename each time.
From execute(), DeepWriter::input() will return the DeepOp input build at the right frame. This then requires validating and requesting before data can be fetched from it. The above example calls ::fillCache() to ensure that the processing is done using worker threads - if deepEngine() is called from this context without having done this step, the main work will be done solely in the thread that execute() is called from.
The filename to write to is accessible from DeepWriterOwner::filename(). The DeepWriter provides helper functions, DeepWriter::openFile() and DeepWriter::closeFile() that automatically uses a temporary file and renames.
If the DeepWriter requires file-format-specific knobs, it can provide these in the knobs() function, as a regular Op would. These knobs would be deleted and replaced as the user changes the file format.