Byte ordering in Form (urgent)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Byte ordering in Form (urgent)

Eliot Miranda-2
 
Hi All,

    in trying to fix a bug in BitBLT to do with accessing a word following a bitmap I have had to understand Form and BitBlt's extensions for handling multiple byte order.  In particular, if a Form has a negative depth its byte ordering is reversed w.r.t. a Form with positive depth.

But in examining this code I think I have found an inconsistency, and I urgently need to check my understanding.  In the Form and BitBlt code, a negative depth is stated to mean a Form whose bits are in little-endian byte order:

Form methods for accessing
depth
^ depth < 0 ifTrue:[0-depth] ifFalse:[depth]
nativeDepth
"Return the 'native' depth of the receiver, e.g., including the endianess"
^depth

Form methods for testing
isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0
isLittleEndian
"Return true if the receiver contains little endian pixels, meaning the left-most pixel is stored in the least significant bits of a word."
^depth < 0

and BitBltSimulation (the Smalltalk code for the plugin that implements BitBlt) has two instance variables destMSW and sourceMSW that are true if the destination form or source form has a positive depth:

BitBltSimulation methods for interpreter interface
loadBitBltDestForm
"Load the dest form for BitBlt. Answer false if anything is wrong, true otherwise."

... destDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: destForm.
destMSB := destDepth > 0.
destDepth < 0 ifTrue:
[destDepth := 0 - destDepth].
...
loadBitBltSourceForm
"Load the source form for BitBlt. Return false if anything is wrong, true otherwise."
...
sourceDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: sourceForm.
sourceMSB := sourceDepth > 0.
sourceDepth < 0 ifTrue:
[sourceDepth := 0 - sourceDepth].
...

But if I have a look at the actual layout of bytes in a Form I see that the meaning of depth is that if it is positive it is the *native* byte order (little endian on x86, x86-64, ARM, big end on SPARC, PowerPC):

Display fill: (0@0 extent: 1@100) rule: Form over fillColor: Color black.
(Display bits at: 1) hex '16rFF000001'

| bytes |
bytes := Display bits copy.
ByteArray adoptInstance: bytes.
bytes copyFrom: 1 to: 4 #[1 0 0 255]

i.e. the first word of the Display after writing the color black into the first 32-bit pixel is 16rFF000001 on Mac OS x86-64, or #[1 0 0 255] , which is little endian.

When the Squeak BttF VM was first written it was written on Motorola 68k Macs and PowerPC Macs, which are big-endian.  So it is natural that at the time the terms isBigEndian and isLittleEndian and destMSB sourceMSB were as they are now, because the platform was big endian.  But subsequently when the code was ported to Windows x86 by Andreas Raab, the meaning seems to me to have changed.  Now depth > 0 implies *native* byte order, not big endian byte order, and depth < 0 implies the *opposite of native* byte order, not little endian order.  Does anyone disagree?  Does anyone have corroborating or contradicting evidence?

I ask because to make sense of the code I would at least like to change the variables in BitBltSimulation to be destNativeByteOrder and sourceNativeByteOrder, and I want to either delete Form>>isBigEndian and Form>>isLittleEndian and replace it with Form>>isNativeByteOrder, or redefine isBigEndian and isLittleEndian, eg as

isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0 == Smalltalk isBigEndian

_,,,^..^,,,_
best, Eliot

Reply | Threaded
Open this post in threaded view
|

Re: Byte ordering in Form (urgent)

timrowledge
 


> On 2018-10-11, at 11:27 AM, Bert Freudenberg <[hidden email]> wrote:
>
> No, positive depth means big endian on all platforms.
>
> Until Andreas added little endian support to bitblt, everything was done in big endian, and only reversed on copying to the OS window. That byte reversal was expensive, so that's why the little endian support was added, to be able to keep forms in native order on little endian platforms. Little endian is indicated by negative depth, also in the platform support code (e.g. supportsDepth).

IIRC from far too long ago I concluded that the littleendian stuff Andreas added was very specifically Windows weird idea of littleendian, which involved some strange stuff for less than 32bpp forms. It certainly didn't work on RISC OS.


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- Calls people to ask them their phone number.


Reply | Threaded
Open this post in threaded view
|

Re: Byte ordering in Form (urgent)

Ronie Salgado
 
Hi Eliot,

I usually use depth: -32 for my stuff, because it corresponds with the common BGR_sRGB_A8_UNORM, which tends to be used commonly by the graphics cards.

Best regards,
Ronie

El jue., 11 oct. 2018 a las 15:34, tim Rowledge (<[hidden email]>) escribió:
 


> On 2018-10-11, at 11:27 AM, Bert Freudenberg <[hidden email]> wrote:
>
> No, positive depth means big endian on all platforms.
>
> Until Andreas added little endian support to bitblt, everything was done in big endian, and only reversed on copying to the OS window. That byte reversal was expensive, so that's why the little endian support was added, to be able to keep forms in native order on little endian platforms. Little endian is indicated by negative depth, also in the platform support code (e.g. supportsDepth).

