//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #include "core/bitRender.h" U32 openTable[32] = { 0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFC,0xFFFFFFF8, 0xFFFFFFF0,0xFFFFFFE0,0xFFFFFFC0,0xFFFFFF80, 0xFFFFFF00,0xFFFFFE00,0xFFFFFC00,0xFFFFF800, 0xFFFFF000,0xFFFFE000,0xFFFFC000,0xFFFF8000, 0xFFFF0000,0xFFFE0000,0xFFFC0000,0xFFF80000, 0xFFF00000,0xFFE00000,0xFFC00000,0xFF800000, 0xFF000000,0xFE000000,0xFC000000,0xF8000000, 0xF0000000,0xE0000000,0xC0000000,0x80000000 }; U32 closeTable[32] = { 0x00000001,0x00000003,0x00000007,0x0000000F, 0x0000001F,0x0000003F,0x0000007F,0x000000FF, 0x000001FF,0x000003FF,0x000007FF,0x00000FFF, 0x00001FFF,0x00003FFF,0x00007FFF,0x0000FFFF, 0x0001FFFF,0x0003FFFF,0x0007FFFF,0x000FFFFF, 0x001FFFFF,0x003FFFFF,0x007FFFFF,0x00FFFFFF, 0x01FFFFFF,0x03FFFFFF,0x07FFFFFF,0x0FFFFFFF, 0x1FFFFFFF,0x3FFFFFFF,0x7FFFFFFF,0xFFFFFFFF }; struct DrawStruct { S16 start; S16 num; }; void BitRender::render_strips(const U8 * draw, S32 numDraw, S32 szDraw, const U16 * indices, const Point2I * points, S32 dim, U32 * bits) { const U8 * drawEnd = draw + numDraw*szDraw; // loop through strips... for (; drawstart; const U16 * iend = icurrent + drawStruct->num; const Point2I * vv0 = points + *(icurrent++); const Point2I * vv1; const Point2I * vv2 = points + *(icurrent++); const Point2I **nextPt = &vv1; while (icurrentx>=0 && v0->xy>=0 && v0->yx>=0 && v1->xy>=0 && v1->yx>=0 && v2->xy>=0 && v2->yx-v1->x)*(v2->y-v1->y) > (v0->y-v1->y)*(v2->x-v1->x)) continue; // rotate so that v0 holds topmost y coord // Note: The particular inequalities used ( <=, <, then <=) are important. // They guarantee that if there are two verts on the top row, that // they will be vert v0 and v1 (also could be three). if (v1->y <= v2->y) { if (v1->y < v0->y) { const Point2I * tmp = v0; v0 = v1; v1 = v2; v2 = tmp; } } else { if (v2->y <= v0->y) { const Point2I * tmp = v0; v0 = v2; v2 = v1; v1 = tmp; } } // all the control variables we have to set up... S32 leftDeltaY, xLeftInc, xLeftErrInc, xLeftDir, xLeft, xLeftErr = 0; S32 rightDeltaY, xRightInc, xRightErrInc, xRightDir, xRight, xRightErr = 0; S32 * changeThisDelta; S32 * changeThisInc; S32 * changeThisErrInc; S32 * changeThisDir; S32 toThisDelta; S32 toThisInc; S32 toThisErrInc; S32 toThisDir; S32 ySwitch; S32 yBottom; // check for special case where top row holds two verts if (v0->y==v1->y) { leftDeltaY = v2->y-v0->y; rightDeltaY = v2->y-v1->y; ySwitch = v2->y; yBottom = v2->y; if (v1->y==v2->y) { // special-special case where top row holds all three verts xLeft = getMin(getMin(v0->x,v1->x),v2->x); xRight = getMax(getMax(v0->x,v1->x),v2->x); xLeftInc = xRightInc = 0; xLeftErrInc = xRightErrInc = 0; xLeftDir = xRightDir = 1; } else { // standard-special case...v2 on different row from v0 and v1 xLeft = v0->x; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; xRight = v1->x; xRightInc = (v2->x-v1->x) / rightDeltaY; xRightErrInc = (v2->x-v1->x) - rightDeltaY*xRightInc; xRightDir = v2->x-v1->x > 0 ? 1 : -1; } // set these variables to avoid a crash... changeThisDelta = &toThisDelta; changeThisInc = &toThisInc; changeThisErrInc = &toThisErrInc; changeThisDir = &toThisDir; } else { leftDeltaY = v2->y-v0->y; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; rightDeltaY = v1->y-v0->y; xRightInc = (v1->x-v0->x) / rightDeltaY; xRightErrInc = (v1->x-v0->x) - rightDeltaY*xRightInc; xRightDir = v1->x-v0->x > 0 ? 1 : -1; xLeft = xRight = v0->x; if (v1->yy) { // right edge bends changeThisDelta = &rightDeltaY; changeThisInc = &xRightInc; changeThisErrInc = &xRightErrInc; changeThisDir = &xRightDir; toThisDelta = v2->y-v1->y; toThisInc = (v2->x-v1->x) / toThisDelta; toThisErrInc = (v2->x-v1->x) - toThisDelta * toThisInc; toThisDir = v2->x-v1->x > 0 ? 1 : -1; ySwitch = v1->y-1; yBottom = v2->y; } else { // left edge bends changeThisDelta = &leftDeltaY; changeThisInc = &xLeftInc; changeThisErrInc = &xLeftErrInc; changeThisDir = &xLeftDir; toThisDelta = v1->y-v2->y; toThisInc = toThisDelta ? (v1->x-v2->x) / toThisDelta : 0; toThisErrInc = toThisDelta ? (v1->x-v2->x) - toThisDelta * toThisInc : 0; toThisDir = v1->x-v2->x > 0 ? 1 : -1; ySwitch = v2->y-1; yBottom = v1->y; } } xLeftErrInc *= xLeftDir; xRightErrInc *= xRightDir; toThisErrInc *= toThisDir; U32 * rowStart = bits + v0->y * (dim>>5); for (S32 y=v0->y; y<=yBottom;) { do { AssertFatal(xLeft<=xRight,"BitRender::render"); U32 open = openTable[xLeft&31]; U32 close = closeTable[xRight&31]; if ( (xLeft^xRight) & ~31) { U32 * x = rowStart+(xLeft>>5); *x |= open; U32 * xEnd = rowStart+(xRight>>5); while (++x>5] |= open & close; xLeft += xLeftInc; xLeftErr += xLeftErrInc; if (xLeftErr >= leftDeltaY) { xLeft += xLeftDir; xLeftErr -= leftDeltaY; } xRight += xRightInc; xRightErr += xRightErrInc; if (xRightErr >= rightDeltaY) { xRight += xRightDir; xRightErr -= rightDeltaY; } rowStart += dim>>5; } while (y++start; const U16 * iend = icurrent + drawStruct->num; while (icurrentx>=0 && v0->xy>=0 && v0->yx>=0 && v1->xy>=0 && v1->yx>=0 && v2->xy>=0 && v2->yx-v1->x)*(v2->y-v1->y) > (v0->y-v1->y)*(v2->x-v1->x)) continue; // rotate so that v0 holds topmost y coord // Note: The particular inequalities used ( <=, <, then <=) are important. // They guarantee that if there are two verts on the top row, that // they will be vert v0 and v1 (also could be three). if (v1->y <= v2->y) { if (v1->y < v0->y) { const Point2I * tmp = v0; v0 = v1; v1 = v2; v2 = tmp; } } else { if (v2->y <= v0->y) { const Point2I * tmp = v0; v0 = v2; v2 = v1; v1 = tmp; } } // all the control variables we have to set up... S32 leftDeltaY, xLeftInc, xLeftErrInc, xLeftDir, xLeft, xLeftErr = 0; S32 rightDeltaY, xRightInc, xRightErrInc, xRightDir, xRight, xRightErr = 0; S32 * changeThisDelta; S32 * changeThisInc; S32 * changeThisErrInc; S32 * changeThisDir; S32 toThisDelta; S32 toThisInc; S32 toThisErrInc; S32 toThisDir; S32 ySwitch; S32 yBottom; // check for special case where top row holds two verts if (v0->y==v1->y) { leftDeltaY = v2->y-v0->y; rightDeltaY = v2->y-v1->y; ySwitch = v2->y; yBottom = v2->y; if (v1->y==v2->y) { // special-special case where top row holds all three verts xLeft = getMin(getMin(v0->x,v1->x),v2->x); xRight = getMax(getMax(v0->x,v1->x),v2->x); xLeftInc = xRightInc = 0; xLeftErrInc = xRightErrInc = 0; xLeftDir = xRightDir = 1; } else { // standard-special case...v2 on different row from v0 and v1 xLeft = v0->x; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; xRight = v1->x; xRightInc = (v2->x-v1->x) / rightDeltaY; xRightErrInc = (v2->x-v1->x) - rightDeltaY*xRightInc; xRightDir = v2->x-v1->x > 0 ? 1 : -1; } // set these variables to avoid a crash... changeThisDelta = &toThisDelta; changeThisInc = &toThisInc; changeThisErrInc = &toThisErrInc; changeThisDir = &toThisDir; } else { leftDeltaY = v2->y-v0->y; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; rightDeltaY = v1->y-v0->y; xRightInc = (v1->x-v0->x) / rightDeltaY; xRightErrInc = (v1->x-v0->x) - rightDeltaY*xRightInc; xRightDir = v1->x-v0->x > 0 ? 1 : -1; xLeft = xRight = v0->x; if (v1->yy) { // right edge bends changeThisDelta = &rightDeltaY; changeThisInc = &xRightInc; changeThisErrInc = &xRightErrInc; changeThisDir = &xRightDir; toThisDelta = v2->y-v1->y; toThisInc = (v2->x-v1->x) / toThisDelta; toThisErrInc = (v2->x-v1->x) - toThisDelta * toThisInc; toThisDir = v2->x-v1->x > 0 ? 1 : -1; ySwitch = v1->y-1; yBottom = v2->y; } else { // left edge bends changeThisDelta = &leftDeltaY; changeThisInc = &xLeftInc; changeThisErrInc = &xLeftErrInc; changeThisDir = &xLeftDir; toThisDelta = v1->y-v2->y; toThisInc = toThisDelta ? (v1->x-v2->x) / toThisDelta : 0; toThisErrInc = toThisDelta ? (v1->x-v2->x) - toThisDelta * toThisInc : 0; toThisDir = v1->x-v2->x > 0 ? 1 : -1; ySwitch = v2->y-1; yBottom = v1->y; } } xLeftErrInc *= xLeftDir; xRightErrInc *= xRightDir; toThisErrInc *= toThisDir; U32 * rowStart = bits + v0->y * (dim>>5); for (S32 y=v0->y; y<=yBottom;) { do { AssertFatal(xLeft<=xRight,"BitRender::render"); U32 open = openTable[xLeft&31]; U32 close = closeTable[xRight&31]; if ( (xLeft^xRight) & ~31) { U32 * x = rowStart+(xLeft>>5); *x |= open; U32 * xEnd = rowStart+(xRight>>5); while (++x>5] |= open & close; xLeft += xLeftInc; xLeftErr += xLeftErrInc; if (xLeftErr >= leftDeltaY) { xLeft += xLeftDir; xLeftErr -= leftDeltaY; } xRight += xRightInc; xRightErr += xRightErrInc; if (xRightErr >= rightDeltaY) { xRight += xRightDir; xRightErr -= rightDeltaY; } rowStart += dim>>5; } while (y++x>=0 && v0->xy>=0 && v0->yx>=0 && v1->xy>=0 && v1->yx>=0 && v2->xy>=0 && v2->yx-v1->x)*(v2->y-v1->y) > (v0->y-v1->y)*(v2->x-v1->x)) return; // rotate so that v0 holds topmost y coord // Note: The particular inequalities used ( <=, <, then <=) are important. // They guarantee that if there are two verts on the top row, that // they will be vert v0 and v1 (also could be three). if (v1->y <= v2->y) { if (v1->y < v0->y) { const Point2I * tmp = v0; v0 = v1; v1 = v2; v2 = tmp; } } else { if (v2->y <= v0->y) { const Point2I * tmp = v0; v0 = v2; v2 = v1; v1 = tmp; } } // all the control variables we have to set up... S32 leftDeltaY, xLeftInc, xLeftErrInc, xLeftDir, xLeft, xLeftErr = 0; S32 rightDeltaY, xRightInc, xRightErrInc, xRightDir, xRight, xRightErr = 0; S32 * changeThisDelta; S32 * changeThisInc; S32 * changeThisErrInc; S32 * changeThisDir; S32 toThisDelta; S32 toThisInc; S32 toThisErrInc; S32 toThisDir; S32 ySwitch; S32 yBottom; // check for special case where top row holds two verts if (v0->y==v1->y) { leftDeltaY = v2->y-v0->y; rightDeltaY = v2->y-v1->y; ySwitch = v2->y; yBottom = v2->y; if (v1->y==v2->y) { // special-special case where top row holds all three verts xLeft = getMin(getMin(v0->x,v1->x),v2->x); xRight = getMax(getMax(v0->x,v1->x),v2->x); xLeftErrInc = xRightErrInc = 0; } else { // standard-special case...v2 on different row from v0 and v1 xLeft = v0->x; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; xRight = v1->x; xRightInc = (v2->x-v1->x) / rightDeltaY; xRightErrInc = (v2->x-v1->x) - rightDeltaY*xRightInc; xRightDir = v2->x-v1->x > 0 ? 1 : -1; } // set these variables to avoid a crash... changeThisDelta = &toThisDelta; changeThisInc = &toThisInc; changeThisErrInc = &toThisErrInc; changeThisDir = &toThisDir; } else { leftDeltaY = v2->y-v0->y; xLeftInc = (v2->x-v0->x) / leftDeltaY; xLeftErrInc = (v2->x-v0->x) - leftDeltaY*xLeftInc; xLeftDir = v2->x-v0->x > 0 ? 1 : -1; rightDeltaY = v1->y-v0->y; xRightInc = (v1->x-v0->x) / rightDeltaY; xRightErrInc = (v1->x-v0->x) - rightDeltaY*xRightInc; xRightDir = v1->x-v0->x > 0 ? 1 : -1; xLeft = xRight = v0->x; if (v1->yy) { // right edge bends changeThisDelta = &rightDeltaY; changeThisInc = &xRightInc; changeThisErrInc = &xRightErrInc; changeThisDir = &xRightDir; toThisDelta = v2->y-v1->y; toThisInc = (v2->x-v1->x) / toThisDelta; toThisErrInc = (v2->x-v1->x) - toThisDelta * toThisInc; toThisDir = v2->x-v1->x > 0 ? 1 : -1; ySwitch = v1->y-1; yBottom = v2->y; } else { // left edge bends changeThisDelta = &leftDeltaY; changeThisInc = &xLeftInc; changeThisErrInc = &xLeftErrInc; changeThisDir = &xLeftDir; toThisDelta = v1->y-v2->y; toThisInc = toThisDelta ? (v1->x-v2->x) / toThisDelta : 0; toThisErrInc = toThisDelta ? (v1->x-v2->x) - toThisDelta * toThisInc : 0; toThisDir = v1->x-v2->x > 0 ? 1 : -1; ySwitch = v2->y-1; yBottom = v1->y; } } xLeftErrInc *= xLeftDir; xRightErrInc *= xRightDir; toThisErrInc *= toThisDir; U32 * rowStart = bits + v0->y * (dim>>5); for (S32 y=v0->y; y<=yBottom;) { do { AssertFatal(xLeft<=xRight,"BitRender::render"); U32 open = openTable[xLeft&31]; U32 close = closeTable[xRight&31]; if ( (xLeft^xRight) & ~31) { U32 * x = rowStart+(xLeft>>5); *x |= open; U32 * xEnd = rowStart+(xRight>>5); while (++x>5] |= open & close; xLeft += xLeftInc; xLeftErr += xLeftErrInc; if (xLeftErr >= leftDeltaY) { xLeft += xLeftDir; xLeftErr -= leftDeltaY; } xRight += xRightInc; xRightErr += xRightErrInc; if (xRightErr >= rightDeltaY) { xRight += xRightDir; xRightErr -= rightDeltaY; } rowStart += dim>>5; } while (y++>5; for (S32 i=0; i>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; *eightBits++ = *(U32*)&bitTable[val&0xF]; val >>= 4; } } U8 bitTableA[16][4] = { SF32( 0, 0, 0, 0), // 0 SF32( 0, 0, 0, 0), // 1 SF32( 0, 0, 0, 0), // 2 SF32( 0, 0, 0, 0), // 3 SF32( 0, 0, 0, 0), // 4 SF32( 0, 0, 0, 0), // 5 SF32( 0, 0, 0, 0), // 6 SF32( 0, 0, 0, 0), // 7 SF32( 17, 0, 0, 0), // 8 SF32( 17, 0, 0, 0), // 9 SF32( 17, 0, 0, 0), // 10 SF32( 17, 0, 0, 0), // 11 SF32( 17, 0, 0, 0), // 12 SF32( 17, 0, 0, 0), // 13 SF32( 17, 0, 0, 0), // 14 SF32( 17, 0, 0, 0), // 15 }; U8 bitTableB[16][4] = { SF32( 0, 0, 0, 0), // 0 SF32( 34, 17, 0, 0), // 1 SF32( 17, 34, 17, 0), // 2 SF32( 51, 51, 17, 0), // 3 SF32( 0, 17, 34, 17), // 4 SF32( 34, 34, 34, 17), // 5 SF32( 17, 51, 51, 17), // 6 SF32( 51, 68, 51, 17), // 7 SF32( 0, 0, 17, 34), // 8 SF32( 34, 17, 17, 34), // 9 SF32( 17, 34, 34, 34), // 10 SF32( 51, 51, 34, 34), // 11 SF32( 0, 17, 51, 51), // 12 SF32( 34, 34, 51, 51), // 13 SF32( 17, 51, 68, 51), // 14 SF32( 51, 68, 68, 51), // 15 }; U8 bitTableC[16][4] = { SF32( 0, 0, 0, 0), // 0 SF32( 0, 0, 0, 17), // 1 SF32( 0, 0, 0, 0), // 2 SF32( 0, 0, 0, 17), // 3 SF32( 0, 0, 0, 0), // 4 SF32( 0, 0, 0, 17), // 5 SF32( 0, 0, 0, 0), // 6 SF32( 0, 0, 0, 17), // 7 SF32( 0, 0, 0, 0), // 8 SF32( 0, 0, 0, 17), // 9 SF32( 0, 0, 0, 0), // 10 SF32( 0, 0, 0, 17), // 11 SF32( 0, 0, 0, 0), // 12 SF32( 0, 0, 0, 17), // 13 SF32( 0, 0, 0, 0), // 14 SF32( 0, 0, 0, 17), // 15 }; U8 bitTableE[16][4] = { SF32( 0, 0, 0, 0), // 0 SF32( 51, 34, 0, 0), // 1 SF32( 34, 51, 34, 0), // 2 SF32( 85, 85, 34, 0), // 3 SF32( 0, 34, 51, 34), // 4 SF32( 51, 68, 51, 34), // 5 SF32( 34, 85, 85, 34), // 6 SF32( 85,119, 85, 34), // 7 SF32( 0, 0, 34, 51), // 8 SF32( 51, 34, 34, 51), // 9 SF32( 34, 51, 68, 51), // 10 SF32( 85, 85, 68, 51), // 11 SF32( 0, 34, 85, 85), // 12 SF32( 51, 68, 85, 85), // 13 SF32( 34, 85,119, 85), // 14 SF32( 85,119,119, 85), // 15 }; void BitRender::bitTo8Bit_3(U32 * bits, U32 * eightBits, S32 dim) { #if defined(TORQUE_BIG_ENDIAN) #define MAX_SHADOW_TEXELS (256 + 4) //256 seems big enough, +4 so we can run off end of buffer. // slow fake gaussian int i, j, c; U8 tmpLine[3][MAX_SHADOW_TEXELS]; U8 *src0, *src1, *src2, *srcTmp; U8 *s0, *s1, *s2; U32 dimS2 = dim>>2; U32 *src32; U32 *currLine = bits; U32 currVal; U32 sampleVal; U8 c00, c01, c02, c10, c11, c12, c20, c21, c22; int openBuf; src0 = tmpLine[0]; src1 = tmpLine[1]; src2 = tmpLine[2]; openBuf = 2; // the one src2 is using right now. // pre-process two rows into our tmp buffers. src32 = (U32*)(src0); for(i=0; i<(dimS2>>3); i++) // walk 4 bytes at a time, 4 bits at a time. { currVal = *currLine++; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[currVal]; } src32 = (U32*)(src1); for(i=0; i<(dimS2>>3); i++) { currVal = *currLine++; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[currVal]; } // pre-clear first row of depth buffer. for (i=0; i0) { j--; // process new line (currLine) into new tmp buffer (src2) src32 = (U32*)(src2); for(i=0; i<(dimS2>>3); i++) // 8 at a time. { currVal = *currLine++; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[0x0F & currVal]; currVal >>= 4; *src32++ = *(U32*)&bitTable[currVal]; } // blur & copy current src1 to current dest #if NO_BLUR // test for basic functionality. srcTmp = src1; src32 = (U32*)srcTmp; for (i=0; i>= 5; // div by 32 subsamples } // mix into val store to hold. currVal |= sampleVal << (8*(3-c)); c00 = c01; c01 = c02; c10 = c11; c11 = c12; c20 = c21; c21 = c22; //c#2 defd next time round } // put samples into dest buffer. *eightBits++ = currVal; } #endif // flip around ptrs for next row processing. openBuf++; if (openBuf>2) openBuf = 0; src0 = src1; src1 = src2; src2 = tmpLine[openBuf]; } // clear last dest buffer row for (i=0; i>2); do { *eightBits++=0; } while (eightBits>2)*(dim-1); U8 * p0 = (U8*)bits; U8 bitLo10 = 0x0F & *p0; U8 bitHi10 = (*p0) >> 4; p0++; U8 * p1 = (U8*)bits + (dim>>3); U8 bitLo11 = 0x0F & *p1; U8 bitHi11 = (*p1) >> 4; p1++; U8 * p2 = (U8*)bits + (dim>>2); U8 bitLo12 = 0x0F & *p2; U8 bitHi12 = (*p2) >> 4; p2++; U8 bitLo20, bitHi20; U8 bitLo21, bitHi21; U8 bitLo22, bitHi22; U8 bitHi00 = 0; U8 bitHi01 = 0; U8 bitHi02 = 0; // go thru penultimate row (but stop before last entry in that row) U8 * end = (U8*)bits + dim*(dim>>3) - 1; do { bitLo20 = 0x0F & *p0; bitHi20 = (*p0) >> 4; bitLo21 = 0x0F & *p1; bitHi21 = (*p1) >> 4; bitLo22 = 0x0F & *p2; bitHi22 = (*p2) >> 4; *eightBits++ = *(U32*)&bitTableA[bitHi00] + *(U32*)&bitTableB[bitLo10] + *(U32*)&bitTableC[bitHi10] + *(U32*)&bitTableA[bitHi01]*2 + *(U32*)&bitTableE[bitLo11] + *(U32*)&bitTableC[bitHi11]*2 + *(U32*)&bitTableA[bitHi02] + *(U32*)&bitTableB[bitLo12] + *(U32*)&bitTableC[bitHi12]; *eightBits++ = *(U32*)&bitTableA[bitLo10] + *(U32*)&bitTableB[bitHi10] + *(U32*)&bitTableC[bitLo20] + *(U32*)&bitTableA[bitLo11]*2 + *(U32*)&bitTableE[bitHi11] + *(U32*)&bitTableC[bitLo21]*2 + *(U32*)&bitTableA[bitLo12] + *(U32*)&bitTableB[bitHi12] + *(U32*)&bitTableC[bitLo22]; bitHi00 = bitHi10; bitLo10 = bitLo20; bitHi10 = bitHi20; bitHi01 = bitHi11; bitLo11 = bitLo21; bitHi11 = bitHi21; bitHi02 = bitHi12; bitLo12 = bitLo22; bitHi12 = bitHi22; p0++; p1++; p2++; } while (p2