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

Eliot Miranda eliot.miranda at gmail.com
Thu Oct 11 21:41:44 UTC 2018


Hi Bert,
On Thu, Oct 11, 2018 at 11:28 AM Bert Freudenberg <bert at freudenbergs.de>
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 at 1 depth: 8.
f fill: (x at 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 at 1 depth: -8.
f fill: (x at 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 <eliot.miranda at gmail.com>
> 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 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
>>
>> *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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20181011/401cc840/attachment-0001.html>


More information about the Vm-dev mailing list