IIRC from far too long ago I concluded that the littleendian stuff Andreas added was very specifically Windows weird idea of littleendian, which involved some strange stuff for less than 32bpp forms. It certainly didn't work on RISC OS.


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- Calls people to ask them their phone number.


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Byte ordering in Form (urgent)

Eliot Miranda-2
In reply to this post by Eliot Miranda-2
 
Hi Bert,
On Thu, Oct 11, 2018 at 11:28 AM Bert Freudenberg <[hidden email]> wrote:
No, positive depth means big endian on all platforms.

Until Andreas added little endian support to bitblt, everything was done in big endian, and only reversed on copying to the OS window. That byte reversal was expensive, so that's why the little endian support was added, to be able to keep forms in native order on little endian platforms. Little endian is indicated by negative depth, also in the platform support code (e.g. supportsDepth).

Thanks!  I've constructed an example that shows this to me:

(0 to: 3) collect: [:x| | f |
f := Form extent: 4@1 depth: 8.
f fill: (x@0 corner: f extent) rule: Form over fillColor: Color white.
ByteArray adoptInstance: f bits.
f bits] #(#[255 255 255 255 0 0 0 0] #[255 255 255 0 0 0 0 0] #[255 255 0 0 0 0 0 0] #[255 0 0 0 0 0 0 0])
(0 to: 3) collect: [:x| | f |
f := Form extent: 4@1 depth: -8.
f fill: (x@0 corner: f extent) rule: Form over fillColor: Color white.
ByteArray adoptInstance: f bits.
f bits] #(#[255 255 255 255 0 0 0 0] #[0 255 255 255 0 0 0 0] #[0 0 255 255 0 0 0 0] #[0 0 0 255 0 0 0 0])


- Bert -

On Thu, Oct 11, 2018 at 11:14 AM Eliot Miranda <[hidden email]> wrote:
 
Hi All,

    in trying to fix a bug in BitBLT to do with accessing a word following a bitmap I have had to understand Form and BitBlt's extensions for handling multiple byte order.  In particular, if a Form has a negative depth its byte ordering is reversed w.r.t. a Form with positive depth.

But in examining this code I think I have found an inconsistency, and I urgently need to check my understanding.  In the Form and BitBlt code, a negative depth is stated to mean a Form whose bits are in little-endian byte order:

Form methods for accessing
depth
^ depth < 0 ifTrue:[0-depth] ifFalse:[depth]
nativeDepth
"Return the 'native' depth of the receiver, e.g., including the endianess"
^depth

Form methods for testing
isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0
isLittleEndian
"Return true if the receiver contains little endian pixels, meaning the left-most pixel is stored in the least significant bits of a word."
^depth < 0

and BitBltSimulation (the Smalltalk code for the plugin that implements BitBlt) has two instance variables destMSW and sourceMSW that are true if the destination form or source form has a positive depth:

BitBltSimulation methods for interpreter interface
loadBitBltDestForm
"Load the dest form for BitBlt. Answer false if anything is wrong, true otherwise."

... destDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: destForm.
destMSB := destDepth > 0.
destDepth < 0 ifTrue:
[destDepth := 0 - destDepth].
...
loadBitBltSourceForm
"Load the source form for BitBlt. Return false if anything is wrong, true otherwise."
...
sourceDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: sourceForm.
sourceMSB := sourceDepth > 0.
sourceDepth < 0 ifTrue:
[sourceDepth := 0 - sourceDepth].
...

But if I have a look at the actual layout of bytes in a Form I see that the meaning of depth is that if it is positive it is the *native* byte order (little endian on x86, x86-64, ARM, big end on SPARC, PowerPC):

Display fill: (0@0 extent: 1@100) rule: Form over fillColor: Color black.
(Display bits at: 1) hex '16rFF000001'

| bytes |
bytes := Display bits copy.
ByteArray adoptInstance: bytes.
bytes copyFrom: 1 to: 4 #[1 0 0 255]

i.e. the first word of the Display after writing the color black into the first 32-bit pixel is 16rFF000001 on Mac OS x86-64, or #[1 0 0 255] , which is little endian.

When the Squeak BttF VM was first written it was written on Motorola 68k Macs and PowerPC Macs, which are big-endian.  So it is natural that at the time the terms isBigEndian and isLittleEndian and destMSB sourceMSB were as they are now, because the platform was big endian.  But subsequently when the code was ported to Windows x86 by Andreas Raab, the meaning seems to me to have changed.  Now depth > 0 implies *native* byte order, not big endian byte order, and depth < 0 implies the *opposite of native* byte order, not little endian order.  Does anyone disagree?  Does anyone have corroborating or contradicting evidence?

I ask because to make sense of the code I would at least like to change the variables in BitBltSimulation to be destNativeByteOrder and sourceNativeByteOrder, and I want to either delete Form>>isBigEndian and Form>>isLittleEndian and replace it with Form>>isNativeByteOrder, or redefine isBigEndian and isLittleEndian, eg as

isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0 == Smalltalk isBigEndian

_,,,^..^,,,_
best, Eliot




--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Byte ordering in Form (urgent)

Eliot Miranda-2
 


