[Vm-dev] [commit] r2486 - Include the rule 41 code in the BitBltPlugin. Fix regression in linux mt build

commits at squeakvm.org commits at squeakvm.org
Mon Aug 8 19:01:31 UTC 2011


Author: eliot
Date: 2011-08-08 12:01:31 -0700 (Mon, 08 Aug 2011)
New Revision: 2486

Modified:
   branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c
   branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
   branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
   branches/Cog/unixbuild/mtbld/mvm
Log:
Include the rule 41 code in the BitBltPlugin.  Fix regression in linux mt build
mvm script.


Modified: branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c
===================================================================
--- branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c	2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/nscogsrc/plugins/BitBltPlugin/BitBltPlugin.c	2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463
+	VMPluginCodeGenerator VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
    from
-	BitBltSimulation VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463
+	BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
  */
-static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.105 uuid: 79234f80-ee6a-404c-9e5c-2134e3b76463 " __DATE__ ;
+static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e " __DATE__ ;
 
 
 
@@ -67,7 +67,7 @@
 #define FormHeightIndex 2
 #define FormWidthIndex 1
 #define GreenIndex 1
-#define OpTableSize 42
+#define OpTableSize 43
 #define RedIndex 0
 
 
@@ -149,6 +149,7 @@
 static sqInt partitionedMaxwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt partitionedMinwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt partitionedMulwithnBitsnPartitions(sqInt word1, sqInt word2, sqInt nBits, sqInt nParts);
+static sqInt partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts);
 static sqInt partitionedSubfromnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt performCopyLoop(void);
 static sqInt pickSourcePixelsflagssrcMaskdestMasksrcShiftIncdstShiftInc(sqInt nPixels, sqInt mapperFlags, sqInt srcMask, sqInt dstMask, sqInt srcShiftInc, sqInt dstShiftInc);
@@ -164,6 +165,11 @@
 static sqInt queryDestSurface(sqInt handle);
 static sqInt querySourceSurface(sqInt handle);
 static sqInt rgbAddwith(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha16(void);
+static sqInt rgbComponentAlpha32(void);
+static sqInt rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha8(void);
+static sqInt rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord);
 static sqInt rgbDiffwith(sqInt sourceWord, sqInt destinationWord);
 static sqInt rgbMap16To32(sqInt sourcePixel);
 static sqInt rgbMap32To32(sqInt sourcePixel);
@@ -214,6 +220,8 @@
 static unsigned int * cmMaskTable;
 static int * cmShiftTable;
 static sqInt combinationRule;
+static sqInt componentAlphaModeAlpha;
+static sqInt componentAlphaModeColor;
 static sqInt destBits;
 static sqInt destDelta;
 static sqInt destDepth;
@@ -242,6 +250,7 @@
 static sqInt dstBitShift;
 static sqInt dx;
 static sqInt dy;
+static unsigned char * gammaLookupTable;
 static sqInt halftoneBase;
 static sqInt halftoneForm;
 static sqInt halftoneHeight;
@@ -263,15 +272,15 @@
 };
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"BitBltPlugin VMMaker.oscog-eem.105 (i)"
+	"BitBltPlugin VMMaker.oscog-eem.115 (i)"
 #else
-	"BitBltPlugin VMMaker.oscog-eem.105 (e)"
+	"BitBltPlugin VMMaker.oscog-eem.115 (e)"
 #endif
 ;
 static sqInt noHalftone;
 static sqInt noSource;
 static sqInt nWords;
-static void *opTable[42];
+static void *opTable[43];
 static sqInt preload;
 static void * querySurfaceFn;
 static sqInt skew;
@@ -291,6 +300,7 @@
 static sqInt srcBitShift;
 static sqInt sx;
 static sqInt sy;
+static unsigned char * ungammaLookupTable;
 static void * unlockSurfaceFn;
 static sqInt vDir;
 static sqInt warpAlignMask;
@@ -1123,11 +1133,13 @@
     sqInt dWid;
     sqInt dxLowBits;
     sqInt endBits;
+    sqInt gammaLookupTableOop;
     sqInt pixPerM1;
     sqInt pixPerM11;
     sqInt startBits;
     sqInt sxLowBits;
     sqInt t;
+    sqInt ungammaLookupTableOop;
 
 	clipRange();
 	if ((bbW <= 0)
@@ -1142,12 +1154,58 @@
 		return interpreterProxy->primitiveFail();
 	}
 	/* begin copyBitsLockedAndClipped */
+	if (combinationRule == 41) {
+
+		/* Try a shortcut for stuff that should be run as quickly as possible */
+		/* fetch the forecolor into componentAlphaModeColor. */
+
+		componentAlphaModeAlpha = 255;
+		componentAlphaModeColor = 16777215;
+		gammaLookupTable = null;
+		ungammaLookupTable = null;
+		if ((interpreterProxy->methodArgumentCount()) >= 2) {
+			componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+			if (!(!(interpreterProxy->failed()))) {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+			componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+			if (!(!(interpreterProxy->failed()))) {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+			if ((interpreterProxy->methodArgumentCount()) == 4) {
+				gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+				if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+					gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+				}
+				ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+				if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+					ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+				}
+			}
+		}
+		else {
+			if ((interpreterProxy->methodArgumentCount()) == 1) {
+				componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+				if (!(!(interpreterProxy->failed()))) {
+					interpreterProxy->primitiveFail();
+					goto l1;
+				}
+			}
+			else {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+		}
+	}
 	/* begin tryCopyingBitsQuickly */
 	if (noSource) {
 		done = 0;
 		goto l2;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		done = 0;
 		goto l2;
 	}
@@ -1159,6 +1217,37 @@
 		done = 0;
 		goto l2;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		done = 0;
+		goto l2;
+	}
 	if (destDepth < 8) {
 		done = 0;
 		goto l2;
@@ -1391,18 +1480,62 @@
     sqInt dWid;
     sqInt dxLowBits;
     sqInt endBits;
+    sqInt gammaLookupTableOop;
     sqInt pixPerM1;
     sqInt pixPerM11;
     sqInt startBits;
     sqInt sxLowBits;
     sqInt t;
+    sqInt ungammaLookupTableOop;
 
+	if (combinationRule == 41) {
+
+		/* Try a shortcut for stuff that should be run as quickly as possible */
+		/* fetch the forecolor into componentAlphaModeColor. */
+
+		componentAlphaModeAlpha = 255;
+		componentAlphaModeColor = 16777215;
+		gammaLookupTable = null;
+		ungammaLookupTable = null;
+		if ((interpreterProxy->methodArgumentCount()) >= 2) {
+			componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+			if (!(!(interpreterProxy->failed()))) {
+				return interpreterProxy->primitiveFail();
+			}
+			componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+			if (!(!(interpreterProxy->failed()))) {
+				return interpreterProxy->primitiveFail();
+			}
+			if ((interpreterProxy->methodArgumentCount()) == 4) {
+				gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+				if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+					gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+				}
+				ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+				if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+					ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+				}
+			}
+		}
+		else {
+			if ((interpreterProxy->methodArgumentCount()) == 1) {
+				componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+				if (!(!(interpreterProxy->failed()))) {
+					return interpreterProxy->primitiveFail();
+				}
+			}
+			else {
+				return interpreterProxy->primitiveFail();
+			}
+		}
+	}
 	/* begin tryCopyingBitsQuickly */
 	if (noSource) {
 		done = 0;
 		goto l1;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		done = 0;
 		goto l1;
 	}
@@ -1414,6 +1547,37 @@
 		done = 0;
 		goto l1;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		done = 0;
+		goto l1;
+	}
 	if (destDepth < 8) {
 		done = 0;
 		goto l1;
@@ -2643,6 +2807,7 @@
 	opTable[38+1] = (void *)pixSwapwith;
 	opTable[39+1] = (void *)pixClearwith;
 	opTable[40+1] = (void *)fixAlphawith;
+	opTable[41+1] = (void *)rgbComponentAlphawith;
 }
 
 static sqInt
@@ -2901,7 +3066,7 @@
 	}
 	ok = 1;
 l3:	/* end loadBitBltDestForm */;
-	if (!(ok)) {
+	if (!ok) {
 		return 0;
 	}
 	destX = fetchIntOrFloatofObjectifNil(BBDestXIndex, bitBltOop, 0);
@@ -2982,7 +3147,7 @@
 		}
 		ok = 1;
 	l10:	/* end loadBitBltSourceForm */;
-		if (!(ok)) {
+		if (!ok) {
 			return 0;
 		}
 		/* begin loadColorMap */
@@ -3102,7 +3267,7 @@
 		}
 		ok = 1;
 	l4:	/* end loadColorMap */;
