I agree with everything up to c.  d should be optional, either do or don't I 
wouldn't care but it would be nice to NOT crop if you don't want to - though I 
imagine this was quietly implied.

cheers
--
Colin Doncaster
Peregrine Labs
http://peregrinelabs.com

On 2011-10-19, at 2:34 AM, Larry Gritz wrote:

> 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

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

Reply via email to