On Thu, Oct 11, 2018 at 2:41 PM Eliot Miranda <[hidden email]> wrote:
Hi Bert,
On Thu, Oct 11, 2018 at 11:28 AM Bert Freudenberg <[hidden email]> wrote:
No, positive depth means big endian on all platforms.

Until Andreas added little endian support to bitblt, everything was done in big endian, and only reversed on copying to the OS window. That byte reversal was expensive, so that's why the little endian support was added, to be able to keep forms in native order on little endian platforms. Little endian is indicated by negative depth, also in the platform support code (e.g. supportsDepth).

Thanks!  I've constructed an example that shows this to me:

(0 to: 3) collect: [:x| | f |
f := Form extent: 4@1 depth: 8.
f fill: (x@0 corner: f extent) rule: Form over fillColor: Color white.
ByteArray adoptInstance: f bits.
f bits] #(#[255 255 255 255 0 0 0 0] #[255 255 255 0 0 0 0 0] #[255 255 0 0 0 0 0 0] #[255 0 0 0 0 0 0 0])
(0 to: 3) collect: [:x| | f |
f := Form extent: 4@1 depth: -8.
f fill: (x@0 corner: f extent) rule: Form over fillColor: Color white.
ByteArray adoptInstance: f bits.
f bits] #(#[255 255 255 255 0 0 0 0] #[0 255 255 255 0 0 0 0] #[0 0 255 255 0 0 0 0] #[0 0 0 255 0 0 0 0])

and revealed a bug in Spur's adoptInstance: code on 64-bits...
 


- Bert -

On Thu, Oct 11, 2018 at 11:14 AM Eliot Miranda <[hidden email]> wrote:
 
Hi All,

    in trying to fix a bug in BitBLT to do with accessing a word following a bitmap I have had to understand Form and BitBlt's extensions for handling multiple byte order.  In particular, if a Form has a negative depth its byte ordering is reversed w.r.t. a Form with positive depth.

But in examining this code I think I have found an inconsistency, and I urgently need to check my understanding.  In the Form and BitBlt code, a negative depth is stated to mean a Form whose bits are in little-endian byte order:

Form methods for accessing
depth
^ depth < 0 ifTrue:[0-depth] ifFalse:[depth]
nativeDepth
"Return the 'native' depth of the receiver, e.g., including the endianess"
^depth

Form methods for testing
isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0
isLittleEndian
"Return true if the receiver contains little endian pixels, meaning the left-most pixel is stored in the least significant bits of a word."
^depth < 0

and BitBltSimulation (the Smalltalk code for the plugin that implements BitBlt) has two instance variables destMSW and sourceMSW that are true if the destination form or source form has a positive depth:

BitBltSimulation methods for interpreter interface
loadBitBltDestForm
"Load the dest form for BitBlt. Answer false if anything is wrong, true otherwise."

... destDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: destForm.
destMSB := destDepth > 0.
destDepth < 0 ifTrue:
[destDepth := 0 - destDepth].
...
loadBitBltSourceForm
"Load the source form for BitBlt. Return false if anything is wrong, true otherwise."
...
sourceDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject: sourceForm.
sourceMSB := sourceDepth > 0.
sourceDepth < 0 ifTrue:
[sourceDepth := 0 - sourceDepth].
...

But if I have a look at the actual layout of bytes in a Form I see that the meaning of depth is that if it is positive it is the *native* byte order (little endian on x86, x86-64, ARM, big end on SPARC, PowerPC):

Display fill: (0@0 extent: 1@100) rule: Form over fillColor: Color black.
(Display bits at: 1) hex '16rFF000001'

| bytes |
bytes := Display bits copy.
ByteArray adoptInstance: bytes.
bytes copyFrom: 1 to: 4 #[1 0 0 255]

i.e. the first word of the Display after writing the color black into the first 32-bit pixel is 16rFF000001 on Mac OS x86-64, or #[1 0 0 255] , which is little endian.

When the Squeak BttF VM was first written it was written on Motorola 68k Macs and PowerPC Macs, which are big-endian.  So it is natural that at the time the terms isBigEndian and isLittleEndian and destMSB sourceMSB were as they are now, because the platform was big endian.  But subsequently when the code was ported to Windows x86 by Andreas Raab, the meaning seems to me to have changed.  Now depth > 0 implies *native* byte order, not big endian byte order, and depth < 0 implies the *opposite of native* byte order, not little endian order.  Does anyone disagree?  Does anyone have corroborating or contradicting evidence?

I ask because to make sense of the code I would at least like to change the variables in BitBltSimulation to be destNativeByteOrder and sourceNativeByteOrder, and I want to either delete Form>>isBigEndian and Form>>isLittleEndian and replace it with Form>>isNativeByteOrder, or redefine isBigEndian and isLittleEndian, eg as

isBigEndian
"Return true if the receiver contains big endian pixels, meaning the left-most pixel is stored in the most significant bits of a word."
^depth > 0 == Smalltalk isBigEndian

_,,,^..^,,,_
best, Eliot




--
_,,,^..^,,,_
best, Eliot


--
_,,,^..^,,,_
best, Eliot