-		if (!(ok)) {
+		if (!ok) {
 			return 0;
 		}
 		if ((cmFlags & ColorMapNewStyle) == 0) {
@@ -3140,7 +3305,7 @@
 	halftoneBase = oopForPointer(interpreterProxy->firstIndexableField(halftoneBits));
 	ok = 1;
 l5:	/* end loadHalftoneForm */;
-	if (!(ok)) {
+	if (!ok) {
 		return 0;
 	}
 	clipX = fetchIntOrFloatofObjectifNil(BBClipXIndex, bitBltOop, 0);
@@ -4047,7 +4212,101 @@
 	return result;
 }
 
+static sqInt
+partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts)
+{
+    sqInt d;
+    sqInt destPix;
+    sqInt i;
+    sqInt mask;
+    sqInt mask3;
+    sqInt p1;
+    sqInt p2;
+    sqInt result;
+    sqInt srcPix;
+    sqInt v;
 
+
+	/* partition mask starts at the right */
+
+	mask = maskTable[nBits];
+	result = 0;
+	for (i = 1; i <= nParts; i += 1) {
+		p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * nBits);
+		p2 = ((usqInt) (destWord & mask)) >> ((i - 1) * nBits);
+		if (!(nBits == 32)) {
+			if (nBits == 16) {
+				p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+				p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+			}
+			else {
+				p1 = (rgbMapfromto(p1, nBits, 32)) | 4278190080UL;
+				p2 = (rgbMapfromto(p2, nBits, 32)) | 4278190080UL;
+			}
+		}
+		v = rgbComponentAlpha32with(p1, p2);
+		if (!(nBits == 32)) {
+			/* begin rgbMap:from:to: */
+			if (((d = nBits - 32)) > 0) {
+
+				/* Expand to more bits by zero-fill */
+				/* Transfer mask */
+
+				mask3 = (1 << 32) - 1;
+				srcPix = v << d;
+				mask3 = mask3 << d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << nBits;
+				srcPix = srcPix << d;
+				v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << nBits));
+				goto l1;
+			}
+			else {
+				if (d == 0) {
+					if (32 == 5) {
+						v = v & 32767;
+						goto l1;
+					}
+					if (32 == 8) {
+						v = v & 16777215;
+						goto l1;
+					}
+					v = v;
+					goto l1;
+				}
+				if (v == 0) {
+					v = v;
+					goto l1;
+				}
+				d = 32 - nBits;
+
+				/* Transfer mask */
+
+				mask3 = (1 << nBits) - 1;
+				srcPix = ((usqInt) v) >> d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << nBits;
+				srcPix = ((usqInt) srcPix) >> d;
+				destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << nBits));
+				if (destPix == 0) {
+					v = 1;
+					goto l1;
+				}
+				v = destPix;
+				goto l1;
+			}
+		l1:	/* end rgbMap:from:to: */;
+		}
+		result = result | (v << ((i - 1) * nBits));
+
+		/* slide left to next partition */
+
+		mask = mask << nBits;
+	}
+	return result;
+}
+
+
 /*	Subtract word1 from word2 as nParts partitions of nBits each.
 	This is useful for packed pixels, or packed colors */
 /*	In C, most arithmetic operations answer the same bit pattern regardless of
@@ -4996,6 +5255,586 @@
 }
 
 
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = 32
+	destPixSize = 16
+	sourceForm ~= destForm.
+	 */
+/*	This particular method should be optimized in itself */
+
+static sqInt
+rgbComponentAlpha16(void)
+{
+    sqInt addThreshold;
+    sqInt deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    sqInt ditherBase;
+    sqInt ditherIndex;
+    sqInt ditherThreshold;
+    sqInt dstIndex;
+    sqInt dstMask;
+    sqInt dstValue;
+    sqInt dstY;
+    sqInt sourceWord;
+    sqInt srcAlpha;
+    sqInt srcIndex;
+    sqInt srcShift;
+    sqInt srcY;
+
+
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+	dstY = dy;
+	srcShift = (dx & 1) * 16;
+	if (destMSB) {
+		srcShift = 16 - srcShift;
+	}
+
+	/* This is the outer loop */
+
+	mask1 = 65535 << (16 - srcShift);
+	while (((deltaY -= 1)) != 0) {
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 1)) * 4);
+		ditherBase = (dstY & 3) * 4;
+
+		/* For pre-increment */
+
+		ditherIndex = (sx & 3) - 1;
+
+		/* So we can pre-decrement */
+
+		deltaX = bbW + 1;
+		dstMask = mask1;
+		if (dstMask == 65535) {
+			srcShift = 16;
+		}
+		else {
+			srcShift = 0;
+		}
+		while (((deltaX -= 1)) != 0) {
+			ditherThreshold = ditherMatrix4x4[ditherBase + ((ditherIndex = (ditherIndex + 1) & 3))];
+			sourceWord = long32At(srcIndex);
+			srcAlpha = sourceWord & 16777215;
+			if (!(srcAlpha == 0)) {
+
+				/* 0 < srcAlpha */
+				/* If we have to mix colors then just copy a single word */
+
+				destWord = long32At(dstIndex);
+				destWord = destWord & (~dstMask);
+
+				/* Expand from 16 to 32 bit by adding zero bits */
+
+				destWord = ((usqInt) destWord) >> srcShift;
+
+				/* Mix colors */
+
+				destWord = ((((usqInt) (destWord & 31744) << 9)) | (((usqInt) (destWord & 992) << 6))) | ((((usqInt) (destWord & 31) << 3)) | 4278190080UL);
+
+				/* And dither */
+
+				sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+				/* begin dither32To16:threshold: */
+
+				/* You bet */
+
+				addThreshold = ((usqInt) ditherThreshold << 8);
+				sourceWord = ((((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 16)) & 255)]) << 10)) + (((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 8)) & 255)]) << 5))) + (dither8Lookup[addThreshold + (sourceWord & 255)]);
+				if (sourceWord == 0) {
+					sourceWord = 1 << srcShift;
+				}
+				else {
+					sourceWord = sourceWord << srcShift;
+				}
+				/* begin dstLongAt:put:mask: */
+				dstValue = long32At(dstIndex);
+				dstValue = dstValue & dstMask;
+				dstValue = dstValue | sourceWord;
+				long32Atput(dstIndex, dstValue);
+			}
+			srcIndex += 4;
+			if (destMSB) {
+				if (srcShift == 0) {
+					dstIndex += 4;
+				}
+			}
+			else {
+				if (!(srcShift == 0)) {
+					dstIndex += 4;
+				}
+			}
+
+			/* Toggle between 0 and 16 */
+
+			srcShift = srcShift ^ 16;
+			dstMask = ~dstMask;
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = destPixSize = 32
+	sourceForm ~= destForm.
+	Note: The inner loop has been optimized for dealing
+	with the special case of aR = aG = aB = 0 
+	 */
+
+static sqInt
+rgbComponentAlpha32(void)
+{
+    register int deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    register int dstIndex;
+    sqInt dstY;
+    register int sourceWord;
+    sqInt srcAlpha;
+    register int srcIndex;
+    sqInt srcY;
+
+
+	/* This particular method should be optimized in itself */
+	/* Give the compile a couple of hints */
+	/* The following should be declared as pointers so the compiler will
+	notice that they're used for accessing memory locations 
+	(good to know on an Intel architecture) but then the increments
+	would be different between ST code and C code so must hope the
+	compiler notices what happens (MS Visual C does) */
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+
+	/* This is the outer loop */
+
+	dstY = dy;
+	while (((deltaY -= 1)) != 0) {
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + (dx * 4);
+
+		/* So we can pre-decrement */
+		/* This is the inner loop */
+
+		deltaX = bbW + 1;
+		while (((deltaX -= 1)) != 0) {
+			sourceWord = long32At(srcIndex);
+			srcAlpha = sourceWord & 16777215;
+			if (srcAlpha == 0) {
+				srcIndex += 4;
+
+				/* Now skip as many words as possible, */
+
+				dstIndex += 4;
+				while ((((deltaX -= 1)) != 0)
+				 && ((((sourceWord = long32At(srcIndex))) & 16777215) == 0)) {
+					srcIndex += 4;
+					dstIndex += 4;
+				}
+				deltaX += 1;
+			}
+			else {
+
+				/* 0 < srcAlpha */
+				/* If we have to mix colors then just copy a single word */
+
+				destWord = long32At(dstIndex);
+				destWord = rgbComponentAlpha32with(sourceWord, destWord);
+				long32Atput(dstIndex, destWord);
+				srcIndex += 4;
+				dstIndex += 4;
+			}
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	
+	componentAlphaModeColor is the color,
+	sourceWord contains an alpha value for each component of RGB
+	each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+	the rule is...
+	
+	color = componentAlphaModeColor.
+	colorAlpha = componentAlphaModeAlpha.
+	mask = sourceWord.
+	dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+	dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+	dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+	dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+	dst.B  */
+/*	Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord)
+{
+    sqInt a;
+    sqInt aA;
+    sqInt aB;
+    sqInt aG;
+    sqInt alpha;
+    sqInt answer;
+    sqInt aR;
+    sqInt b;
+    sqInt d;
+    sqInt dstMask;
+    sqInt g;
+    sqInt r;
+    sqInt s;
+    sqInt srcAlpha;
+    sqInt srcColor;
+
+	alpha = sourceWord;
+	if (alpha == 0) {
+		return destinationWord;
+	}
+	srcColor = componentAlphaModeColor;
+	srcAlpha = componentAlphaModeAlpha & 255;
+	aB = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aG = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aR = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aA = alpha & 255;
+	if (!(srcAlpha == 255)) {
+		aA = ((usqInt) (aA * srcAlpha)) >> 8;
+		aR = ((usqInt) (aR * srcAlpha)) >> 8;
+		aG = ((usqInt) (aG * srcAlpha)) >> 8;
+		aB = ((usqInt) (aB * srcAlpha)) >> 8;
+	}
+	dstMask = destinationWord;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	b = (((usqInt) (d * (255 - aB))) >> 8) + (((usqInt) (s * aB)) >> 8);
+	if (b > 255) {
+		b = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		b = gammaLookupTable[b];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	g = (((usqInt) (d * (255 - aG))) >> 8) + (((usqInt) (s * aG)) >> 8);
+	if (g > 255) {
+		g = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		g = gammaLookupTable[g];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	r = (((usqInt) (d * (255 - aR))) >> 8) + (((usqInt) (s * aR)) >> 8);
+	if (r > 255) {
+		r = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		r = gammaLookupTable[r];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+
+	/* no need to gamma correct alpha value ? */
+
+	a = (((usqInt) ((dstMask & 255) * (255 - aA))) >> 8) + aA;
+	if (a > 255) {
+		a = 255;
+	}
+	answer = (((((a << 8) + r) << 8) + g) << 8) + b;
+	return answer;
+}
+
+
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = 32
+	destPixSize = 8
+	sourceForm ~= destForm.
+	Note: This is not real blending since we don't have the source colors
+	available.  */
+
+static sqInt
+rgbComponentAlpha8(void)
+{
+    sqInt adjust;
+    sqInt deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    sqInt dstIndex;
+    sqInt dstMask;
+    sqInt dstValue;
+    sqInt dstY;
+    sqInt mapperFlags;
+    unsigned int *mappingTable;
+    sqInt pv;
+    sqInt sourceWord;
+    sqInt srcAlpha;
+    sqInt srcIndex;
+    sqInt srcShift;
+    sqInt srcY;
+    sqInt val;
+
+
+	/* This particular method should be optimized in itself */
+
+	mappingTable = default8To32Table();
+	mapperFlags = cmFlags & (~ColorMapNewStyle);
+
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+	dstY = dy;
+	mask1 = (dx & 3) * 8;
+	if (destMSB) {
+		mask1 = 24 - mask1;
+	}
+	mask2 = AllOnes ^ (255 << mask1);
+	if ((dx & 1) == 0) {
+		adjust = 0;
+	}
+	else {
+		adjust = 522133279;
+	}
+	if ((dy & 1) == 0) {
+		adjust = adjust ^ 522133279;
+	}
+	while (((deltaY -= 1)) != 0) {
+		adjust = adjust ^ 522133279;
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 2)) * 4);
+
+		/* So we can pre-decrement */
+
+		deltaX = bbW + 1;
+		srcShift = mask1;
+
+		/* This is the inner loop */
+
+		dstMask = mask2;
+		while (((deltaX -= 1)) != 0) {
+			sourceWord = ((long32At(srcIndex)) & (~adjust)) + adjust;
+
+			/* set srcAlpha to the average of the 3 separate aR,Ag,AB values */
+
+			srcAlpha = sourceWord & 16777215;
+			srcAlpha = (((((usqInt) srcAlpha) >> 16) + ((((usqInt) srcAlpha) >> 8) & 255)) + (srcAlpha & 255)) / 3;
+			if (srcAlpha > 31) {
+				if (srcAlpha > 224) {
+
+					/* Everything below 31 is transparent */
+					/* treat everything above 224 as opaque */
+
+					sourceWord = 4294967295UL;
+				}
+				destWord = long32At(dstIndex);
+				destWord = destWord & (~dstMask);
+				destWord = ((usqInt) destWord) >> srcShift;
+				destWord = mappingTable[destWord];
+				sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+				/* begin mapPixel:flags: */
+				pv = sourceWord;
+				if ((mapperFlags & ColorMapPresent) != 0) {
+					if ((mapperFlags & ColorMapFixedPart) != 0) {
+						/* begin rgbMapPixel:flags: */
+						val = (((cmShiftTable[0]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[0])) >> -(cmShiftTable[0])) : ((usqInt) (sourceWord & (cmMaskTable[0])) << (cmShiftTable[0])));
+						val = val | ((((cmShiftTable[1]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[1])) >> -(cmShiftTable[1])) : ((usqInt) (sourceWord & (cmMaskTable[1])) << (cmShiftTable[1]))));
+						val = val | ((((cmShiftTable[2]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[2])) >> -(cmShiftTable[2])) : ((usqInt) (sourceWord & (cmMaskTable[2])) << (cmShiftTable[2]))));
+						pv = val | ((((cmShiftTable[3]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[3])) >> -(cmShiftTable[3])) : ((usqInt) (sourceWord & (cmMaskTable[3])) << (cmShiftTable[3]))));
+						if ((pv == 0)
+						 && (sourceWord != 0)) {
+							pv = 1;
+						}
+					}
+					if ((mapperFlags & ColorMapIndexedPart) != 0) {
+						pv = cmLookupTable[pv & cmMask];
+					}
+				}
+				sourceWord = pv;
+
+				/* Store back */
+
+				sourceWord = sourceWord << srcShift;
+				/* begin dstLongAt:put:mask: */
+				dstValue = long32At(dstIndex);
+				dstValue = dstValue & dstMask;
+				dstValue = dstValue | sourceWord;
+				long32Atput(dstIndex, dstValue);
+			}
+			srcIndex += 4;
+			if (destMSB) {
+				if (srcShift == 0) {
+					dstIndex += 4;
+					srcShift = 24;
+					dstMask = 16777215;
+				}
+				else {
+					srcShift -= 8;
+					dstMask = (((usqInt) dstMask) >> 8) | 4278190080UL;
+				}
+			}
+			else {
+				if (srcShift == 32) {
+					dstIndex += 4;
+					srcShift = 0;
+					dstMask = 4294967040UL;
+				}
+				else {
+					srcShift += 8;
+					dstMask = (dstMask << 8) | 255;
+				}
+			}
+			adjust = adjust ^ 522133279;
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	
+	componentAlphaModeColor is the color,
+	sourceWord contains an alpha value for each component of RGB
+	each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+	the rule is...
+	
+	color = componentAlphaModeColor.
+	colorAlpha = componentAlphaModeAlpha.
+	mask = sourceWord.
+	dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+	dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+	dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+	dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+	dst.B  */
+/*	Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord)
+{
+    sqInt alpha;
+    sqInt d;
+    sqInt destPix;
+    sqInt i;
+    sqInt mask;
+    sqInt mask3;
+    sqInt p1;
+    sqInt p2;
+    sqInt result;
+    sqInt srcPix;
+    sqInt v;
+
+	alpha = sourceWord;
+	if (alpha == 0) {
+		return destinationWord;
+	}
+	/* begin partitionedRgbComponentAlpha:dest:nBits:nPartitions: */
+
+	/* partition mask starts at the right */
+
+	mask = maskTable[destDepth];
+	result = 0;
+	for (i = 1; i <= destPPW; i += 1) {
+		p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * destDepth);
+		p2 = ((usqInt) (destinationWord & mask)) >> ((i - 1) * destDepth);
+		if (!(destDepth == 32)) {
+			if (destDepth == 16) {
+				p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+				p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+			}
+			else {
+				p1 = (rgbMapfromto(p1, destDepth, 32)) | 4278190080UL;
+				p2 = (rgbMapfromto(p2, destDepth, 32)) | 4278190080UL;
+			}
+		}
+		v = rgbComponentAlpha32with(p1, p2);
+		if (!(destDepth == 32)) {
+			/* begin rgbMap:from:to: */
+			if (((d = destDepth - 32)) > 0) {
+
+				/* Expand to more bits by zero-fill */
+				/* Transfer mask */
+
+				mask3 = (1 << 32) - 1;
+				srcPix = v << d;
+				mask3 = mask3 << d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << destDepth;
+				srcPix = srcPix << d;
+				v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << destDepth));
+				goto l1;
+			}
+			else {
+				if (d == 0) {
+					if (32 == 5) {
+						v = v & 32767;
+						goto l1;
+					}
+					if (32 == 8) {
+						v = v & 16777215;
+						goto l1;
+					}
+					v = v;
+					goto l1;
+				}
+				if (v == 0) {
+					v = v;
+					goto l1;
+				}
+				d = 32 - destDepth;
+
+				/* Transfer mask */
+
+				mask3 = (1 << destDepth) - 1;
+				srcPix = ((usqInt) v) >> d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << destDepth;
+				srcPix = ((usqInt) srcPix) >> d;
+				destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << destDepth));
+				if (destPix == 0) {
+					v = 1;
+					goto l1;
+				}
+				v = destPix;
+				goto l1;
+			}
+		l1:	/* end rgbMap:from:to: */;
+		}
+		result = result | (v << ((i - 1) * destDepth));
+
+		/* slide left to next partition */
+
+		mask = mask << destDepth;
+	}
+	return result;
+}
+
+
 /*	Subract the pixels in the source and destination, color by color,
 	and return the sum of the absolute value of all the differences.
 	For non-rgb, return the number of differing pixels. */
