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

Eliot Miranda eliot.miranda at gmail.com
Fri Oct 12 04:40:09 UTC 2018


On Thu, Oct 11, 2018 at 2:41 PM Eliot Miranda <eliot.miranda at gmail.com>
wrote:

> 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])
>

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


>
>
> - 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
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20181011/41f5ac42/attachment-0001.html>


More information about the Vm-dev mailing list