[Vm-dev] Byte ordering in Form (urgent)

Eliot Miranda eliot.miranda at gmail.com
Thu Oct 11 18:14:15 UTC 2018

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 < 0 ifTrue:[0-depth] ifFalse:[depth]
"Return the 'native' depth of the receiver, e.g., including the endianess"

*Form methods for testing*
"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
"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*
"Load the dest form for BitBlt. Answer false if anything is wrong, true

... destDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject:
destMSB := destDepth > 0.
destDepth < 0 ifTrue:
[destDepth := 0 - destDepth].
"Load the source form for BitBlt. Return false if anything is wrong, true
sourceDepth := interpreterProxy fetchInteger: FormDepthIndex ofObject:
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 at 0 extent: 1 at 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

"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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20181011/4f777451/attachment.html>

More information about the Vm-dev mailing list