@@ -5682,7 +6521,8 @@
 	if (noSource) {
 		return 0;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		return 0;
 	}
 	if (!(sourceDepth == 32)) {
@@ -5691,6 +6531,33 @@
 	if (sourceForm == destForm) {
 		return 0;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		return 0;
+	}
 	if (destDepth < 8) {
 		return 0;
 	}
@@ -5748,7 +6615,7 @@
 			destBits = (destPitch = 0);
 			destLocked = 1;
 		}
-		if (!(noSource)) {
+		if (!noSource) {
 			sourceHandle = interpreterProxy->fetchPointerofObject(FormBitsIndex, sourceForm);
 			if ((sourceHandle & 1)) {
 


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Sun Aug  7 13:36:19 PDT 2011
   + Mon Aug  8 12:00:18 PDT 2011

Modified: branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
===================================================================
--- branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c	2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c	2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99
+	VMPluginCodeGenerator VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
    from
-	BitBltSimulation VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99
+	BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e
  */
-static char __buildInfo[] = "BitBltSimulation VMMaker-oscog.40 uuid: 637db40c-33c6-4263-816e-1b8cc19e3c99 " __DATE__ ;
+static char __buildInfo[] = "BitBltSimulation VMMaker.oscog-eem.115 uuid: 9e410250-c808-4f95-a591-ef67d54f978e " __DATE__ ;
 
 
 
@@ -67,7 +67,7 @@
 #define FormHeightIndex 2
 #define FormWidthIndex 1
 #define GreenIndex 1
-#define OpTableSize 42
+#define OpTableSize 43
 #define RedIndex 0
 
 
@@ -149,6 +149,7 @@
 static sqInt partitionedMaxwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt partitionedMinwithnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt partitionedMulwithnBitsnPartitions(sqInt word1, sqInt word2, sqInt nBits, sqInt nParts);
+static sqInt partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts);
 static sqInt partitionedSubfromnBitsnPartitions(unsigned int word1, unsigned int word2, sqInt nBits, sqInt nParts);
 static sqInt performCopyLoop(void);
 static sqInt pickSourcePixelsflagssrcMaskdestMasksrcShiftIncdstShiftInc(sqInt nPixels, sqInt mapperFlags, sqInt srcMask, sqInt dstMask, sqInt srcShiftInc, sqInt dstShiftInc);
@@ -164,6 +165,11 @@
 static sqInt queryDestSurface(sqInt handle);
 static sqInt querySourceSurface(sqInt handle);
 static sqInt rgbAddwith(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha16(void);
+static sqInt rgbComponentAlpha32(void);
+static sqInt rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord);
+static sqInt rgbComponentAlpha8(void);
+static sqInt rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord);
 static sqInt rgbDiffwith(sqInt sourceWord, sqInt destinationWord);
 static sqInt rgbMap16To32(sqInt sourcePixel);
 static sqInt rgbMap32To32(sqInt sourcePixel);
@@ -214,6 +220,8 @@
 static unsigned int * cmMaskTable;
 static int * cmShiftTable;
 static sqInt combinationRule;
+static sqInt componentAlphaModeAlpha;
+static sqInt componentAlphaModeColor;
 static sqInt destBits;
 static sqInt destDelta;
 static sqInt destDepth;
@@ -242,6 +250,7 @@
 static sqInt dstBitShift;
 static sqInt dx;
 static sqInt dy;
+static unsigned char * gammaLookupTable;
 static sqInt halftoneBase;
 static sqInt halftoneForm;
 static sqInt halftoneHeight;
@@ -263,15 +272,15 @@
 };
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"BitBltPlugin VMMaker-oscog.40 (i)"
+	"BitBltPlugin VMMaker.oscog-eem.115 (i)"
 #else
