Hi,

  I have having difficult working out the correct stride logic to write one
scanline at a time to an OpenEXR file.

  The example code shows write the entire array in memory but I only have
access to a single scanline at a time.

  I want to minimize the memory usage by not storing the entire image
before writing.

  Here is the code.

  Thanks in advance.

#include <stdio.h>
#include <string>
#include <OpenEXR/ImfOutputFile.h>
#include <OpenEXR/ImfArray.h>
#include <OpenEXR/ImfCompression.h>
#include <OpenEXR/ImfChannelList.h>
#include <OpenEXR/ImfRgba.h>

// This is currently NOT working but would be a useful example to have

void writeIncrementalScanline (const std::string& fileName,
   int width,
   int height)
{
float pixelAspectRatio = 1;
const Imath::V2f screenWindowCenter = Imath::V2f (0, 0);
float screenWindowWidth = 1;
Imf::LineOrder lineOrder = Imf::INCREASING_Y;
Imf::Compression compression = Imf::ZIPS_COMPRESSION;
Imf::Header header(width, height,
   pixelAspectRatio,
   screenWindowCenter,
   screenWindowWidth,
   lineOrder,
   compression);

header.channels().insert("rgba.R",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.G",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.B",Imf::Channel(Imf::HALF));
header.channels().insert("rgba.A",Imf::Channel(Imf::HALF));
Imf::OutputFile file (fileName.c_str(), header);
Imf::FrameBuffer framebuffer;

Imf::Array2D<half> redBuffer(width,1);
Imf::Array2D<half> greenBuffer(width,1);
Imf::Array2D<half> blueBuffer(width,1);
Imf::Array2D<half> alphaBuffer(width,1);
half colorChannelGreyScaleDelta = 1.0f/float(height-1);
std::cout << "colorChannelGreyScaleDelta = " << colorChannelGreyScaleDelta
<< std::endl;
std::cout << "height * colorChannelGreyScaleDelta = " << height *
colorChannelGreyScaleDelta << std::endl;


size_t xStride = sizeof(half) * 1;
size_t yStride = width;

const half *redPixels   = &redBuffer[0][0];
const half *greenPixels = &greenBuffer[0][0];
const half *bluePixels  = &blueBuffer[0][0];
const half *alphaPixels = &alphaBuffer[0][0];

framebuffer.insert("rgba.R",
   Imf::Slice(Imf::HALF,
  (char *)redPixels,
  xStride,
  yStride));
framebuffer.insert("rgba.G",
   Imf::Slice(Imf::HALF,
  (char *)greenPixels,
  xStride,
  yStride));
framebuffer.insert("rgba.B",
   Imf::Slice(Imf::HALF,
  (char *)bluePixels,
  xStride,
  yStride));
framebuffer.insert("rgba.A",
   Imf::Slice(Imf::HALF,
  (char *)alphaPixels,
  xStride,
  yStride));


for (int h=0;h<height;h++)
{
half grey_scale_value = colorChannelGreyScaleDelta * h;
for (int w=0;w<width;w++)
{
redBuffer[w][0]   = 1.;//grey_scale_value;
greenBuffer[w][0] = 1.;//grey_scale_value;
blueBuffer[w][0]  = 1.;//grey_scale_value;
alphaBuffer[w][0] = 1.;
}

file.setFrameBuffer(framebuffer);
file.writePixels();

}
}

int main()
{
    const std::string fileName("IncrementalScanline.exr");

    const int width = 256;
    const int height = 512;
    writeIncrementalScanline (fileName, width, height);

    return 0;
}

Cheers
-- 
Nicholas Yue
_______________________________________________
Openexr-devel mailing list
Openexr-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/openexr-devel

Reply via email to