// Copyright (c) 2011 The Foundry Visionmongers Ltd. All Rights Reserved. #include "DDImage/DeepWriter.h" #include "DDImage/DeepOp.h" #include #include namespace Nuke { namespace Deep { using namespace DD::Image; /** * This is a plugin to read 'Crude Deep Format' files. NOTE THAT THIS FORMAT * IS NOT INTENDED FOR ACTUAL USE. It is intended as an example and for testing * only, in the absence of any other deep data formats suitable for this purpose. * * The CDF format consists of * * int32_t bbox l * int32_t bbox b (ascending is upwards) * int32_t bbox r * int32_t bbox t * int32_t channel mask (as per Mask_ values in DDImage/Channel.h) * int64_t[size] offsets * * The offsets table contains offsets within the file for each line between b and t. * Pixel data is according to the following layout: * * int32_t sampleCount * * float sample 0 chan 0 * float sample 0 chan 1 * ... * float sample 0 chan n * float sample 1 chan 0 * float sample 1 chan 1 * ... * float sample 1 chan n * ... * float sample n chan 0 * float sample n chan 1 * ... * float sample n chan n * */ class cdfWriter : public DeepWriter { public: cdfWriter(DeepWriterOwner* o) : DeepWriter(o) { } /** helper function for writing out an int32_t */ static void writeInt32(FILE* f, int32_t i) { fwrite(&i, sizeof(i), 1, f); } /** helper function for writing out an int64_t */ static void writeInt64(FILE* f, int64_t i) { fwrite(&i, sizeof(i), 1, f); } /** helper function for writing out a float */ static void writeFloat(FILE* f, float flt) { fwrite(&flt, sizeof(flt), 1, f); } /** * definition of knobs. Only knob is warning not to use this format * in production */ void knobs(Knob_Callback f) { Text_knob(f, "NOTE: This format is intended as an example for developers\nand for internal testing only. DO NOT USE."); } void execute() { input()->validate(true); const DeepInfo& di = input()->deepInfo(); const DD::Image::ChannelSet& channels = di.channels(); input()->deepRequest(di.box(), channels); input()->fillCache(); FILE* f = openFile(); if (!f) return; const int l = di.box().x(); const int r = di.box().r(); const int b = di.box().y(); const int t = di.box().t(); DD::Image::ChannelSet writingChannels = Mask_RGBA | Mask_Deep; writingChannels &= channels; writeInt32(f, l); writeInt32(f, b); writeInt32(f, r); writeInt32(f, t); writeInt32(f, writingChannels.value()); for (int y = b; y < t; y++) { DeepPlane plane; if (!input()->deepEngine(y, l, r, channels, plane)) return; size_t psc = 0; for (int x = l ; x < r; x++) { DeepPixel pixel = plane.getPixel(y, x); psc += pixel.getSampleCount(); } writeInt64(f, psc); } for (int y = b; y < t; y++) { DeepPlane plane; if (!input()->deepEngine(y, l, r, channels, plane)) return; for (int x = l ; x < r; x++) { DeepPixel pixel = plane.getPixel(y, x); writeInt32(f, pixel.getSampleCount()); for (int i = 0; i < pixel.getSampleCount(); i++) { foreach(z, writingChannels) { writeFloat(f, pixel.getUnorderedSample(i, z)); } } } } closeFile(f); } }; static DeepWriter* build(DeepWriterOwner* iop) { return new cdfWriter(iop); } static const DeepWriter::Description d("cdf\0", build); } }