-	"BitBltPlugin VMMaker-oscog.40 (e)"
+	"BitBltPlugin VMMaker.oscog-eem.115 (e)"
 #endif
 ;
 static sqInt noHalftone;
 static sqInt noSource;
 static sqInt nWords;
-static void *opTable[42];
+static void *opTable[43];
 static sqInt preload;
 static void * querySurfaceFn;
 static sqInt skew;
@@ -291,6 +300,7 @@
 static sqInt srcBitShift;
 static sqInt sx;
 static sqInt sy;
+static unsigned char * ungammaLookupTable;
 static void * unlockSurfaceFn;
 static sqInt vDir;
 static sqInt warpAlignMask;
@@ -755,7 +765,7 @@
 
 				dstIndex += 4;
 				while ((((deltaX -= 1)) != 0)
- && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 255)) {
+				 && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 255)) {
 					long32Atput(dstIndex, sourceWord);
 					srcIndex += 4;
 					dstIndex += 4;
@@ -773,7 +783,7 @@
 
 					dstIndex += 4;
 					while ((((deltaX -= 1)) != 0)
- && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 0)) {
+					 && ((((usqInt) ((sourceWord = long32At(srcIndex)))) >> 24) == 0)) {
 						srcIndex += 4;
 						dstIndex += 4;
 					}
@@ -1123,11 +1133,13 @@
     sqInt dWid;
     sqInt dxLowBits;
     sqInt endBits;
+    sqInt gammaLookupTableOop;
     sqInt pixPerM1;
     sqInt pixPerM11;
     sqInt startBits;
     sqInt sxLowBits;
     sqInt t;
+    sqInt ungammaLookupTableOop;
 
 	clipRange();
 	if ((bbW <= 0)
@@ -1135,19 +1147,65 @@
 
 		/* zero width or height; noop */
 
-		affectedL = affectedR = affectedT = affectedB = 0;
+		affectedL = (affectedR = (affectedT = (affectedB = 0)));
 		return null;
 	}
 	if (!(lockSurfaces())) {
 		return interpreterProxy->primitiveFail();
 	}
 	/* begin copyBitsLockedAndClipped */
+	if (combinationRule == 41) {
+
+		/* Try a shortcut for stuff that should be run as quickly as possible */
+		/* fetch the forecolor into componentAlphaModeColor. */
+
+		componentAlphaModeAlpha = 255;
+		componentAlphaModeColor = 16777215;
+		gammaLookupTable = null;
+		ungammaLookupTable = null;
+		if ((interpreterProxy->methodArgumentCount()) >= 2) {
+			componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+			if (!(!(interpreterProxy->failed()))) {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+			componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+			if (!(!(interpreterProxy->failed()))) {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+			if ((interpreterProxy->methodArgumentCount()) == 4) {
+				gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+				if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+					gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+				}
+				ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+				if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+					ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+				}
+			}
+		}
+		else {
+			if ((interpreterProxy->methodArgumentCount()) == 1) {
+				componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+				if (!(!(interpreterProxy->failed()))) {
+					interpreterProxy->primitiveFail();
+					goto l1;
+				}
+			}
+			else {
+				interpreterProxy->primitiveFail();
+				goto l1;
+			}
+		}
+	}
 	/* begin tryCopyingBitsQuickly */
 	if (noSource) {
 		done = 0;
 		goto l2;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		done = 0;
 		goto l2;
 	}
@@ -1159,6 +1217,37 @@
 		done = 0;
 		goto l2;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l2;
+		}
+		done = 0;
+		goto l2;
+	}
 	if (destDepth < 8) {
 		done = 0;
 		goto l2;
@@ -1241,7 +1330,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 	if (noSource) {
@@ -1285,7 +1374,7 @@
 		}
 		if ((sourceDepth != destDepth)
 		 || ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+		 || (sourceMSB != destMSB))) {
 			copyLoopPixMap();
 		}
 		else {
@@ -1343,7 +1432,7 @@
 
 		/* zero width and height; return the count */
 
-		affectedL = affectedR = affectedT = affectedB = 0;
+		affectedL = (affectedR = (affectedT = (affectedB = 0)));
 	}
 	if (hDir > 0) {
 		affectedL = dx;
@@ -1391,18 +1480,62 @@
     sqInt dWid;
     sqInt dxLowBits;
     sqInt endBits;
+    sqInt gammaLookupTableOop;
     sqInt pixPerM1;
     sqInt pixPerM11;
     sqInt startBits;
     sqInt sxLowBits;
     sqInt t;
+    sqInt ungammaLookupTableOop;
 
+	if (combinationRule == 41) {
+
+		/* Try a shortcut for stuff that should be run as quickly as possible */
+		/* fetch the forecolor into componentAlphaModeColor. */
+
+		componentAlphaModeAlpha = 255;
+		componentAlphaModeColor = 16777215;
+		gammaLookupTable = null;
+		ungammaLookupTable = null;
+		if ((interpreterProxy->methodArgumentCount()) >= 2) {
+			componentAlphaModeAlpha = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 2);
+			if (!(!(interpreterProxy->failed()))) {
+				return interpreterProxy->primitiveFail();
+			}
+			componentAlphaModeColor = interpreterProxy->stackIntegerValue((interpreterProxy->methodArgumentCount()) - 1);
+			if (!(!(interpreterProxy->failed()))) {
+				return interpreterProxy->primitiveFail();
+			}
+			if ((interpreterProxy->methodArgumentCount()) == 4) {
+				gammaLookupTableOop = interpreterProxy->stackObjectValue(1);
+				if (interpreterProxy->isBytes(gammaLookupTableOop)) {
+					gammaLookupTable = interpreterProxy->firstIndexableField(gammaLookupTableOop);
+				}
+				ungammaLookupTableOop = interpreterProxy->stackObjectValue(0);
+				if (interpreterProxy->isBytes(ungammaLookupTableOop)) {
+					ungammaLookupTable = interpreterProxy->firstIndexableField(ungammaLookupTableOop);
+				}
+			}
+		}
+		else {
+			if ((interpreterProxy->methodArgumentCount()) == 1) {
+				componentAlphaModeColor = interpreterProxy->stackIntegerValue(0);
+				if (!(!(interpreterProxy->failed()))) {
+					return interpreterProxy->primitiveFail();
+				}
+			}
+			else {
+				return interpreterProxy->primitiveFail();
+			}
+		}
+	}
 	/* begin tryCopyingBitsQuickly */
 	if (noSource) {
 		done = 0;
 		goto l1;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		done = 0;
 		goto l1;
 	}
@@ -1414,6 +1547,37 @@
 		done = 0;
 		goto l1;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			done = 1;
+			goto l1;
+		}
+		done = 0;
+		goto l1;
+	}
 	if (destDepth < 8) {
 		done = 0;
 		goto l1;
@@ -1494,7 +1658,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 	if (noSource) {
@@ -1538,7 +1702,7 @@
 		}
 		if ((sourceDepth != destDepth)
 		 || ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+		 || (sourceMSB != destMSB))) {
 			copyLoopPixMap();
 		}
 		else {
@@ -1596,7 +1760,7 @@
 
 		/* zero width and height; return the count */
 
-		affectedL = affectedR = affectedT = affectedB = 0;
+		affectedL = (affectedR = (affectedT = (affectedB = 0)));
 	}
 	if (hDir > 0) {
 		affectedL = dx;
@@ -1645,7 +1809,7 @@
 
 	hInc = hDir * 4;
 	if (skew == -32) {
-		skew = unskew = skewMask = 0;
+		skew = (unskew = (skewMask = 0));
 	}
 	else {
 		if (skew < 0) {
@@ -2008,7 +2172,7 @@
 							srcShift1 -= 32;
 						}
 						/* begin srcLongAt: */
-						idx = sourceIndex += 4;
+						idx = (sourceIndex += 4);
 						sourceWord = long32At(idx);
 					}
 				} while(!(((nPix1 -= 1)) == 0));
