The question is what happens when an image that has different "data" and 
"display" windows is output to an image file type that does not support that 
concept.  Does it write the pixels (data) as the whole image and lose the 
metadata about the display window, or does it consider the display window 
sacrosanct and crop and/or pad the pixel data to conform?  And at what level of 
abstraction should this logic live?

OK, here is what I hope will be the final word on the matter:

I think that high-level classes and apps that deal with the level of 
abstraction of entire images (e.g., ImageBuf, oiiotool) ought to provide simple 
API commands and facilities that will crop/pad the data to match the display 
window.  I can accept that this should perhaps be the default behavior when 
outputting to a file format that doesn't support the distinction.

But I think that low-level ImageOutput (individual format writers) should write 
precisely the pixels they get from the app; no more, no less.  I have two 
reasons for this:

1. Philosophical: This level of abstraction is meant to hide the details of 
individual format library APIs (TIFFfoo() versus JPEGbar() versus ImfBlah()), 
but is not supposed to abstract entire images or their semantics.  In other 
words, an app hands a pile of pixels to an ImageOutput, and expects those 
pixels to be written, without being overly clever.

2. Practical: Consider briefly the logistics of handling this automatically in 
an ImageOutput.  Let's say the display window is (0,0)-(1023,1023), the data 
window is (3,3)-(34,34), and the image is tiled with 16x16 tiles. Now, from the 
app's point of view, it needs to call write_tile() four times, once for each 
tile, which are by definition always aligned to the data window.  Upon the 
first write_tile() call, what does the ImageOutput do?  Well, if it is to pad 
automatically, then the output image's tiles start at 0, not at 3, so it needs 
to "re-tile" on the fly -- what it really needs to do is split that "app tile" 
appropriately to the 4 "output tiles", 3 of which can't be output then, since 
they overlap with other app tiles not yet received, so the ImageOutput would 
have to buffer those pending tiles, ugh.  Basically, it's a nightmare, would 
make hard-to-follow (and probably buggy) code, and have a lot of the tricky 
bits replicated across many different ImageOutput subclass
 es. No way.


So, to recap, the only practicable solution I see is:

a) ImageOutputs write pixels they are sent, as they currently do (no change 
needed).

b) But the ImageOutput::supports() method can be extended to allow the app to 
query if the image format supports separate display/data windows.  Proposed 
syntax:  supports("displaywindow")

c) Add a simple, single utility function to handle the auto crop/pad:

        ImageBufAlgo::FixToDisplayWindow (ImageBuf &img, const std::string 
&format)

   If the named format does not support display windows (or unconditionally, if 
format == ""),
   pad and/or crop the image so that its pixel data window exactly fills the 
display window.
   Padding is black, unless img's ImageSpec contains metadata 
"oiio:bordercolor" 
   (of type float[nchans]) specifying a different border color to use for 
pixels beyond the
   data window.

d) Change the default behavior of oiiotool and other image-writing utilities to 
call this when writing images.


Comments?

        -- lg


On Oct 17, 2011, at 9:50 PM, Will Rosecrans wrote:

> On Mon, Oct 17, 2011 at 8:48 PM, Larry Gritz <[email protected]> wrote:
>> The higher-level tools (iconvert, oiiotool) are another story entirely, and
>> I'm willing to bow to common sense, consensus, or precedent of other apps.
>>  The two cases we care about are when the input image (a) has a data window
>> smaller than the display window (a crop window) or (b) has a data window
>> larger than the display window (overscan regions), but the output image
>> format does not support these notions at all (e.g. JPEG).  What should
>> happen?  What do other programs do?
>> Hugh implies that Shake would pad with some black (or some kind of settable
>> background color?), or crop to the display window.  Do you agree?
>> Anybody familiar enough with Nuke to know what it does in these
>> circumstances?
>> Jeremy, do you have an opinion on any of this?
>> -- lg
>> 
> 
> If rendering something in nuke where the internal "data window" is
> smaller than the "display window" to a format the doesn't have such
> concepts, it will render a result that is the size of the "display
> window." which is basically the data surrounded by black.  It's
> actually a bit more complicated than that because nuke wants to repeat
> edge pixels, but a crop node defaults to adding a one pixel black
> border around the cropped area (just outside the display window, so
> the resulting so that you edge-repeat the black border in the
> undefined space.)  If rendering to EXR, nuke will correctly preserve
> the windows.  I don't think nuke has a ngcolor in the sense that Shake
> did.
> 
> In nuke-speak, you use a crop node to set the data window, and a
> reformat node to set the display window.  You can also reformat in a
> crop node to do both at once.  But, if you have the black border
> enabled when you reformat while you crop, the resulting data and
> display windows are not identical.  The data window extends one pixel
> past the display window in each direction for the invisible black
> border.  (This works fairly well in practice, despite being oddly
> complicated to explain nuke's behavior, you seldom have to think about
> it very explicitly.)
> 
> In Shakespeak, the Crop node set the display window, and a setDOD node
> set the data window, basically.  It was simpler in Shake.
> 
> When rendering an EXR out of nuke where the display window is smaller
> than the data window, Compressor on Mac OS X will try to interpret the
> EXR in terms of the data window.  The rule seems to be based on
> 'whichever is bigger.'  The result is a QuickTime movie made from an
> EXR sequence that is physically larger than expected, and has
> unexpected stuff visible in it, and a very confused and angry editor.
> I consider the Compressor behavior to be incorrect, and I have never
> desired it.
> 
> Basically, if I am making images where the data window matters, I'll
> keep strictly within the realm of tools and formats that maintain the
> distinction.  If I need to use a tool that doesn't understand the data
> window, then I'll change my settings in the originating tool to make
> my images unambiguous.  Efforts by intermediate tools to care about
> the data window in formats that don't understand it have never turned
> out useful to me.  They should just use the display window, IMHO.
> _______________________________________________
> 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

Reply via email to