Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.1059.mcz
==================== Summary ====================
Name: Collections-nice.1059
Author: nice
Time: 8 February 2024, 12:57:43.861987 am
UUID: a61087ae-f9ac-4e43-89d1-837d3edb7493
Ancestors: Collections-mt.1058
Provide the ability to reverse the endianness of a RawBitsArray. Spur platforms are all little-endian so far, so this is for the case when we would want to exchange such an array in a big-endian format.
Example:
| w |
w := WordArray with: 16r01020304.
w reverseEndianness.
w first hex
Also provide the ability to access the underlying bytes of any collection of raw bits thru byteAt: and byteAt:put:, whatever the number of bytesPerBasicElement.
Examples:
| w b |
w := WordArray with: 16r01020304.
b := w copy changeClassTo: ByteArray.
1 to: 4 do: [:index |
self assert: (w byteAt: index) = (b byteAt: index)].
| w b |
w := WordArray with: 16r01020304.
b := w copy changeClassTo: ByteArray.
w byteAt: 3 put: 5.
b byteAt: 3 put: 5.
{w first hex. b}
This might be usefull for low level operations, like simulating a VM for example.
=============== Diff against Collections-mt.1058 ===============
Item was added:
+ ----- Method: RawBitsArray>>byteAt: (in category 'accessing') -----
+ byteAt: anIndex
+ "Access a byte of the receiver, considered as a raw sequence of bytes.
+ This is a memory efficient implementation of:
+ ((self copy changeClassTo: ByteArray) at: anIndex)"
+ | int mask stride index shift |
+ self class isBytes
+ ifTrue: [^ self basicAt: anIndex].
+ mask := 16rFF.
+ stride := self bytesPerBasicElement.
+ index := anIndex - 1 // stride + 1.
+ shift := anIndex - 1 \\ stride * -8.
+ Smalltalk isLittleEndian ifFalse: [shift := stride - 1 * 8 - shift].
+ int := self basicAt: index.
+ int := int bitShift: shift.
+ int := int bitAnd: mask.
+ ^int!
Item was added:
+ ----- Method: RawBitsArray>>byteAt:put: (in category 'accessing') -----
+ byteAt: anIndex put: aByte
+ "Modify a byte of the receiver, considered as a raw sequence of bytes.
+ This is a less scary implementation than:
+ ([:class | ((self changeClassTo: ByteArray) at: anIndex put: aByte) changeClassTo: class] value: self class)"
+ | int stride index shift mask |
+ self class isBytes
+ ifTrue: [^ self basicAt: anIndex put: aByte].
+ mask := 16rFF.
+ stride := self bytesPerBasicElement.
+ index := anIndex - 1 // stride + 1.
+ shift := anIndex - 1 \\ stride * 8.
+ Smalltalk isLittleEndian ifFalse: [shift := stride - 1 * 8 - shift].
+ int := self basicAt: index.
+ int := int bitClear: (mask bitShift: shift).
+ int := int bitOr: (aByte bitShift: shift).
+ self basicAt: index put: int.
+ ^aByte!
Item was added:
+ ----- Method: RawBitsArray>>reverseEndianness (in category 'converting') -----
+ reverseEndianness
+ "reverse the endianness for each element"
+
+ self class isBytes ifTrue: [^self].
+ self class isWords ifTrue: [^self swapWords].
+ self class isLongs ifTrue: [^self swapDoubleWords].
+ self class isShorts ifTrue: [^self swapDoubleBytes].
+ self error: 'this is not a collection of 1,2,4 or 8 bytes elements'!
Item was added:
+ ----- Method: RawBitsArray>>swap16pairs (in category 'private') -----
+ swap16pairs
+ "Swap every pair of double-bytes
+ Example: #[ 1 2 3 4 5 6 7 8 ] copy swap16pairs => #[ 3 4 1 2 7 8 5 6]
+ Implementation notes: this is the same as swapHalves, except that swapHalves only work for WordArray"
+
+ | hack blt |
+ "The implementation is a hack, but fast for large ranges"
+ hack := Form new hackBits: self.
+ blt := (BitBlt toForm: hack) sourceForm: hack.
+ blt combinationRule: Form reverse. "XOR"
+ blt sourceY: 0; destY: 0; height: self byteSize//4; width: 2.
+ blt sourceX: 0; destX: 2; copyBits. "Exchange double-bytes 0 and 1"
+ blt sourceX: 2; destX: 0; copyBits.
+ blt sourceX: 0; destX: 2; copyBits.!
Item was added:
+ ----- Method: RawBitsArray>>swap32pairs (in category 'private') -----
+ swap32pairs
+ "Swap every pair of words
+ Example: #[ 1 2 3 4 5 6 7 8 ] copy swap32pairs => #[ 5 6 7 8 1 2 3 4 ]"
+
+ | hack blt |
+ "The implementation is a hack, but fast for large ranges"
+ hack := Form new hackBits: self width: 8.
+ blt := (BitBlt toForm: hack) sourceForm: hack.
+ blt combinationRule: Form reverse. "XOR"
+ blt sourceY: 0; destY: 0; height: self byteSize//8; width: 4.
+ blt sourceX: 0; destX: 4; copyBits. "Exchange words 0 and 1"
+ blt sourceX: 4; destX: 0; copyBits.
+ blt sourceX: 0; destX: 4; copyBits.!
Item was added:
+ ----- Method: RawBitsArray>>swap8pairs (in category 'private') -----
+ swap8pairs
+ "Swap every pair of bytes
+ Example: #[ 1 2 3 4 5 6 ] copy swap8pairs => #[ 2 1 4 3 6 5 ]"
+
+ | hack blt |
+ "The implementation is a hack, but fast for large ranges"
+ hack := Form new hackBits: self.
+ blt := (BitBlt toForm: hack) sourceForm: hack.
+ blt combinationRule: Form reverse. "XOR"
+ blt sourceY: 0; destY: 0; height: self byteSize//4; width: 1.
+ blt sourceX: 0; destX: 1; copyBits. "Exchange bytes 0 and 1"
+ blt sourceX: 1; destX: 0; copyBits.
+ blt sourceX: 0; destX: 1; copyBits.
+ blt sourceX: 2; destX: 3; copyBits. "Exchange bytes 2 and 3"
+ blt sourceX: 3; destX: 2; copyBits.
+ blt sourceX: 2; destX: 3; copyBits.
+ self byteSize\\4 >= 2
+ ifTrue:
+ ["The lines in a From must fit on a Word boundary.
+ Handle the excess bytes"
+ | n tmp |
+ n := self byteSize // 4 * 4.
+ tmp := self byteAt: n + 1.
+ self byteAt: n + 1 put: (self byteAt: n + 2).
+ self byteAt: n + 2 put: tmp.]!
Item was added:
+ ----- Method: RawBitsArray>>swapDoubleBytes (in category 'private') -----
+ swapDoubleBytes
+ "Perform a bigEndian/littleEndian byte reversal of my double bytes.
+ Assume that our byte size is a multiple of souble byte size (2)
+ If it's not the case, trailing bytes would be left unchanged"
+
+ self swap8pairs!
Item was added:
+ ----- Method: RawBitsArray>>swapDoubleWords (in category 'private') -----
+ swapDoubleWords
+ "Perform a bigEndian/littleEndian byte reversal of my double words.
+ Assume that our byte size is a multiple of double word size (8)
+ If it's not the case, 4 trailing bytes might be altered"
+
+ self swap32pairs. "#[1 2 3 4 5 6 7 8] copy swap32pairs => #[5 6 7 8 1 2 3 4]"
+ self swapWords "#[5 6 7 8 1 2 3 4] copy swapWords => #[8 7 6 5 4 3 2 1]"!
Item was added:
+ ----- Method: RawBitsArray>>swapWords (in category 'private') -----
+ swapWords
+ "Perform a bigEndian/littleEndian byte reversal of my words.
+ Assume that our byte size is a multiple of word size (4)
+ If it's not the case, trailing bytes will remain unchanged"
+
+ | hack blt |
+ "The implementation is a hack, but fast for large ranges"
+ hack := Form new hackBits: self.
+ blt := (BitBlt toForm: hack) sourceForm: hack.
+ blt combinationRule: Form reverse. "XOR"
+ blt sourceY: 0; destY: 0; height: self byteSize//4; width: 1.
+ blt sourceX: 0; destX: 3; copyBits. "Exchange bytes 0 and 3"
+ blt sourceX: 3; destX: 0; copyBits.
+ blt sourceX: 0; destX: 3; copyBits.
+ blt sourceX: 2; destX: 1; copyBits. "Exchange bytes 1 and 2"
+ blt sourceX: 1; destX: 2; copyBits.
+ blt sourceX: 2; destX: 1; copyBits.!
Nicolas Cellier uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-nice.551.mcz
==================== Summary ====================
Name: Graphics-nice.551
Author: nice
Time: 27 February 2024, 11:04:54.187486 pm
UUID: 6687a9e4-2fa7-4981-8548-fa272b631eda
Ancestors: Graphics-mt.550, Graphics-nice.550
Merge Graphics-mt.550 & Graphics-nice.550
=============== Diff against Graphics-mt.550 ===============
Item was added:
+ ----- Method: Form>>hackBits:width: (in category 'private') -----
+ hackBits: bitThing width: anInteger
+ "This method provides an initialization so that BitBlt may be used, eg, to
+ copy ByteArrays and other non-pointer objects efficiently.
+ The resulting form looks anInteger wide, 8 bits deep, and height is adjusted to fit the bitThing size.
+ anInteger shall be a multiple of 4, because lines in a Form always fall on a Word boundary.
+ If not, some dead bytes will remain unaccessible to the BitBlt operations on each line.
+ That's also the case of trailing excess bytes"
+ width := anInteger.
+ depth := 8.
+ bitThing class isBits ifFalse: [self error: 'bitThing must be a non-pointer object'].
+ height := bitThing basicSize * bitThing bytesPerBasicElement // (width + 3 // 4 * 4).
+ bits := bitThing!
Nicolas Cellier uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-nice.550.mcz
==================== Summary ====================
Name: Graphics-nice.550
Author: nice
Time: 7 February 2024, 11:08:47.366987 pm
UUID: 9a845f0a-b60c-a740-93f9-d705b5b9b840
Ancestors: Graphics-mt.549
Provide a new Form hack of arbitrary width for bulk transfer of bytes.
This may be used for example for reversing the endianness of a DoubleWordArray.
=============== Diff against Graphics-mt.549 ===============
Item was added:
+ ----- Method: Form>>hackBits:width: (in category 'private') -----
+ hackBits: bitThing width: anInteger
+ "This method provides an initialization so that BitBlt may be used, eg, to
+ copy ByteArrays and other non-pointer objects efficiently.
+ The resulting form looks anInteger wide, 8 bits deep, and height is adjusted to fit the bitThing size.
+ anInteger shall be a multiple of 4, because lines in a Form always fall on a Word boundary.
+ If not, some dead bytes will remain unaccessible to the BitBlt operations on each line.
+ That's also the case of trailing excess bytes"
+ width := anInteger.
+ depth := 8.
+ bitThing class isBits ifFalse: [self error: 'bitThing must be a non-pointer object'].
+ height := bitThing basicSize * bitThing bytesPerBasicElement // (width + 3 // 4 * 4).
+ bits := bitThing!