@@ -2054,7 +2218,7 @@
 							srcShift1 -= 32;
 						}
 						/* begin srcLongAt: */
-						idx1 = sourceIndex += 4;
+						idx1 = (sourceIndex += 4);
 						sourceWord = long32At(idx1);
 					}
 				} while(!(((nPix1 -= 1)) == 0));
@@ -2225,7 +2389,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 }
@@ -2290,8 +2454,8 @@
 
 	/* init null rectangle */
 
-	affL = affT = 9999;
-	affR = affB = -9999;
+	affL = (affT = 9999);
+	affR = (affB = -9999);
 	if (py > px) {
 
 		/* more horizontal */
@@ -2330,8 +2494,8 @@
 
 						/* init null rectangle */
 
-						affL = affT = 9999;
-						affR = affB = -9999;
+						affL = (affT = 9999);
+						affR = (affB = -9999);
 					}
 				}
 			}
@@ -2375,8 +2539,8 @@
 
 						/* init null rectangle */
 
-						affL = affT = 9999;
-						affR = affB = -9999;
+						affL = (affT = 9999);
+						affR = (affB = -9999);
 					}
 				}
 			}
@@ -2643,6 +2807,7 @@
 	opTable[38+1] = (void *)pixSwapwith;
 	opTable[39+1] = (void *)pixClearwith;
 	opTable[40+1] = (void *)fixAlphawith;
+	opTable[41+1] = (void *)rgbComponentAlphawith;
 }
 
 static sqInt
@@ -2715,12 +2880,12 @@
 	}
 	if (((shifts[RedIndex]) == 0)
 	 && (((shifts[GreenIndex]) == 0)
- && (((shifts[BlueIndex]) == 0)
- && (((shifts[AlphaIndex]) == 0)
- && (((masks[RedIndex]) == 16711680)
- && (((masks[GreenIndex]) == 65280)
- && (((masks[BlueIndex]) == 255)
- && ((masks[AlphaIndex]) == 4278190080UL)))))))) {
+	 && (((shifts[BlueIndex]) == 0)
+	 && (((shifts[AlphaIndex]) == 0)
+	 && (((masks[RedIndex]) == 16711680)
+	 && (((masks[GreenIndex]) == 65280)
+	 && (((masks[BlueIndex]) == 255)
+	 && ((masks[AlphaIndex]) == 4278190080UL)))))))) {
 		return 1;
 	}
 	return 0;
@@ -2753,7 +2918,7 @@
 			return 0;
 		}
 		destPPW = 32 / destDepth;
-		destBits = destPitch = 0;
+		destBits = (destPitch = 0);
 	}
 	else {
 		destPPW = 32 / destDepth;
@@ -2806,7 +2971,7 @@
 	combinationRule = interpreterProxy->fetchIntegerofObject(BBRuleIndex, bitBltOop);
 	if ((interpreterProxy->failed())
 	 || ((combinationRule < 0)
- || (combinationRule > (OpTableSize - 2)))) {
+	 || (combinationRule > (OpTableSize - 2)))) {
 		return 0;
 	}
 	if ((combinationRule >= 16)
@@ -2886,7 +3051,7 @@
 			goto l3;
 		}
 		destPPW = 32 / destDepth;
-		destBits = destPitch = 0;
+		destBits = (destPitch = 0);
 	}
 	else {
 		destPPW = 32 / destDepth;
@@ -2901,7 +3066,7 @@
 	}
 	ok = 1;
 l3:	/* end loadBitBltDestForm */;
-	if (!(ok)) {
+	if (!ok) {
 		return 0;
 	}
 	destX = fetchIntOrFloatofObjectifNil(BBDestXIndex, bitBltOop, 0);
@@ -2912,7 +3077,7 @@
 		return 0;
 	}
 	if (noSource) {
-		sourceX = sourceY = 0;
+		sourceX = (sourceY = 0);
 	}
 	else {
 		if (!((interpreterProxy->isPointers(sourceForm))
@@ -2967,7 +3132,7 @@
 				goto l10;
 			}
 			sourcePPW = 32 / sourceDepth;
-			sourceBits = sourcePitch = 0;
+			sourceBits = (sourcePitch = 0);
 		}
 		else {
 			sourcePPW = 32 / sourceDepth;
@@ -2982,11 +3147,11 @@
 		}
 		ok = 1;
 	l10:	/* end loadBitBltSourceForm */;
-		if (!(ok)) {
+		if (!ok) {
 			return 0;
 		}
 		/* begin loadColorMap */
-		cmFlags = cmMask = cmBitsPerColor = 0;
+		cmFlags = (cmMask = (cmBitsPerColor = 0));
 		cmShiftTable = null;
 		cmMaskTable = null;
 		cmLookupTable = null;
@@ -3102,7 +3267,7 @@
 		}
 		ok = 1;
 	l4:	/* end loadColorMap */;
-		if (!(ok)) {
+		if (!ok) {
 			return 0;
 		}
 		if ((cmFlags & ColorMapNewStyle) == 0) {
@@ -3140,7 +3305,7 @@
 	halftoneBase = oopForPointer(interpreterProxy->firstIndexableField(halftoneBits));
 	ok = 1;
 l5:	/* end loadHalftoneForm */;
-	if (!(ok)) {
+	if (!ok) {
 		return 0;
 	}
 	clipX = fetchIntOrFloatofObjectifNil(BBClipXIndex, bitBltOop, 0);
@@ -3226,7 +3391,7 @@
 			return 0;
 		}
 		sourcePPW = 32 / sourceDepth;
-		sourceBits = sourcePitch = 0;
+		sourceBits = (sourcePitch = 0);
 	}
 	else {
 		sourcePPW = 32 / sourceDepth;
@@ -3256,7 +3421,7 @@
     sqInt oldStyle;
     sqInt oop;
 
-	cmFlags = cmMask = cmBitsPerColor = 0;
+	cmFlags = (cmMask = (cmBitsPerColor = 0));
 	cmShiftTable = null;
 	cmMaskTable = null;
 	cmLookupTable = null;
@@ -3433,7 +3598,7 @@
 	unlockSurfaceFn = interpreterProxy->ioLoadFunctionFrom("ioUnlockSurface", "SurfacePlugin");
 	return (querySurfaceFn != 0)
 	 && ((lockSurfaceFn != 0)
- && (unlockSurfaceFn != 0));
+	 && (unlockSurfaceFn != 0));
 }
 
 static sqInt
@@ -3554,7 +3719,7 @@
 	}
 	return (destBits != 0)
 	 && ((sourceBits != 0)
- || (noSource));
+	 || (noSource));
 }
 
 
@@ -3607,7 +3772,7 @@
 moduleUnloaded(char *aModuleName)
 {
 	if ((strcmp(aModuleName, "SurfacePlugin")) == 0) {
-		querySurfaceFn = lockSurfaceFn = unlockSurfaceFn = 0;
+		querySurfaceFn = (lockSurfaceFn = (unlockSurfaceFn = 0));
 	}
 }
 
@@ -4047,7 +4212,101 @@
 	return result;
 }
 
+static sqInt
+partitionedRgbComponentAlphadestnBitsnPartitions(sqInt sourceWord, sqInt destWord, sqInt nBits, sqInt nParts)
+{
+    sqInt d;
+    sqInt destPix;
+    sqInt i;
+    sqInt mask;
+    sqInt mask3;
+    sqInt p1;
+    sqInt p2;
+    sqInt result;
+    sqInt srcPix;
+    sqInt v;
 
+
+	/* partition mask starts at the right */
+
+	mask = maskTable[nBits];
+	result = 0;
+	for (i = 1; i <= nParts; i += 1) {
+		p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * nBits);
+		p2 = ((usqInt) (destWord & mask)) >> ((i - 1) * nBits);
+		if (!(nBits == 32)) {
+			if (nBits == 16) {
+				p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+				p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+			}
+			else {
+				p1 = (rgbMapfromto(p1, nBits, 32)) | 4278190080UL;
+				p2 = (rgbMapfromto(p2, nBits, 32)) | 4278190080UL;
+			}
+		}
+		v = rgbComponentAlpha32with(p1, p2);
+		if (!(nBits == 32)) {
+			/* begin rgbMap:from:to: */
+			if (((d = nBits - 32)) > 0) {
+
+				/* Expand to more bits by zero-fill */
+				/* Transfer mask */
+
+				mask3 = (1 << 32) - 1;
+				srcPix = v << d;
+				mask3 = mask3 << d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << nBits;
+				srcPix = srcPix << d;
+				v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << nBits));
+				goto l1;
+			}
+			else {
+				if (d == 0) {
+					if (32 == 5) {
+						v = v & 32767;
+						goto l1;
+					}
+					if (32 == 8) {
+						v = v & 16777215;
+						goto l1;
+					}
+					v = v;
+					goto l1;
+				}
+				if (v == 0) {
+					v = v;
+					goto l1;
+				}
+				d = 32 - nBits;
+
+				/* Transfer mask */
+
+				mask3 = (1 << nBits) - 1;
+				srcPix = ((usqInt) v) >> d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << nBits;
+				srcPix = ((usqInt) srcPix) >> d;
+				destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << nBits));
+				if (destPix == 0) {
+					v = 1;
+					goto l1;
+				}
+				v = destPix;
+				goto l1;
+			}
+		l1:	/* end rgbMap:from:to: */;
+		}
+		result = result | (v << ((i - 1) * nBits));
+
+		/* slide left to next partition */
+
+		mask = mask << nBits;
+	}
+	return result;
+}
+
+
 /*	Subtract word1 from word2 as nParts partitions of nBits each.
 	This is useful for packed pixels, or packed colors */
 /*	In C, most arithmetic operations answer the same bit pattern regardless of
@@ -4141,7 +4400,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 	if (noSource) {
@@ -4185,7 +4444,7 @@
 		}
 		if ((sourceDepth != destDepth)
 		 || ((cmFlags != 0)
- || (sourceMSB != destMSB))) {
+		 || (sourceMSB != destMSB))) {
 			copyLoopPixMap();
 		}
 		else {
@@ -4303,7 +4562,7 @@
 					srcShift -= 32;
 				}
 				/* begin srcLongAt: */
