'From Squeak3.10.2 of ''5 June 2008'' [latest update: #7179] on 26 October 2009 at 9:25:13 am'!
!BitBltSimulation methodsFor: 'combination rules' stamp: 'jmv 10/26/2009 08:58'!
partitionedAdd: word1 to: word2 nBits: nBits nPartitions: nParts
"Add word1 to word2 as nParts partitions of nBits each.
This is useful for packed pixels, or packed colors"
| mask sum result maskedWord1 |
"In C, most aritmethic operarions answer the same bit pattern regardless of the operands being signed or unsigned ints
(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
words as unsigned int in those cases where comparisions are done (jmv)"
self var: #word1 type: 'unsigned int'.
self var: #word2 type: 'unsigned int'.
self var: #mask type: 'unsigned int'.
self var: #sum type: 'unsigned int'.
self var: #result type: 'unsigned int'.
self var: #maskedWord1 type: 'unsigned int'.
mask := maskTable at: nBits. "partition mask starts at the right"
result := 0.
1 to: nParts do:
[:i |
maskedWord1 := word1 bitAnd: mask.
sum := maskedWord1 + (word2 bitAnd: mask).
(sum <= mask "result must not carry out of partition"
and: [ sum >= maskedWord1 ]) "This is needed because in C, integer aritmethic overflows silently!! (jmv)"
ifTrue: [result := result bitOr: sum]
ifFalse: [result := result bitOr: mask].
mask := mask << nBits "slide left to next partition"].
^ result
! !
!BitBltSimulation methodsFor: 'combination rules' stamp: 'jmv 10/26/2009 08:59'!
partitionedMax: word1 with: word2 nBits: nBits nPartitions: nParts
"Max word1 to word2 as nParts partitions of nBits each"
| mask result |
"In C, most aritmethic operarions answer the same bit pattern regardless of the operands being signed or unsigned ints
(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
words as unsigned int in those cases where comparisions are done (jmv)"
self var: #word1 type: 'unsigned int'.
self var: #word2 type: 'unsigned int'.
self var: #mask type: 'unsigned int'.
self var: #result type: 'unsigned int'.
mask := maskTable at: nBits. "partition mask starts at the right"
result := 0.
1 to: nParts do:
[:i |
result := result bitOr: ((word2 bitAnd: mask) max: (word1 bitAnd: mask)).
mask := mask << nBits "slide left to next partition"].
^ result
! !
!BitBltSimulation methodsFor: 'combination rules' stamp: 'jmv 10/26/2009 08:59'!
partitionedMin: word1 with: word2 nBits: nBits nPartitions: nParts
"Min word1 to word2 as nParts partitions of nBits each"
| mask result |
"In C, most aritmethic operarions answer the same bit pattern regardless of the operands being signed or unsigned ints
(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
words as unsigned int in those cases where comparisions are done (jmv)"
self var: #word1 type: 'unsigned int'.
self var: #word2 type: 'unsigned int'.
self var: #mask type: 'unsigned int'.
self var: #result type: 'unsigned int'.
mask := maskTable at: nBits. "partition mask starts at the right"
result := 0.
1 to: nParts do:
[:i |
result := result bitOr: ((word2 bitAnd: mask) min: (word1 bitAnd: mask)).
mask := mask << nBits "slide left to next partition"].
^ result
! !
!BitBltSimulation methodsFor: 'combination rules' stamp: 'jmv 10/26/2009 09:01'!
partitionedMul: word1 with: word2 nBits: nBits nPartitions: nParts
"Multiply word1 with word2 as nParts partitions of nBits each.
This is useful for packed pixels, or packed colors.
Bug in loop version when non-white background"
| sMask product result dMask |
"In C, integer multiplication might answer a wrong value if the unsigned values are declared as signed.
This problem does not affect this method, because the most significant bit (i.e. the sign bit) will
always be zero (jmv)"
sMask := maskTable at: nBits. "partition mask starts at the right"
dMask := sMask << nBits.
result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1
bitAnd: dMask) >> nBits. "optimized first step"
nParts = 1
ifTrue: [ ^result ].
product := (((word1>>nBits bitAnd: sMask)+1) * ((word2>>nBits bitAnd: sMask)+1) - 1 bitAnd: dMask).
result := result bitOr: product.
nParts = 2
ifTrue: [ ^result ].
product := (((word1>>(2*nBits) bitAnd: sMask)+1) * ((word2>>(2*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).
result := result bitOr: product << nBits.
nParts = 3
ifTrue: [ ^result ].
product := (((word1>>(3*nBits) bitAnd: sMask)+1) * ((word2>>(3*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).
result := result bitOr: product << (2*nBits).
^ result
" | sMask product result dMask |
sMask := maskTable at: nBits. 'partition mask starts at the right'
dMask := sMask << nBits.
result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1
bitAnd: dMask) >> nBits. 'optimized first step'
nBits to: nBits * (nParts-1) by: nBits do: [:ofs |
product := (((word1>>ofs bitAnd: sMask)+1) * ((word2>>ofs bitAnd: sMask)+1) - 1 bitAnd: dMask).
result := result bitOr: (product bitAnd: dMask) << (ofs-nBits)].
^ result"! !
!BitBltSimulation methodsFor: 'combination rules' stamp: 'jmv 10/26/2009 08:59'!
partitionedSub: word1 from: word2 nBits: nBits nPartitions: nParts
"Subtract word1 from word2 as nParts partitions of nBits each.
This is useful for packed pixels, or packed colors"
| mask result p1 p2 |
"In C, most aritmethic operarions answer the same bit pattern regardless of the operands being signed or unsigned ints
(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
words as unsigned int in those cases where comparisions are done (jmv)"
self var: #word1 type: 'unsigned int'.
self var: #word2 type: 'unsigned int'.
self var: #p1 type: 'unsigned int'.
self var: #p2 type: 'unsigned int'.
self var: #mask type: 'unsigned int'.
self var: #result type: 'unsigned int'.
mask := maskTable at: nBits. "partition mask starts at the right"
result := 0.
1 to: nParts do:
[:i |
p1 := word1 bitAnd: mask.
p2 := word2 bitAnd: mask.
p1 < p2 "result is really abs value of thedifference"
ifTrue: [result := result bitOr: p2 - p1]
ifFalse: [result := result bitOr: p1 - p2].
mask := mask << nBits "slide left to next partition"].
^ result
! !