openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openexr-devel] Writing a tiled Rgba image file with tiles given


From: Werner Benger
Subject: Re: [Openexr-devel] Writing a tiled Rgba image file with tiles given
Date: Thu, 05 Mar 2009 16:31:08 -0500
User-agent: Opera Mail/9.64 (Win32)

Hi Florian,

 I was aware the sent in code was not comprehensive, but that could be
easily expanded, I can send in that code if it's of interest to be
added to the library. It seemed the underlying layer would just provide
some functionality that some higher-level API did not pass through.
Would easily fix those pointer arithmetic issues. This might also be
related to some other issue that I faced:

I had some problems with what I thought would be taken care of by
setting INCREASING_Y vs. DECREASING_Y in the header. I had expected
it to turn upside down an image, but neither exrdisplay, Photoshop
nor Irfanview did show a difference there. Instead, I'm setting up
the frame buffer with a call like this:

vector<Rgba> Pixels;
TiledRgbaOutputFile *Outfile;
        ...
        Outfile->setFrameBuffer(&*Pixels.begin()+
                                tileXSize*tileYSize-1,
                                1,                      // xStride
                                -tileXSize,             // yStride
                                true                    // the pixels buffer is 
relative
                                );



So it begins with the last row and advances backwards to the first
row. Is this the right way to do it? How would it be different from
INCREASING_Y vs. DECREASING_Y ?

Cheers,
        Werner



On Wed, 04 Mar 2009 14:54:46 -0500, Florian Kainz <address@hidden> wrote:

Hi Kevin,

I would agree with your statement about this being more of a
theoretical concern.  I don't know of any examples where the
pointer arithmetic for addressing pixels in the frame buffer
fails in practice.

As long as a C/C++ program runs in an environment that presents
applications with a linear address space, I don't see what kind
of compiler optimizations could affect the outcome of pointer
arithmetic.  At the machine code level pointers are just unsigned
integers with enough bits to uniquely identify any location in
the address space.  Adding to or subtracting from such an integer
always produces another integer, even though interpreting that
integer as a pointer may not yield the address of a valid object.

With large images it is possible that computing the base pointer
for setFrameBuffer produces a negative address.  However, actual
hardware performs unsigned integer arithmetic modulo 2^32 or 2^64
such that negative addresses wrap around to a large positive ones.
Later, the address calculations during during pixel reads or writes
will wrap around the other way and produce valid pointers to pixels.

It is true that the code relies on properties of pointer arithmetic
that are not guaranteed by the C++ standard.  But then, the
implementation of the "half" data type also relies on features
of the C++ implementation that are not guaranteed by the standard.

The C++ standard states that the results of certain pointer
subtractions and pointer comparisons are "unspecified."
As far as I know there are two reasons for this: first, the
relative memory addresses of objects that are not part of
the same struct or array are not known ahead of time.  The
addresses may even be different in different runs of the
program.  Second, in segmented memory architectures pointers
are (segment id, offset) pairs.  Subtracting two pointers with
different segment ids doesn't produce anything meaningful.
On the other hand, if the implementation of a segmented memory
pointer represents the segment id and the offset as bit fields
in a large integer, with the offset in the low-order bits, then
the setFrameBuffer pointer arithmetic would still work.

Florian



Kevin Wheatley wrote:
Florian Kainz wrote:
memory location where pixel (0,0) would be if it existed.  If your
buffer contains only a single tile, and that tile does not include
pixel (0,0), then the base pointer just points outside the buffer.
This may seem weird, but it works.  For a more detailed explanation
 it is also relying on implementation defined/undefined behaviour in
the language standard - subtracting from the pointer results in a
location outside an allocated block of memory (give or take the one
past the end allowance) could result in all sorts of weird behaviour
depending on implementation by the compiler vendor.
 I imagine on embedded systems your more likely to get problems or on
platforms where the address of the allocated memory block has a
smaller value vs the offset to base memory that the calculation
results in. This on some platforms could result in a calculation that
wraps to a very large memory address which could generare traps or
exceptions.
 But this is a 'theory' rather than 'practice' statement on most
desktop platforms of course :-)
 Kevin





--
___________________________________________________________________________
Dr. Werner Benger <address@hidden>               Visualization Research
Laboratory for Creative Arts and Technology (LCAT)
Center for Computation & Technology at Louisiana State University (CCT/LSU)
239 Johnston Hall, Baton Rouge, Louisiana 70803
Tel.: +1 225 578 4809                        Fax.: +1 225 578-5362




reply via email to

[Prev in Thread] Current Thread [Next in Thread]