-				idx = sourceIndex += 4;
+				idx = (sourceIndex += 4);
 				sourceWord = long32At(idx);
 			}
 		} while(!(((nPix -= 1)) == 0));
@@ -4349,7 +4608,7 @@
 					srcShift -= 32;
 				}
 				/* begin srcLongAt: */
-				idx1 = sourceIndex += 4;
+				idx1 = (sourceIndex += 4);
 				sourceWord = long32At(idx1);
 			}
 		} while(!(((nPix -= 1)) == 0));
@@ -4377,8 +4636,8 @@
 
 	if ((xx < 0)
 	 || ((yy < 0)
- || ((((x = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
+	 || ((((x = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
+	 || (((y = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
 		return 0;
 	}
 	srcIndex = (sourceBits + (y * sourcePitch)) + ((((usqInt) x) >> warpAlignShift) * 4);
@@ -4581,7 +4840,7 @@
 	}
 	if (!((startIndex > 0)
 		 && ((stopIndex > 0)
- && (stopIndex <= (interpreterProxy->byteSizeOf(sourceString)))))) {
+		 && (stopIndex <= (interpreterProxy->byteSizeOf(sourceString)))))) {
 		return interpreterProxy->primitiveFail();
 	}
 	bbObj = interpreterProxy->stackObjectValue(6);
@@ -4594,11 +4853,11 @@
 	}
 	quickBlt = (destBits != 0)
 	 && ((sourceBits != 0)
- && ((noSource == 0)
- && ((sourceForm != destForm)
- && ((cmFlags != 0)
- || ((sourceMSB != destMSB)
- || (sourceDepth != destDepth))))));
+	 && ((noSource == 0)
+	 && ((sourceForm != destForm)
+	 && ((cmFlags != 0)
+	 || ((sourceMSB != destMSB)
+	 || (sourceDepth != destDepth))))));
 	left = destX;
 	sourcePtr = interpreterProxy->firstIndexableField(sourceString);
 	for (charIndex = startIndex; charIndex <= stopIndex; charIndex += 1) {
@@ -4650,7 +4909,7 @@
 				/* calculate byte addr and delta, based on first word of data */
 				/* Note pitch is bytes and nWords is longs, not bytes */
 
-				hDir = vDir = 1;
+				hDir = (vDir = 1);
 				destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 				destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 				copyLoopPixMap();
@@ -4729,8 +4988,8 @@
 
 		/* init null rectangle */
 
-		affL = affT = 9999;
-		affR = affB = -9999;
+		affL = (affT = 9999);
+		affR = (affB = -9999);
 		if (py > px) {
 
 			/* more horizontal */
@@ -4769,8 +5028,8 @@
 
 							/* init null rectangle */
 
-							affL = affT = 9999;
-							affR = affB = -9999;
+							affL = (affT = 9999);
+							affR = (affB = -9999);
 						}
 					}
 				}
@@ -4814,8 +5073,8 @@
 
 							/* init null rectangle */
 
-							affL = affT = 9999;
-							affR = affB = -9999;
+							affL = (affT = 9999);
+							affR = (affB = -9999);
 						}
 					}
 				}
@@ -4864,11 +5123,11 @@
 	noSource = ns;
 	if (noSource
 	 || ((bbW <= 0)
- || (bbH <= 0))) {
+	 || (bbH <= 0))) {
 
 		/* zero width or height; noop */
 
-		affectedL = affectedR = affectedT = affectedB = 0;
+		affectedL = (affectedR = (affectedT = (affectedB = 0)));
 		goto l1;
 	}
 	if (!(lockSurfaces())) {
@@ -4908,7 +5167,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 	warpLoop();
@@ -4996,6 +5255,586 @@
 }
 
 
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = 32
+	destPixSize = 16
+	sourceForm ~= destForm.
+	 */
+/*	This particular method should be optimized in itself */
+
+static sqInt
+rgbComponentAlpha16(void)
+{
+    sqInt addThreshold;
+    sqInt deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    sqInt ditherBase;
+    sqInt ditherIndex;
+    sqInt ditherThreshold;
+    sqInt dstIndex;
+    sqInt dstMask;
+    sqInt dstValue;
+    sqInt dstY;
+    sqInt sourceWord;
+    sqInt srcAlpha;
+    sqInt srcIndex;
+    sqInt srcShift;
+    sqInt srcY;
+
+
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+	dstY = dy;
+	srcShift = (dx & 1) * 16;
+	if (destMSB) {
+		srcShift = 16 - srcShift;
+	}
+
+	/* This is the outer loop */
+
+	mask1 = 65535 << (16 - srcShift);
+	while (((deltaY -= 1)) != 0) {
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 1)) * 4);
+		ditherBase = (dstY & 3) * 4;
+
+		/* For pre-increment */
+
+		ditherIndex = (sx & 3) - 1;
+
+		/* So we can pre-decrement */
+
+		deltaX = bbW + 1;
+		dstMask = mask1;
+		if (dstMask == 65535) {
+			srcShift = 16;
+		}
+		else {
+			srcShift = 0;
+		}
+		while (((deltaX -= 1)) != 0) {
+			ditherThreshold = ditherMatrix4x4[ditherBase + ((ditherIndex = (ditherIndex + 1) & 3))];
+			sourceWord = long32At(srcIndex);
+			srcAlpha = sourceWord & 16777215;
+			if (!(srcAlpha == 0)) {
+
+				/* 0 < srcAlpha */
+				/* If we have to mix colors then just copy a single word */
+
+				destWord = long32At(dstIndex);
+				destWord = destWord & (~dstMask);
+
+				/* Expand from 16 to 32 bit by adding zero bits */
+
+				destWord = ((usqInt) destWord) >> srcShift;
+
+				/* Mix colors */
+
+				destWord = ((((usqInt) (destWord & 31744) << 9)) | (((usqInt) (destWord & 992) << 6))) | ((((usqInt) (destWord & 31) << 3)) | 4278190080UL);
+
+				/* And dither */
+
+				sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+				/* begin dither32To16:threshold: */
+
+				/* You bet */
+
+				addThreshold = ((usqInt) ditherThreshold << 8);
+				sourceWord = ((((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 16)) & 255)]) << 10)) + (((usqInt) (dither8Lookup[addThreshold + ((((usqInt) sourceWord >> 8)) & 255)]) << 5))) + (dither8Lookup[addThreshold + (sourceWord & 255)]);
+				if (sourceWord == 0) {
+					sourceWord = 1 << srcShift;
+				}
+				else {
+					sourceWord = sourceWord << srcShift;
+				}
+				/* begin dstLongAt:put:mask: */
+				dstValue = long32At(dstIndex);
+				dstValue = dstValue & dstMask;
+				dstValue = dstValue | sourceWord;
+				long32Atput(dstIndex, dstValue);
+			}
+			srcIndex += 4;
+			if (destMSB) {
+				if (srcShift == 0) {
+					dstIndex += 4;
+				}
+			}
+			else {
+				if (!(srcShift == 0)) {
+					dstIndex += 4;
+				}
+			}
+
+			/* Toggle between 0 and 16 */
+
+			srcShift = srcShift ^ 16;
+			dstMask = ~dstMask;
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = destPixSize = 32
+	sourceForm ~= destForm.
+	Note: The inner loop has been optimized for dealing
+	with the special case of aR = aG = aB = 0 
+	 */
+
+static sqInt
+rgbComponentAlpha32(void)
+{
+    register int deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    register int dstIndex;
+    sqInt dstY;
+    register int sourceWord;
+    sqInt srcAlpha;
+    register int srcIndex;
+    sqInt srcY;
+
+
+	/* This particular method should be optimized in itself */
+	/* Give the compile a couple of hints */
+	/* The following should be declared as pointers so the compiler will
+	notice that they're used for accessing memory locations 
+	(good to know on an Intel architecture) but then the increments
+	would be different between ST code and C code so must hope the
+	compiler notices what happens (MS Visual C does) */
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+
+	/* This is the outer loop */
+
+	dstY = dy;
+	while (((deltaY -= 1)) != 0) {
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + (dx * 4);
+
+		/* So we can pre-decrement */
+		/* This is the inner loop */
+
+		deltaX = bbW + 1;
+		while (((deltaX -= 1)) != 0) {
+			sourceWord = long32At(srcIndex);
+			srcAlpha = sourceWord & 16777215;
+			if (srcAlpha == 0) {
+				srcIndex += 4;
+
+				/* Now skip as many words as possible, */
+
+				dstIndex += 4;
+				while ((((deltaX -= 1)) != 0)
+				 && ((((sourceWord = long32At(srcIndex))) & 16777215) == 0)) {
+					srcIndex += 4;
+					dstIndex += 4;
+				}
+				deltaX += 1;
+			}
+			else {
+
+				/* 0 < srcAlpha */
+				/* If we have to mix colors then just copy a single word */
+
+				destWord = long32At(dstIndex);
+				destWord = rgbComponentAlpha32with(sourceWord, destWord);
+				long32Atput(dstIndex, destWord);
+				srcIndex += 4;
+				dstIndex += 4;
+			}
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	
+	componentAlphaModeColor is the color,
+	sourceWord contains an alpha value for each component of RGB
+	each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+	the rule is...
+	
+	color = componentAlphaModeColor.
+	colorAlpha = componentAlphaModeAlpha.
+	mask = sourceWord.
+	dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+	dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+	dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+	dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+	dst.B  */
+/*	Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlpha32with(sqInt sourceWord, sqInt destinationWord)
+{
+    sqInt a;
+    sqInt aA;
+    sqInt aB;
+    sqInt aG;
+    sqInt alpha;
+    sqInt answer;
+    sqInt aR;
+    sqInt b;
+    sqInt d;
+    sqInt dstMask;
+    sqInt g;
+    sqInt r;
+    sqInt s;
+    sqInt srcAlpha;
+    sqInt srcColor;
+
+	alpha = sourceWord;
+	if (alpha == 0) {
+		return destinationWord;
+	}
+	srcColor = componentAlphaModeColor;
+	srcAlpha = componentAlphaModeAlpha & 255;
+	aB = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aG = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aR = alpha & 255;
+	alpha = ((usqInt) alpha) >> 8;
+	aA = alpha & 255;
+	if (!(srcAlpha == 255)) {
+		aA = ((usqInt) (aA * srcAlpha)) >> 8;
+		aR = ((usqInt) (aR * srcAlpha)) >> 8;
+		aG = ((usqInt) (aG * srcAlpha)) >> 8;
+		aB = ((usqInt) (aB * srcAlpha)) >> 8;
+	}
+	dstMask = destinationWord;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	b = (((usqInt) (d * (255 - aB))) >> 8) + (((usqInt) (s * aB)) >> 8);
+	if (b > 255) {
+		b = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		b = gammaLookupTable[b];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	g = (((usqInt) (d * (255 - aG))) >> 8) + (((usqInt) (s * aG)) >> 8);
+	if (g > 255) {
+		g = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		g = gammaLookupTable[g];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+	d = dstMask & 255;
+	s = srcColor & 255;
+	if (!(ungammaLookupTable == null)) {
+		d = ungammaLookupTable[d];
+		s = ungammaLookupTable[s];
+	}
+	r = (((usqInt) (d * (255 - aR))) >> 8) + (((usqInt) (s * aR)) >> 8);
+	if (r > 255) {
+		r = 255;
+	}
+	if (!(gammaLookupTable == null)) {
+		r = gammaLookupTable[r];
+	}
+	dstMask = ((usqInt) dstMask) >> 8;
+	srcColor = ((usqInt) srcColor) >> 8;
+
+	/* no need to gamma correct alpha value ? */
+
+	a = (((usqInt) ((dstMask & 255) * (255 - aA))) >> 8) + aA;
+	if (a > 255) {
+		a = 255;
+	}
+	answer = (((((a << 8) + r) << 8) + g) << 8) + b;
+	return answer;
+}
+
+
+/*	This version assumes 
+	combinationRule = 41
+	sourcePixSize = 32
+	destPixSize = 8
+	sourceForm ~= destForm.
+	Note: This is not real blending since we don't have the source colors
+	available.  */
+
+static sqInt
+rgbComponentAlpha8(void)
+{
+    sqInt adjust;
+    sqInt deltaX;
+    sqInt deltaY;
+    sqInt destWord;
+    sqInt dstIndex;
+    sqInt dstMask;
+    sqInt dstValue;
+    sqInt dstY;
+    sqInt mapperFlags;
+    unsigned int *mappingTable;
+    sqInt pv;
+    sqInt sourceWord;
+    sqInt srcAlpha;
+    sqInt srcIndex;
+    sqInt srcShift;
+    sqInt srcY;
+    sqInt val;
+
+
+	/* This particular method should be optimized in itself */
+
+	mappingTable = default8To32Table();
+	mapperFlags = cmFlags & (~ColorMapNewStyle);
+
+	/* So we can pre-decrement */
+
+	deltaY = bbH + 1;
+	srcY = sy;
+	dstY = dy;
+	mask1 = (dx & 3) * 8;
+	if (destMSB) {
+		mask1 = 24 - mask1;
+	}
+	mask2 = AllOnes ^ (255 << mask1);
+	if ((dx & 1) == 0) {
+		adjust = 0;
+	}
+	else {
+		adjust = 522133279;
+	}
+	if ((dy & 1) == 0) {
+		adjust = adjust ^ 522133279;
+	}
+	while (((deltaY -= 1)) != 0) {
+		adjust = adjust ^ 522133279;
+		srcIndex = (sourceBits + (srcY * sourcePitch)) + (sx * 4);
+		dstIndex = (destBits + (dstY * destPitch)) + ((((sqInt) dx >> 2)) * 4);
+
+		/* So we can pre-decrement */
+
+		deltaX = bbW + 1;
+		srcShift = mask1;
+
+		/* This is the inner loop */
+
+		dstMask = mask2;
+		while (((deltaX -= 1)) != 0) {
+			sourceWord = ((long32At(srcIndex)) & (~adjust)) + adjust;
+
+			/* set srcAlpha to the average of the 3 separate aR,Ag,AB values */
+
+			srcAlpha = sourceWord & 16777215;
+			srcAlpha = (((((usqInt) srcAlpha) >> 16) + ((((usqInt) srcAlpha) >> 8) & 255)) + (srcAlpha & 255)) / 3;
+			if (srcAlpha > 31) {
+				if (srcAlpha > 224) {
+
+					/* Everything below 31 is transparent */
+					/* treat everything above 224 as opaque */
+
+					sourceWord = 4294967295UL;
+				}
+				destWord = long32At(dstIndex);
+				destWord = destWord & (~dstMask);
+				destWord = ((usqInt) destWord) >> srcShift;
+				destWord = mappingTable[destWord];
+				sourceWord = rgbComponentAlpha32with(sourceWord, destWord);
+				/* begin mapPixel:flags: */
+				pv = sourceWord;
+				if ((mapperFlags & ColorMapPresent) != 0) {
+					if ((mapperFlags & ColorMapFixedPart) != 0) {
+						/* begin rgbMapPixel:flags: */
+						val = (((cmShiftTable[0]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[0])) >> -(cmShiftTable[0])) : ((usqInt) (sourceWord & (cmMaskTable[0])) << (cmShiftTable[0])));
+						val = val | ((((cmShiftTable[1]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[1])) >> -(cmShiftTable[1])) : ((usqInt) (sourceWord & (cmMaskTable[1])) << (cmShiftTable[1]))));
+						val = val | ((((cmShiftTable[2]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[2])) >> -(cmShiftTable[2])) : ((usqInt) (sourceWord & (cmMaskTable[2])) << (cmShiftTable[2]))));
+						pv = val | ((((cmShiftTable[3]) < 0) ? ((usqInt) (sourceWord & (cmMaskTable[3])) >> -(cmShiftTable[3])) : ((usqInt) (sourceWord & (cmMaskTable[3])) << (cmShiftTable[3]))));
+						if ((pv == 0)
+						 && (sourceWord != 0)) {
+							pv = 1;
+						}
+					}
+					if ((mapperFlags & ColorMapIndexedPart) != 0) {
+						pv = cmLookupTable[pv & cmMask];
+					}
+				}
+				sourceWord = pv;
+
+				/* Store back */
+
+				sourceWord = sourceWord << srcShift;
+				/* begin dstLongAt:put:mask: */
+				dstValue = long32At(dstIndex);
+				dstValue = dstValue & dstMask;
+				dstValue = dstValue | sourceWord;
+				long32Atput(dstIndex, dstValue);
+			}
+			srcIndex += 4;
+			if (destMSB) {
+				if (srcShift == 0) {
+					dstIndex += 4;
+					srcShift = 24;
+					dstMask = 16777215;
+				}
+				else {
+					srcShift -= 8;
+					dstMask = (((usqInt) dstMask) >> 8) | 4278190080UL;
+				}
+			}
+			else {
+				if (srcShift == 32) {
+					dstIndex += 4;
+					srcShift = 0;
+					dstMask = 4294967040UL;
+				}
+				else {
+					srcShift += 8;
+					dstMask = (dstMask << 8) | 255;
+				}
+			}
+			adjust = adjust ^ 522133279;
+		}
+		srcY += 1;
+		dstY += 1;
+	}
+}
+
+
+/*	
+	componentAlphaModeColor is the color,
+	sourceWord contains an alpha value for each component of RGB
+	each of which is encoded as0 meaning 0.0 and 255 meaning 1.0 .
+	the rule is...
+	
+	color = componentAlphaModeColor.
+	colorAlpha = componentAlphaModeAlpha.
+	mask = sourceWord.
+	dst.A = colorAlpha + (1 - colorAlpha) * dst.A
+	dst.R = color.R * mask.R * colorAlpha + (1 - (mask.R * colorAlpha)) *
+	dst.R dst.G = color.G * mask.G * colorAlpha + (1 - (mask.G* colorAlpha)) *
+	dst.G dst.B = color.B * mask.B * colorAlpha + (1 - (mask.B* colorAlpha)) *
+	dst.B  */
+/*	Do NOT inline this into optimized loops */
+
+static sqInt
+rgbComponentAlphawith(sqInt sourceWord, sqInt destinationWord)
+{
+    sqInt alpha;
+    sqInt d;
+    sqInt destPix;
+    sqInt i;
+    sqInt mask;
+    sqInt mask3;
+    sqInt p1;
+    sqInt p2;
+    sqInt result;
+    sqInt srcPix;
+    sqInt v;
+
+	alpha = sourceWord;
+	if (alpha == 0) {
+		return destinationWord;
+	}
+	/* begin partitionedRgbComponentAlpha:dest:nBits:nPartitions: */
+
+	/* partition mask starts at the right */
+
+	mask = maskTable[destDepth];
+	result = 0;
+	for (i = 1; i <= destPPW; i += 1) {
+		p1 = ((usqInt) (sourceWord & mask)) >> ((i - 1) * destDepth);
+		p2 = ((usqInt) (destinationWord & mask)) >> ((i - 1) * destDepth);
+		if (!(destDepth == 32)) {
+			if (destDepth == 16) {
+				p1 = ((((p1 & 31) << 3) | ((p1 & 992) << 6)) | ((p1 & 31744) << 9)) | 4278190080UL;
+				p2 = ((((p2 & 31) << 3) | ((p2 & 992) << 6)) | ((p2 & 31744) << 9)) | 4278190080UL;
+			}
+			else {
+				p1 = (rgbMapfromto(p1, destDepth, 32)) | 4278190080UL;
+				p2 = (rgbMapfromto(p2, destDepth, 32)) | 4278190080UL;
+			}
+		}
+		v = rgbComponentAlpha32with(p1, p2);
+		if (!(destDepth == 32)) {
+			/* begin rgbMap:from:to: */
+			if (((d = destDepth - 32)) > 0) {
+
+				/* Expand to more bits by zero-fill */
+				/* Transfer mask */
+
+				mask3 = (1 << 32) - 1;
+				srcPix = v << d;
+				mask3 = mask3 << d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << destDepth;
+				srcPix = srcPix << d;
+				v = (destPix + (srcPix & mask3)) + ((srcPix << d) & (mask3 << destDepth));
+				goto l1;
+			}
+			else {
+				if (d == 0) {
+					if (32 == 5) {
+						v = v & 32767;
+						goto l1;
+					}
+					if (32 == 8) {
+						v = v & 16777215;
+						goto l1;
+					}
+					v = v;
+					goto l1;
+				}
+				if (v == 0) {
+					v = v;
+					goto l1;
+				}
+				d = 32 - destDepth;
+
+				/* Transfer mask */
+
+				mask3 = (1 << destDepth) - 1;
+				srcPix = ((usqInt) v) >> d;
+				destPix = srcPix & mask3;
+				mask3 = mask3 << destDepth;
+				srcPix = ((usqInt) srcPix) >> d;
+				destPix = (destPix + (srcPix & mask3)) + ((((usqInt) srcPix) >> d) & (mask3 << destDepth));
+				if (destPix == 0) {
+					v = 1;
+					goto l1;
+				}
+				v = destPix;
+				goto l1;
+			}
+		l1:	/* end rgbMap:from:to: */;
+		}
+		result = result | (v << ((i - 1) * destDepth));
+
+		/* slide left to next partition */
+
+		mask = mask << destDepth;
+	}
+	return result;
+}
+
+
 /*	Subract the pixels in the source and destination, color by color,
 	and return the sum of the absolute value of all the differences.
 	For non-rgb, return the number of differing pixels. */
