Thanks for your answer, i did not notice this copy_image function before. Really helpful to interlace raw data. Looping on all the tiles I have in memory, calling it then calling write_tile does the job.

Still one stride issue to fix when i need to write more than 4 channels.

Thanks !

Michel


On 07/11/2013 09:26 AM, Larry Gritz wrote:
You definitely have to stage it -- copy your separate channels into the 
interleaved form that the OIIO API wants.

But you don't need to do it for an entire image at a time via 
ImageOutput::write_image().  For the sake of keeping memory under control, I 
would recommend using write_scanlines() or write_tiles().  If you write several 
scanlines at once, or a whole row of tiles/buckets at once, it can be more 
efficient than writing just one scanline or tile per call (in particular, 
OpenEXR is good at using threads to speed this up).

Also, imageio.h contains some helper routines for copying image-like data 
around that will make this whole affair simple to program.  In particular, 
copy_image().

Conceptually, it looks like this.  Let's say that you have separate buffers, 
float *red, *green, *blue.  You want something like this:

     // Open the file and set up
     int nchannels = 3;
     ImageSpec spec (xres, yres, nchannels, TypeDesc::FLOAT);
     if (you want a tiled file) {
         spec.tile_width = spec.tile_height = tilesize;
     }
     ImageOutput *out = ImageOutput::create (filename);
     out->open (filename, spec);

     // Break it up into batches of at most 64 scanlines, or the tile size
     int scanline_batch = tiled ? spec.tile_width : 64;
     std::vector<float> tmp (xres*scanline_batch*nchannels);
     for (int y = 0;  y < yres;  y += scanline_batch) {
         int n = std::min (scanline_batch, yres-y);
        
         // Copy the separate buffers into a contiguous staging area
         OIIO::copy_image (1, xres, n, 1, red+y*xres, sizeof(float), 
sizeof(float),
                           OIIO::AutoStride, OIIO::AutoStride,
                           &tmp[0]+0, nchannels*sizeeof(float), 
OIIO::AutoStride, OIIO::AutoStride);
         OIIO::copy_image (1, xres, n, 1, green+y*xres, sizeof(float), 
sizeof(float),
                           OIIO::AutoStride, OIIO::AutoStride,
                           &tmp[0]+1, nchannels*sizeeof(float), 
OIIO::AutoStride, OIIO::AutoStride);
         OIIO::copy_image (1, xres, n, 1, blue+y*xres, sizeof(float), 
sizeof(float),
                           OIIO::AutoStride, OIIO::AutoStride,
                           &tmp[0]+2, nchannels*sizeeof(float), 
OIIO::AutoStride, OIIO::AutoStride);
         if (spec.tile_height) {
             out->write_tiles (0, xres, y, y+n, 0, 1, TypeDesc::FLOAT, &tmp[0]);
         } else {
             out->write_scanlines (y, y+n, 0, TypeDesc::FLOAT, &tmp[0]);
         }
    }

     // clean up
     out->close ();
     delete out;

I'm just typing this off the top of my head (and glancing at imageio.h), I 
haven't tried compiling it so I don't guarantee that I haven't made some 
ghastly error. But that's the gist of what you'd need to do.

        -- lg



On Jul 10, 2013, at 8:59 AM, Michel Lerenard wrote:

Hi,

I need to write images to the disk, and am facing a problem that seems so basic 
i'm wondering if I'm not missing something obvious.

I need to write specific channels to an image. For example, write UVW values 
next to RGBA 'standard' data.
Using directly OpenEXR, i would create the seven channels one after another and 
fill each channel with matching data. Our application (Clarisse IFx) stores 
data per channel so it would be pretty straigthforward.

I have seen no way using OIIO to do such a thing: there is no writeScanline 
function that would take start / end channels: i can't write data channel per 
channel.
The only thing I could do is build a huge interlaced buffer gathering all channels from 
my image and call "writeimage", but i fear it would use an horrible amount of 
memory and extra processing that seems unecessary.

Should I check the file format first and directly instanciate an EXROutput or 
TiffOutput when needed ? How could I set channel names ?


Thanks in advance for your help,

Michel
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
--
Larry Gritz
[email protected]


_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to