protected override unsafe void Diffuse( int rError, int gError, int bError, byte* ptr )
{
int edR; // error diffusion
int edG; // error diffusion
int edB; // error diffusion
// do error diffusion to right-standing neighbors
int[] coefficientsRow = coefficients[0];
for ( int jI = 1, jP = pixelSize, jC = 0, k = coefficientsRow.Length; jC < k; jI++, jC++, jP += pixelSize )
{
if ( x + jI >= width )
break;
edR = ptr[jP + RGB.R] + ( rError * coefficientsRow[jC] ) / coefficientsSum;
edR = ( edR < 0 ) ? 0 : ( ( edR > 255 ) ? 255 : edR );
ptr[jP + RGB.R] = (byte) edR;
edG = ptr[jP + RGB.G] + ( gError * coefficientsRow[jC] ) / coefficientsSum;
edG = ( edG < 0 ) ? 0 : ( ( edG > 255 ) ? 255 : edG );
ptr[jP + RGB.G] = (byte) edG;
edB = ptr[jP + RGB.B] + ( bError * coefficientsRow[jC] ) / coefficientsSum;
edB = ( edB < 0 ) ? 0 : ( ( edB > 255 ) ? 255 : edB );
ptr[jP + RGB.B] = (byte) edB;
}
// do error diffusion to bottom neigbors
for ( int i = 1, n = coefficients.Length; i < n; i++ )
{
if ( y + i >= height )
break;
// move pointer to next image line
ptr += stride;
// get coefficients of the row
coefficientsRow = coefficients[i];
// process the row
for ( int jC = 0, k = coefficientsRow.Length, jI = -( k >> 1 ), jP = -( k >> 1 ) * pixelSize; jC < k; jI++, jC++, jP += pixelSize )
{
if ( x + jI >= width )
break;
if ( x + jI < 0 )
continue;
edR = ptr[jP + RGB.R] + ( rError * coefficientsRow[jC] ) / coefficientsSum;
edR = ( edR < 0 ) ? 0 : ( ( edR > 255 ) ? 255 : edR );
ptr[jP + RGB.R] = (byte) edR;
edG = ptr[jP + RGB.G] + ( gError * coefficientsRow[jC] ) / coefficientsSum;
edG = ( edG < 0 ) ? 0 : ( ( edG > 255 ) ? 255 : edG );
ptr[jP + RGB.G] = (byte) edG;
edB = ptr[jP + RGB.B] + ( bError * coefficientsRow[jC] ) / coefficientsSum;
edB = ( edB < 0 ) ? 0 : ( ( edB > 255 ) ? 255 : edB );
ptr[jP + RGB.B] = (byte) edB;
}
}
}