@@ -5342,7 +6181,7 @@
     sqInt bits;
     sqInt targetBits;
 
-	bits = targetBits = 0;
+	bits = (targetBits = 0);
 	if (sourceDepth <= 8) {
 		return null;
 	}
@@ -5682,7 +6521,8 @@
 	if (noSource) {
 		return 0;
 	}
-	if (!(combinationRule == 34)) {
+	if (!((combinationRule == 34)
+		 || (combinationRule == 41))) {
 		return 0;
 	}
 	if (!(sourceDepth == 32)) {
@@ -5691,6 +6531,33 @@
 	if (sourceForm == destForm) {
 		return 0;
 	}
+	if (combinationRule == 41) {
+		if (destDepth == 32) {
+			rgbComponentAlpha32();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		if (destDepth == 16) {
+			rgbComponentAlpha16();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		if (destDepth == 8) {
+			rgbComponentAlpha8();
+			affectedL = dx;
+			affectedR = dx + bbW;
+			affectedT = dy;
+			affectedB = dy + bbH;
+			return 1;
+		}
+		return 0;
+	}
 	if (destDepth < 8) {
 		return 0;
 	}
@@ -5745,10 +6612,10 @@
 
 			destHandle = (destHandle >> 1);
 			fn(destHandle, affectedL, affectedT, affectedR-affectedL, affectedB-affectedT);
-			destBits = destPitch = 0;
+			destBits = (destPitch = 0);
 			destLocked = 1;
 		}
-		if (!(noSource)) {
+		if (!noSource) {
 			sourceHandle = interpreterProxy->fetchPointerofObject(FormBitsIndex, sourceForm);
 			if ((sourceHandle & 1)) {
 
@@ -5759,7 +6626,7 @@
 					 && (sourceHandle == destHandle))) {
 					fn(sourceHandle, 0, 0, 0, 0);
 				}
-				sourceBits = sourcePitch = 0;
+				sourceBits = (sourcePitch = 0);
 			}
 		}
 		hasSurfaceLock = 0;
@@ -5780,11 +6647,11 @@
 	noSource = ns;
 	if (noSource
 	 || ((bbW <= 0)
- || (bbH <= 0))) {
+	 || (bbH <= 0))) {
 
 		/* zero width or height; noop */
 
-		affectedL = affectedR = affectedT = affectedB = 0;
+		affectedL = (affectedR = (affectedT = (affectedB = 0)));
 		return null;
 	}
 	if (!(lockSurfaces())) {
@@ -5823,7 +6690,7 @@
 	/* calculate byte addr and delta, based on first word of data */
 	/* Note pitch is bytes and nWords is longs, not bytes */
 
-	hDir = vDir = 1;
+	hDir = (vDir = 1);
 	destIndex = (destBits + (dy * destPitch)) + ((dx / destPPW) * 4);
 	destDelta = (destPitch * vDir) - (4 * (nWords * hDir));
 	warpLoop();
@@ -6286,8 +7153,8 @@
 						/* begin pickWarpPixelAtX:y: */
 						if ((sx < 0)
 						 || ((sy < 0)
- || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+						 || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+						 || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
 							sourcePix = 0;
 							goto l15;
 						}
@@ -6312,8 +7179,8 @@
 						/* begin pickWarpPixelAtX:y: */
 						if ((sx < 0)
 						 || ((sy < 0)
- || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+						 || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+						 || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
 							sourcePix = 0;
 							goto l16;
 						}
@@ -6504,7 +7371,7 @@
 
 		/* Pick and average n*n subpixels */
 
-		a = r = g = b = 0;
+		a = (r = (g = (b = 0)));
 
 		/* actual number of pixels (not clipped and not transparent) */
 
@@ -6518,8 +7385,8 @@
 				/* begin pickWarpPixelAtX:y: */
 				if ((xx < 0)
 				 || ((yy < 0)
- || ((((x1 = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
+				 || ((((x1 = ((usqInt) xx) >> BinaryPoint)) >= sourceWidth)
+				 || (((y1 = ((usqInt) yy) >> BinaryPoint)) >= sourceHeight)))) {
 					rgb = 0;
 					goto l1;
 				}
@@ -6565,7 +7432,7 @@
 		} while(!(((j -= 1)) == 0));
 		if ((nPix == 0)
 		 || ((combinationRule == 25)
- && (nPix < (((sqInt) (n * n) >> 1))))) {
+		 && (nPix < (((sqInt) (n * n) >> 1))))) {
 
 			/* All pixels were 0, or most were transparent */
 
@@ -6665,8 +7532,8 @@
 			/* begin pickWarpPixelAtX:y: */
 			if ((sx < 0)
 			 || ((sy < 0)
- || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+			 || ((((x = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+			 || (((y = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
 				sourcePix = 0;
 				goto l1;
 			}
@@ -6691,8 +7558,8 @@
 			/* begin pickWarpPixelAtX:y: */
 			if ((sx < 0)
 			 || ((sy < 0)
- || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
- || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
+			 || ((((x1 = ((usqInt) sx) >> BinaryPoint)) >= sourceWidth)
+			 || (((y1 = ((usqInt) sy) >> BinaryPoint)) >= sourceHeight)))) {
 				sourcePix = 0;
 				goto l2;
 			}

Modified: branches/Cog/unixbuild/mtbld/mvm
===================================================================
--- branches/Cog/unixbuild/mtbld/mvm	2011-08-07 20:36:57 UTC (rev 2485)
+++ branches/Cog/unixbuild/mtbld/mvm	2011-08-08 19:01:31 UTC (rev 2486)
@@ -1,5 +1,5 @@
 #!/bin/sh
-test -f config.h ||  ../../platforms/unix/config/configure INTERP=cointerpmt --without-vm-display-fbdev --without-npsqueak CFLAGS="-g -O2 -msse2 -DNDEBUG -DCOGMTVM=1 -DDEBUGVM=0 -D_GNU_SOURCE -DITIMER_HEARTBEAT=1 -DNO_VM_PROFILE=1" LIBS=-lpthread
+test -f config.h || ../../platforms/unix/config/configure INTERP=cointerpmt --without-vm-display-fbdev --without-npsqueak CFLAGS="-g -O2 -msse2 -DNDEBUG -DCOGMTVM=1 -DDEBUGVM=0 -D_GNU_SOURCE -DITIMER_HEARTBEAT=1 -DNO_VM_PROFILE=1" LIBS=-lpthread
 ../../scripts/nukeversion
 rm -rf ../../cogmtlinux
 make install prefix=`readlink -f \`pwd\`/../../cogmtlinux`



More information about the Vm-dev mailing list