On 16-Feb-07, at 4:24 PM, Peter K. Stys wrote:

On 2/16/07, Frank Condello <[EMAIL PROTECTED]> wrote:
On 16-Feb-07, at 3:16 PM, Peter K. Stys wrote:

Now, I would still swap the whole block in this situation (or at
least the parts that need it) but do it using Ptr.Byte not
Memoryblock.ByteValue and you'll see a massive gain. Honestly though,
for large blocks like you're describing I'd do this sort of thing in
a plugin, which will be faster still. Once your block is swapped for
the current platform you can use fast Ptr access all the time without
worrying about endianess. You still need to pick an endianess and
stick to it for the file format however.

but if I pick a fixed endianness, the huge memblocks will always need
to be swapped on one of the platforms when the file is read. If the
endianness matches the current platform, then the swap will only be
required if the file is opened on the other platform (a far less
frequent event).

Right - you have two choices: a). Define the file format as always being either big or small - OR - b). Add a flag to the file format that tells the loader if it's big or small. You can't avoid swapping when things don't match up, you just have to deal with it.

Incidentally, can you change binStream.LittleEndian on-the-fly, while
the stream is open?

Yes (AFAIK) it's just a flag that the read/write methods check. Don't expect any magic from LittleEndian properties though - you can't set the flag then write out a big chunk of data and expect it to be correct. You have to use individual accessors (long, single etc.). LittleEndian doesn't change the underlying memory, it's only a hint to the accessor/read/write methods that certain return values should be swapped.

Also watch out for situations where a memoryblock returns a new block, 'cause its LittleEndian flag may not be in sync with the original's. E.g. m1 = m1+m2 will reset m1's LittleEndian flag (makes sense if you think about it but it's a common error).

Finally, there are even more subtle issues.  I create an RGB image
from raw pixel data by calling:

sourceMap = GetGWorldPixMap( (GWorldPtr) sourceDes.pictureData);
...
sourceData = (long*) GetPixBaseAddr( sourceMap );       // get the base addr
of pix data

then generate the 32 bit color (8 bits per color channel + alpha):

sourceData[sourceLineAddrOffset+xCtr] = (redColor << 16) | (grnColor
<< 8) | (bluColor);

where red/grn/bluColor vary from 0-255 depending on the pixel values.
Even tho numerically the pixel values are correct on Intel, the color
generated by the last statement is wrong: is that because
red/grn/bluColor are shifted into the wrong byte positions because of
Intel endianness (this was originally written for PPC)?

This could break many plugin operations that perform direct byte-wise
access of pointers.

Don't confuse pixel formats with endianess - these are related problems but not the same thing! The LittleEndian property is of little use unless you need to reverse a 4byte pixel wholesale: RGBA- >ABGR isn't a common operation. Often you just have to reverse the RGB byte order (RGBA->BGRA) or move the alpha byte to a different end (RGBA->ARGB) rather than swap everything.

Frank.
<http://developer.chaoticbox.com/>


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives:
<http://support.realsoftware.com/listarchives/lists.html>

Reply via email to