Nicolas Cellier uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2909.mcz ==================== Summary ==================== Name: VMMaker.oscog-nice.2909 Author: nice Time: 23 December 2020, 9:54:51.201058 pm UUID: 6869c4f1-9d80-40c3-8409-7c05e087edf5 Ancestors: VMMaker.oscog-eem.2908 WIP: implement new BitBlt ops (rules) for alpha compositing "42" alphaScale:with: "43" alphaUnscale:with: "44" alphaBlendUnscaled:with: This is a proposal implementation for https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/505 The generated C code compiles, but it's otherwise mostly yet unused and untested code. I commit it before I loose it. There's probably more to do for letting accelerated code work (PI). =============== Diff against VMMaker.oscog-eem.2908 =============== Item was changed: SmartSyntaxInterpreterPlugin subclass: #BitBltSimulation instanceVariableNames: 'destForm sourceForm halftoneForm combinationRule destX destY width height sourceX sourceY clipX clipY clipWidth clipHeight sourceWidth sourceHeight sourceDepth sourcePitch sourceBits sourcePPW sourceMSB destWidth destHeight destDepth destPitch destBits destPPW destMSB bitCount skew mask1 mask2 preload nWords destMask hDir vDir sourceIndex sourceDelta destIndex destDelta sx sy dx dy bbW bbH halftoneHeight noSource noHalftone halftoneBase sourceAlpha srcBitShift dstBitShift bitBltOop affectedL affectedR affectedT affectedB opTable maskTable ditherMatrix4x4 ditherThresholds16 ditherValues16 hasSurfaceLock warpSrcShift warpSrcMask warpAlignShift warpAlignMask warpBitShiftTable querySurfaceFn lockSurfaceFn unlockSurfaceFn isWarping cmFlags cmMask cmShiftTable cmMaskTable cmLookupTable cmBitsPerColor dither8Lookup componentAlphaModeColor componentAlphaModeAlpha ungammaLookupTable gammaLookupTable numGCsOnInvocation bitBltIsReceiver endOfDestination endOfSource' classVariableNames: 'AllOnes AlphaIndex BBClipHeightIndex BBClipWidthIndex BBClipXIndex BBClipYIndex BBColorMapIndex BBDestFormIndex BBDestXIndex BBDestYIndex BBHalftoneFormIndex BBHeightIndex BBLastIndex BBRuleIndex BBSourceFormIndex BBSourceXIndex BBSourceYIndex BBWarpBase BBWidthIndex BBXTableIndex BEBitBltIndex BinaryPoint BlueIndex ColorMapFixedPart ColorMapIndexedPart ColorMapNewStyle ColorMapPresent CrossedX EndOfRun FixedPt1 FormBitsIndex FormDepthIndex FormHeightIndex FormWidthIndex GreenIndex OpTable OpTableSize RedIndex' poolDictionaries: '' category: 'VMMaker-Interpreter'! + !BitBltSimulation commentStamp: 'nice 10/31/2020 23:39' prior: 0! - !BitBltSimulation commentStamp: 'tpr 3/25/2013 16:50' prior: 0! This class implements BitBlt, much as specified in the Blue Book spec. Performance has been enhanced through the use of pointer variables such as sourceIndex and destIndex, and by separating several special cases of the inner loop. Operation has been extended to color, with support for 1, 2, 4, 8, 16, and 32-bit pixel sizes. Conversion between different pixel sizes is facilitated by accepting an optional color map. In addition to the original 16 combination rules, this BitBlt supports 16 fail (for old paint mode) 17 fail (for old mask mode) 18 sourceWord + destinationWord 19 sourceWord - destinationWord 20 rgbAdd: sourceWord with: destinationWord 21 rgbSub: sourceWord with: destinationWord 22 OLDrgbDiff: sourceWord with: destinationWord 23 OLDtallyIntoMap: destinationWord -- old vers doesn't clip to bit boundary 24 alphaBlend: sourceWord with: destinationWord 25 pixPaint: sourceWord with: destinationWord 26 pixMask: sourceWord with: destinationWord 27 rgbMax: sourceWord with: destinationWord 28 rgbMin: sourceWord with: destinationWord 29 rgbMin: sourceWord bitInvert32 with: destinationWord 30 alphaBlendConst: sourceWord with: destinationWord -- alpha passed as an arg 31 alphaPaintConst: sourceWord with: destinationWord -- alpha passed as an arg 32 rgbDiff: sourceWord with: destinationWord 33 tallyIntoMap: destinationWord 34 alphaBlendScaled: sourceWord with: destinationWord 35 alphaBlendScaled: sourceWord with: "unused here - only used by FXBlt" 36 alphaBlendScaled: sourceWord with: "unused here - only used by FXBlt" 37 rgbMul: sourceWord with: destinationWord 38 pixSwap: sourceWord with: destinationWord 39 pixClear: sourceWord with: destinationWord 40 fixAlpha: sourceWord with: destinationWord 41 rgbComponentAlpha: sourceWord with: destinationWord + 42 alphaScale: ignoredSourceWord with: destinationWord + 43 alphaUnscale: ignoredSourceWord with: destinationWord + 44 alphaBlendUnscaled: sourceWord with: destinationWord This implementation has also been fitted with an experimental "warp drive" that allows abritrary scaling and rotation (and even limited affine deformations) with all BitBlt storage modes supported. To add a new rule to BitBlt... 1. add the new rule method or methods in the category 'combination rules' of BBSim 2. describe it in the class comment of BBSim and in the class comment for BitBlt 3. add refs to initializeRuleTable in proper positions 4. add refs to initBBOpTable, following the pattern ! Item was changed: ----- Method: BitBltSimulation class>>initializeRuleTable (in category 'initialization') ----- initializeRuleTable "BitBltSimulation initializeRuleTable" "**WARNING** You MUST change initBBOpTable if you change this" OpTable := #( "0" clearWord:with: "1" bitAnd:with: "2" bitAndInvert:with: "3" sourceWord:with: "4" bitInvertAnd:with: "5" destinationWord:with: "6" bitXor:with: "7" bitOr:with: "8" bitInvertAndInvert:with: "9" bitInvertXor:with: "10" bitInvertDestination:with: "11" bitOrInvert:with: "12" bitInvertSource:with: "13" bitInvertOr:with: "14" bitInvertOrInvert:with: "15" destinationWord:with: "16" destinationWord:with: "unused - was old paint" "17" destinationWord:with: "unused - was old mask" "18" addWord:with: "19" subWord:with: "20" rgbAdd:with: "21" rgbSub:with: "22" OLDrgbDiff:with: "23" OLDtallyIntoMap:with: "24" alphaBlend:with: "25" pixPaint:with: "26" pixMask:with: "27" rgbMax:with: "28" rgbMin:with: "29" rgbMinInvert:with: "30" alphaBlendConst:with: "31" alphaPaintConst:with: "32" rgbDiff:with: "33" tallyIntoMap:with: "34" alphaBlendScaled:with: "35" alphaBlendScaled:with: "unused here - only used by FXBlt" "36" alphaBlendScaled:with: "unused here - only used by FXBlt" "37" rgbMul:with: "38" pixSwap:with: "39" pixClear:with: "40" fixAlpha:with: "41" rgbComponentAlpha:with: + "42" alphaScale:with: + "43" alphaUnscale:with: + "44" alphaBlendUnscaled:with: ). OpTableSize := OpTable size + 1. "0-origin indexing" ! Item was added: + ----- Method: BitBltSimulation>>alphaBlendUnscaled:with: (in category 'combination rules') ----- + alphaBlendUnscaled: sourceWord with: destinationWord + "Blend sourceWord with destinationWord using the alpha value from both sourceWord and destinationWord. + Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0. + The alpha channel and color produced are + + srcAlpha + (destAlpha*(1-srcAlpha)) + (srcAlpha*srcColor + (destAlpha*(1-srcAlpha)*dstColor)) / (srcAlpha + (destAlpha*(1-srcAlpha))) + + In contrast to alphaBlend:with: the method does not assume that destination form is opaque. + In contrast to alphaBlendScaled:with: the method does not assume that colors have been pre-scaled (muliplied) by alpha channel." + | alpha blendA result blendRB blendG | + <inline: false> + <returnTypeC: 'unsigned int'> + <var: #sourceWord type: 'unsigned int'> + <var: #destinationWord type: 'unsigned int'> + <var: #blendRB type: 'unsigned int'> + <var: #blendG type: 'unsigned int'> + <var: #result type: 'unsigned int'> + <var: #alpha type: 'unsigned int'> + <var: #blendA type: 'unsigned int'> + alpha := sourceWord >> 24. "High 8 bits of source pixel, assuming ARGB encoding" + alpha = 0 ifTrue: [ ^ destinationWord ]. + alpha = 255 ifTrue: [ ^ sourceWord ]. + + blendA := 16rFF * alpha + (16rFF - alpha * (destinationWord >> 24)) + 16rFF. "blend alpha channels" + blendA := blendA + (blendA - 1 >> 8 bitAnd: 16rFF) >> 8 bitAnd: 16rFF. "divide by 255" + + blendRB := ((sourceWord bitAnd: 16rFF00FF) * alpha) + + ((destinationWord bitAnd: 16rFF00FF) * (blendA-alpha)) + / blendA. "blend red and blue" + + blendG := ((sourceWord bitAnd: 16r00FF00) * alpha) + + ((destinationWord bitAnd: 16r00FF00) * (blendA-alpha)) + / blendA. "blend green" + result := (blendRB bitOr: blendG) bitOr: blendA << 24. + ^ result + ! Item was added: + ----- Method: BitBltSimulation>>alphaScale:with: (in category 'combination rules') ----- + alphaScale: sourceWord with: destinationWord + "Scale (premultiply) the destination with its alpha channel. + Note that sourceWord is ignored." + | alpha rb g | + <inline: false> "Do NOT inline this into optimized loops" + <returnTypeC: 'unsigned int'> + <var: #sourceWord type: 'unsigned int'> + <var: #destinationWord type: 'unsigned int'> + <var: #rb type: 'unsigned int'> + <var: #g type: 'unsigned int'> + <var: #alpha type: 'unsigned int'> + alpha := destinationWord >> 24. "High 8 bits is opacity (ARGB format)" + rb := ((destinationWord bitAnd: 16rFF00FF) * alpha >> 8 bitAnd: 16rFF00FF). "scale red and blue components" + g := ((destinationWord bitAnd: 16r00FF00) * alpha >> 8 bitAnd: 16r00FF00). "scale green component" + ^(g bitOr: rb) bitOr: (destinationWord bitAnd: 16rFF000000) "recompose"! Item was added: + ----- Method: BitBltSimulation>>alphaUnscale:with: (in category 'combination rules') ----- + alphaUnscale: sourceWord with: destinationWord + "Unscale (divide) the destination with its alpha channel. + Note that sourceWord is ignored." + | alpha rb g rgb carry | + <inline: false> "Do NOT inline this into optimized loops" + <returnTypeC: 'unsigned int'> + <var: #sourceWord type: 'unsigned int'> + <var: #destinationWord type: 'unsigned int'> + <var: #rb type: 'unsigned int'> + <var: #g type: 'unsigned int'> + <var: #rgb type: 'unsigned int'> + <var: #alpha type: 'unsigned int'> + <var: #carry type: 'unsigned int'> + alpha := destinationWord >> 24. "High 8 bits is opacity (ARGB format)" + alpha = 0 ifTrue: [^0]. + rb := (destinationWord bitAnd: 16rFF00FF) << 8 / alpha. "unscale red and blue components" + g := (destinationWord bitAnd: 16r00FF00) / alpha. "unscale green component" + carry := ((rb >> 8 bitAnd: 16rAA00AA) >> 1 bitOr: (rb >> 8 bitAnd: 16r550055) << 1) + bitOr: ((g bitAnd: 16r00AA00) >> 1 bitOr: (g bitAnd: 16r005500) << 1). + carry := (carry bitAnd: 16rCCCCCC) >> 2 bitOr: (carry bitAnd: 16r333333) << 2. + carry := (carry bitAnd: 16rF0F0F0) >> 4 bitOr: (carry bitAnd: 16r0F0F0F) << 4. + rgb := (rb bitAnd: 16rFF00FF) bitOr: (g << 8 bitAnd: 16r00FF00). + rgb := rgb bitOr: carry. "saturate RGB components if division overflows" + ^rgb bitOr: (destinationWord bitAnd: 16rFF000000) "restore alpha"! Item was changed: ----- Method: BitBltSimulation>>initBBOpTable (in category 'initialize-release') ----- initBBOpTable self cCode: 'opTable[0+1] = (void *)clearWordwith'. self cCode: 'opTable[1+1] = (void *)bitAndwith'. self cCode: 'opTable[2+1] = (void *)bitAndInvertwith'. self cCode: 'opTable[3+1] = (void *)sourceWordwith'. self cCode: 'opTable[4+1] = (void *)bitInvertAndwith'. self cCode: 'opTable[5+1] = (void *)destinationWordwith'. self cCode: 'opTable[6+1] = (void *)bitXorwith'. self cCode: 'opTable[7+1] = (void *)bitOrwith'. self cCode: 'opTable[8+1] = (void *)bitInvertAndInvertwith'. self cCode: 'opTable[9+1] = (void *)bitInvertXorwith'. self cCode: 'opTable[10+1] = (void *)bitInvertDestinationwith'. self cCode: 'opTable[11+1] = (void *)bitOrInvertwith'. self cCode: 'opTable[12+1] = (void *)bitInvertSourcewith'. self cCode: 'opTable[13+1] = (void *)bitInvertOrwith'. self cCode: 'opTable[14+1] = (void *)bitInvertOrInvertwith'. self cCode: 'opTable[15+1] = (void *)destinationWordwith'. self cCode: 'opTable[16+1] = (void *)destinationWordwith'. self cCode: 'opTable[17+1] = (void *)destinationWordwith'. self cCode: 'opTable[18+1] = (void *)addWordwith'. self cCode: 'opTable[19+1] = (void *)subWordwith'. self cCode: 'opTable[20+1] = (void *)rgbAddwith'. self cCode: 'opTable[21+1] = (void *)rgbSubwith'. self cCode: 'opTable[22+1] = (void *)OLDrgbDiffwith'. self cCode: 'opTable[23+1] = (void *)OLDtallyIntoMapwith'. self cCode: 'opTable[24+1] = (void *)alphaBlendwith'. self cCode: 'opTable[25+1] = (void *)pixPaintwith'. self cCode: 'opTable[26+1] = (void *)pixMaskwith'. self cCode: 'opTable[27+1] = (void *)rgbMaxwith'. self cCode: 'opTable[28+1] = (void *)rgbMinwith'. self cCode: 'opTable[29+1] = (void *)rgbMinInvertwith'. self cCode: 'opTable[30+1] = (void *)alphaBlendConstwith'. self cCode: 'opTable[31+1] = (void *)alphaPaintConstwith'. self cCode: 'opTable[32+1] = (void *)rgbDiffwith'. self cCode: 'opTable[33+1] = (void *)tallyIntoMapwith'. self cCode: 'opTable[34+1] = (void *)alphaBlendScaledwith'. self cCode: 'opTable[35+1] = (void *)alphaBlendScaledwith'. self cCode: 'opTable[36+1] = (void *)alphaBlendScaledwith'. self cCode: 'opTable[37+1] = (void *)rgbMulwith'. self cCode: 'opTable[38+1] = (void *)pixSwapwith'. self cCode: 'opTable[39+1] = (void *)pixClearwith'. self cCode: 'opTable[40+1] = (void *)fixAlphawith'. + self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'. + self cCode: 'opTable[42+1] = (void *)alphaScalewith'. + self cCode: 'opTable[43+1] = (void *)alphaUnscalewith'. + self cCode: 'opTable[44+1] = (void *)alphaBlendUnscaledwith'.! - self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'.! |
Finally :-D Best, Karl On Wed, Dec 23, 2020 at 9:55 PM <[hidden email]> wrote:
|
Bravo! Thank you Nicolas. Dave On Sun, Dec 27, 2020 at 09:42:47PM +0100, karl ramberg wrote: > > Finally :-D > > Best, > Karl > > > On Wed, Dec 23, 2020 at 9:55 PM <[hidden email]> wrote: > > > > > Nicolas Cellier uploaded a new version of VMMaker to project VM Maker: > > http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2909.mcz > > > > ==================== Summary ==================== > > > > Name: VMMaker.oscog-nice.2909 > > Author: nice > > Time: 23 December 2020, 9:54:51.201058 pm > > UUID: 6869c4f1-9d80-40c3-8409-7c05e087edf5 > > Ancestors: VMMaker.oscog-eem.2908 > > > > WIP: implement new BitBlt ops (rules) for alpha compositing > > > > "42" alphaScale:with: > > "43" alphaUnscale:with: > > "44" alphaBlendUnscaled:with: > > > > This is a proposal implementation for > > https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/505 > > > > The generated C code compiles, but it's otherwise mostly yet unused and > > untested code. I commit it before I loose it. > > There's probably more to do for letting accelerated code work (PI). > > > > =============== Diff against VMMaker.oscog-eem.2908 =============== > > > > Item was changed: > > SmartSyntaxInterpreterPlugin subclass: #BitBltSimulation > > instanceVariableNames: 'destForm sourceForm halftoneForm > > combinationRule destX destY width height sourceX sourceY clipX clipY > > clipWidth clipHeight sourceWidth sourceHeight sourceDepth sourcePitch > > sourceBits sourcePPW sourceMSB destWidth destHeight destDepth destPitch > > destBits destPPW destMSB bitCount skew mask1 mask2 preload nWords destMask > > hDir vDir sourceIndex sourceDelta destIndex destDelta sx sy dx dy bbW bbH > > halftoneHeight noSource noHalftone halftoneBase sourceAlpha srcBitShift > > dstBitShift bitBltOop affectedL affectedR affectedT affectedB opTable > > maskTable ditherMatrix4x4 ditherThresholds16 ditherValues16 hasSurfaceLock > > warpSrcShift warpSrcMask warpAlignShift warpAlignMask warpBitShiftTable > > querySurfaceFn lockSurfaceFn unlockSurfaceFn isWarping cmFlags cmMask > > cmShiftTable cmMaskTable cmLookupTable cmBitsPerColor dither8Lookup > > componentAlphaModeColor componentAlphaModeAlpha ungammaLookupTable > > gammaLookupTable numGCsOnInvocation bitBltIsReceiver endOfDestination > > endOfSource' > > classVariableNames: 'AllOnes AlphaIndex BBClipHeightIndex > > BBClipWidthIndex BBClipXIndex BBClipYIndex BBColorMapIndex BBDestFormIndex > > BBDestXIndex BBDestYIndex BBHalftoneFormIndex BBHeightIndex BBLastIndex > > BBRuleIndex BBSourceFormIndex BBSourceXIndex BBSourceYIndex BBWarpBase > > BBWidthIndex BBXTableIndex BEBitBltIndex BinaryPoint BlueIndex > > ColorMapFixedPart ColorMapIndexedPart ColorMapNewStyle ColorMapPresent > > CrossedX EndOfRun FixedPt1 FormBitsIndex FormDepthIndex FormHeightIndex > > FormWidthIndex GreenIndex OpTable OpTableSize RedIndex' > > poolDictionaries: '' > > category: 'VMMaker-Interpreter'! > > > > + !BitBltSimulation commentStamp: 'nice 10/31/2020 23:39' prior: 0! > > - !BitBltSimulation commentStamp: 'tpr 3/25/2013 16:50' prior: 0! > > This class implements BitBlt, much as specified in the Blue Book spec. > > > > Performance has been enhanced through the use of pointer variables such > > as sourceIndex and destIndex, and by separating several special cases of > > the inner loop. > > > > Operation has been extended to color, with support for 1, 2, 4, 8, 16, > > and 32-bit pixel sizes. Conversion between different pixel sizes is > > facilitated by accepting an optional color map. > > > > In addition to the original 16 combination rules, this BitBlt supports > > 16 fail (for old paint mode) > > 17 fail (for old mask mode) > > 18 sourceWord + destinationWord > > 19 sourceWord - destinationWord > > 20 rgbAdd: sourceWord with: destinationWord > > 21 rgbSub: sourceWord with: destinationWord > > 22 OLDrgbDiff: sourceWord with: destinationWord > > 23 OLDtallyIntoMap: destinationWord -- old vers doesn't clip > > to bit boundary > > 24 alphaBlend: sourceWord with: destinationWord > > 25 pixPaint: sourceWord with: destinationWord > > 26 pixMask: sourceWord with: destinationWord > > 27 rgbMax: sourceWord with: destinationWord > > 28 rgbMin: sourceWord with: destinationWord > > 29 rgbMin: sourceWord bitInvert32 with: destinationWord > > 30 alphaBlendConst: sourceWord with: destinationWord -- alpha > > passed as an arg > > 31 alphaPaintConst: sourceWord with: destinationWord -- alpha > > passed as an arg > > 32 rgbDiff: sourceWord with: destinationWord > > 33 tallyIntoMap: destinationWord > > 34 alphaBlendScaled: sourceWord with: destinationWord > > 35 alphaBlendScaled: sourceWord with: "unused here - only used > > by FXBlt" > > 36 alphaBlendScaled: sourceWord with: "unused here - only used > > by FXBlt" > > 37 rgbMul: sourceWord with: destinationWord > > 38 pixSwap: sourceWord with: destinationWord > > 39 pixClear: sourceWord with: destinationWord > > 40 fixAlpha: sourceWord with: destinationWord > > 41 rgbComponentAlpha: sourceWord with: destinationWord > > + 42 alphaScale: ignoredSourceWord with: destinationWord > > + 43 alphaUnscale: ignoredSourceWord with: destinationWord > > + 44 alphaBlendUnscaled: sourceWord with: destinationWord > > > > This implementation has also been fitted with an experimental "warp > > drive" that allows abritrary scaling and rotation (and even limited affine > > deformations) with all BitBlt storage modes supported. > > > > To add a new rule to BitBlt... > > 1. add the new rule method or methods in the category > > 'combination rules' of BBSim > > 2. describe it in the class comment of BBSim and in the class > > comment for BitBlt > > 3. add refs to initializeRuleTable in proper positions > > 4. add refs to initBBOpTable, following the pattern > > ! > > > > Item was changed: > > ----- Method: BitBltSimulation class>>initializeRuleTable (in category > > 'initialization') ----- > > initializeRuleTable > > "BitBltSimulation initializeRuleTable" > > "**WARNING** You MUST change initBBOpTable if you change this" > > OpTable := #( > > "0" clearWord:with: > > "1" bitAnd:with: > > "2" bitAndInvert:with: > > "3" sourceWord:with: > > "4" bitInvertAnd:with: > > "5" destinationWord:with: > > "6" bitXor:with: > > "7" bitOr:with: > > "8" bitInvertAndInvert:with: > > "9" bitInvertXor:with: > > "10" bitInvertDestination:with: > > "11" bitOrInvert:with: > > "12" bitInvertSource:with: > > "13" bitInvertOr:with: > > "14" bitInvertOrInvert:with: > > "15" destinationWord:with: > > "16" destinationWord:with: "unused - was old paint" > > "17" destinationWord:with: "unused - was old mask" > > "18" addWord:with: > > "19" subWord:with: > > "20" rgbAdd:with: > > "21" rgbSub:with: > > "22" OLDrgbDiff:with: > > "23" OLDtallyIntoMap:with: > > "24" alphaBlend:with: > > "25" pixPaint:with: > > "26" pixMask:with: > > "27" rgbMax:with: > > "28" rgbMin:with: > > "29" rgbMinInvert:with: > > "30" alphaBlendConst:with: > > "31" alphaPaintConst:with: > > "32" rgbDiff:with: > > "33" tallyIntoMap:with: > > "34" alphaBlendScaled:with: > > > > "35" alphaBlendScaled:with: "unused here - only used > > by FXBlt" > > "36" alphaBlendScaled:with: "unused here - only used > > by FXBlt" > > "37" rgbMul:with: > > "38" pixSwap:with: > > "39" pixClear:with: > > "40" fixAlpha:with: > > "41" rgbComponentAlpha:with: > > + "42" alphaScale:with: > > + "43" alphaUnscale:with: > > + "44" alphaBlendUnscaled:with: > > ). > > OpTableSize := OpTable size + 1. "0-origin indexing" > > ! > > > > Item was added: > > + ----- Method: BitBltSimulation>>alphaBlendUnscaled:with: (in category > > 'combination rules') ----- > > + alphaBlendUnscaled: sourceWord with: destinationWord > > + "Blend sourceWord with destinationWord using the alpha value from > > both sourceWord and destinationWord. > > + Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0. > > + The alpha channel and color produced are > > + > > + srcAlpha + (destAlpha*(1-srcAlpha)) > > + (srcAlpha*srcColor + (destAlpha*(1-srcAlpha)*dstColor)) / > > (srcAlpha + (destAlpha*(1-srcAlpha))) > > + > > + In contrast to alphaBlend:with: the method does not assume that > > destination form is opaque. > > + In contrast to alphaBlendScaled:with: the method does not assume > > that colors have been pre-scaled (muliplied) by alpha channel." > > + | alpha blendA result blendRB blendG | > > + <inline: false> > > + <returnTypeC: 'unsigned int'> > > + <var: #sourceWord type: 'unsigned int'> > > + <var: #destinationWord type: 'unsigned int'> > > + <var: #blendRB type: 'unsigned int'> > > + <var: #blendG type: 'unsigned int'> > > + <var: #result type: 'unsigned int'> > > + <var: #alpha type: 'unsigned int'> > > + <var: #blendA type: 'unsigned int'> > > + alpha := sourceWord >> 24. "High 8 bits of source pixel, assuming > > ARGB encoding" > > + alpha = 0 ifTrue: [ ^ destinationWord ]. > > + alpha = 255 ifTrue: [ ^ sourceWord ]. > > + > > + blendA := 16rFF * alpha + (16rFF - alpha * (destinationWord >> > > 24)) + 16rFF. "blend alpha channels" > > + blendA := blendA + (blendA - 1 >> 8 bitAnd: 16rFF) >> 8 bitAnd: > > 16rFF. "divide by 255" > > + > > + blendRB := ((sourceWord bitAnd: 16rFF00FF) * alpha) + > > + ((destinationWord bitAnd: 16rFF00FF) * > > (blendA-alpha)) > > + / blendA. "blend red and blue" > > + > > + blendG := ((sourceWord bitAnd: 16r00FF00) * alpha) + > > + ((destinationWord bitAnd: 16r00FF00) * > > (blendA-alpha)) > > + / blendA. "blend green" > > + result := (blendRB bitOr: blendG) bitOr: blendA << 24. > > + ^ result > > + ! > > > > Item was added: > > + ----- Method: BitBltSimulation>>alphaScale:with: (in category > > 'combination rules') ----- > > + alphaScale: sourceWord with: destinationWord > > + "Scale (premultiply) the destination with its alpha channel. > > + Note that sourceWord is ignored." > > + | alpha rb g | > > + <inline: false> "Do NOT inline this into optimized loops" > > + <returnTypeC: 'unsigned int'> > > + <var: #sourceWord type: 'unsigned int'> > > + <var: #destinationWord type: 'unsigned int'> > > + <var: #rb type: 'unsigned int'> > > + <var: #g type: 'unsigned int'> > > + <var: #alpha type: 'unsigned int'> > > + alpha := destinationWord >> 24. "High 8 bits is opacity (ARGB > > format)" > > + rb := ((destinationWord bitAnd: 16rFF00FF) * alpha >> 8 bitAnd: > > 16rFF00FF). "scale red and blue components" > > + g := ((destinationWord bitAnd: 16r00FF00) * alpha >> 8 bitAnd: > > 16r00FF00). "scale green component" > > + ^(g bitOr: rb) bitOr: (destinationWord bitAnd: 16rFF000000) > > "recompose"! > > > > Item was added: > > + ----- Method: BitBltSimulation>>alphaUnscale:with: (in category > > 'combination rules') ----- > > + alphaUnscale: sourceWord with: destinationWord > > + "Unscale (divide) the destination with its alpha channel. > > + Note that sourceWord is ignored." > > + | alpha rb g rgb carry | > > + <inline: false> "Do NOT inline this into optimized loops" > > + <returnTypeC: 'unsigned int'> > > + <var: #sourceWord type: 'unsigned int'> > > + <var: #destinationWord type: 'unsigned int'> > > + <var: #rb type: 'unsigned int'> > > + <var: #g type: 'unsigned int'> > > + <var: #rgb type: 'unsigned int'> > > + <var: #alpha type: 'unsigned int'> > > + <var: #carry type: 'unsigned int'> > > + alpha := destinationWord >> 24. "High 8 bits is opacity (ARGB > > format)" > > + alpha = 0 ifTrue: [^0]. > > + rb := (destinationWord bitAnd: 16rFF00FF) << 8 / alpha. "unscale > > red and blue components" > > + g := (destinationWord bitAnd: 16r00FF00) / alpha. "unscale green > > component" > > + carry := ((rb >> 8 bitAnd: 16rAA00AA) >> 1 bitOr: (rb >> 8 bitAnd: > > 16r550055) << 1) > > + bitOr: ((g bitAnd: 16r00AA00) >> 1 bitOr: (g bitAnd: > > 16r005500) << 1). > > + carry := (carry bitAnd: 16rCCCCCC) >> 2 bitOr: (carry bitAnd: > > 16r333333) << 2. > > + carry := (carry bitAnd: 16rF0F0F0) >> 4 bitOr: (carry bitAnd: > > 16r0F0F0F) << 4. > > + rgb := (rb bitAnd: 16rFF00FF) bitOr: (g << 8 bitAnd: 16r00FF00). > > + rgb := rgb bitOr: carry. "saturate RGB components if division > > overflows" > > + ^rgb bitOr: (destinationWord bitAnd: 16rFF000000) "restore alpha"! > > > > Item was changed: > > ----- Method: BitBltSimulation>>initBBOpTable (in category > > 'initialize-release') ----- > > initBBOpTable > > self cCode: 'opTable[0+1] = (void *)clearWordwith'. > > self cCode: 'opTable[1+1] = (void *)bitAndwith'. > > self cCode: 'opTable[2+1] = (void *)bitAndInvertwith'. > > self cCode: 'opTable[3+1] = (void *)sourceWordwith'. > > self cCode: 'opTable[4+1] = (void *)bitInvertAndwith'. > > self cCode: 'opTable[5+1] = (void *)destinationWordwith'. > > self cCode: 'opTable[6+1] = (void *)bitXorwith'. > > self cCode: 'opTable[7+1] = (void *)bitOrwith'. > > self cCode: 'opTable[8+1] = (void *)bitInvertAndInvertwith'. > > self cCode: 'opTable[9+1] = (void *)bitInvertXorwith'. > > self cCode: 'opTable[10+1] = (void *)bitInvertDestinationwith'. > > self cCode: 'opTable[11+1] = (void *)bitOrInvertwith'. > > self cCode: 'opTable[12+1] = (void *)bitInvertSourcewith'. > > self cCode: 'opTable[13+1] = (void *)bitInvertOrwith'. > > self cCode: 'opTable[14+1] = (void *)bitInvertOrInvertwith'. > > self cCode: 'opTable[15+1] = (void *)destinationWordwith'. > > self cCode: 'opTable[16+1] = (void *)destinationWordwith'. > > self cCode: 'opTable[17+1] = (void *)destinationWordwith'. > > self cCode: 'opTable[18+1] = (void *)addWordwith'. > > self cCode: 'opTable[19+1] = (void *)subWordwith'. > > self cCode: 'opTable[20+1] = (void *)rgbAddwith'. > > self cCode: 'opTable[21+1] = (void *)rgbSubwith'. > > self cCode: 'opTable[22+1] = (void *)OLDrgbDiffwith'. > > self cCode: 'opTable[23+1] = (void *)OLDtallyIntoMapwith'. > > self cCode: 'opTable[24+1] = (void *)alphaBlendwith'. > > self cCode: 'opTable[25+1] = (void *)pixPaintwith'. > > self cCode: 'opTable[26+1] = (void *)pixMaskwith'. > > self cCode: 'opTable[27+1] = (void *)rgbMaxwith'. > > self cCode: 'opTable[28+1] = (void *)rgbMinwith'. > > self cCode: 'opTable[29+1] = (void *)rgbMinInvertwith'. > > self cCode: 'opTable[30+1] = (void *)alphaBlendConstwith'. > > self cCode: 'opTable[31+1] = (void *)alphaPaintConstwith'. > > self cCode: 'opTable[32+1] = (void *)rgbDiffwith'. > > self cCode: 'opTable[33+1] = (void *)tallyIntoMapwith'. > > self cCode: 'opTable[34+1] = (void *)alphaBlendScaledwith'. > > self cCode: 'opTable[35+1] = (void *)alphaBlendScaledwith'. > > self cCode: 'opTable[36+1] = (void *)alphaBlendScaledwith'. > > self cCode: 'opTable[37+1] = (void *)rgbMulwith'. > > self cCode: 'opTable[38+1] = (void *)pixSwapwith'. > > self cCode: 'opTable[39+1] = (void *)pixClearwith'. > > self cCode: 'opTable[40+1] = (void *)fixAlphawith'. > > + self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'. > > + self cCode: 'opTable[42+1] = (void *)alphaScalewith'. > > + self cCode: 'opTable[43+1] = (void *)alphaUnscalewith'. > > + self cCode: 'opTable[44+1] = (void *)alphaBlendUnscaledwith'.! > > - self cCode: 'opTable[41+1] = (void *)rgbComponentAlphawith'.! > > > > |
Free forum by Nabble | Edit this page |