void BlendScanline(MemBitmap dstBmp, byte[] expandGreyBuffer, PixelFarm.Drawing.Color color, int x, int y, int width) { byte[] rgb = new byte[3] { color.R, color.G, color.B }; //------------------------- //destination CpuBlit.TempMemPtr memPtr = MemBitmap.GetBufferPtr(dstBmp); //start pixel int destImgIndex = (x * 4) + (dstBmp.Stride * y); //start img src int srcImgIndex = x + (width * y); int colorIndex = 0; int round = 0; byte color_a = color.A; unsafe { byte *destImgBuffer = (byte *)memPtr.Ptr; while (width > 3) { int a0 = expandGreyBuffer[srcImgIndex] * color_a; int a1 = expandGreyBuffer[srcImgIndex + 1] * color_a; int a2 = expandGreyBuffer[srcImgIndex + 2] * color_a; byte ec0 = destImgBuffer[destImgIndex]; //existing color byte ec1 = destImgBuffer[destImgIndex + 1]; //existing color byte ec2 = destImgBuffer[destImgIndex + 2]; //existing color //------------------------------------------------------ //please note that we swap a2 and a0 on the fly**** //------------------------------------------------------ byte n0 = (byte)((((rgb[colorIndex] - ec0) * a2) + (ec0 << 16)) >> 16); byte n1 = (byte)((((rgb[colorIndex + 1] - ec1) * a1) + (ec1 << 16)) >> 16); byte n2 = (byte)((((rgb[colorIndex + 2] - ec2) * a0) + (ec2 << 16)) >> 16); destImgBuffer[destImgIndex] = n0; destImgBuffer[destImgIndex + 1] = n1; destImgBuffer[destImgIndex + 2] = n2; destImgIndex += 4; round = 0; colorIndex = 0; srcImgIndex += 3; width -= 3; } memPtr.Dispose(); } }
static byte[] CreateGreyScaleBuffer(MemBitmap bmp) { //assume img is 32 rgba img int imgW = bmp.Width; int height = bmp.Height; //56 level grey scale buffer CpuBlit.TempMemPtr srcMemPtr = MemBitmap.GetBufferPtr(bmp); int greyScaleBufferLen = imgW * height; byte[] greyScaleBuffer = new byte[greyScaleBufferLen]; int destIndex = 0; int srcImgIndex = 0; int srcImgStride = bmp.Stride; unsafe { byte *srcImgBuffer = (byte *)srcMemPtr.Ptr; for (int y = 0; y < height; ++y) { srcImgIndex = srcImgStride * y; destIndex = imgW * y; for (int x = 0; x < imgW; ++x) { byte r = srcImgBuffer[srcImgIndex]; byte g = srcImgBuffer[srcImgIndex + 1]; byte b = srcImgBuffer[srcImgIndex + 2]; byte a = srcImgBuffer[srcImgIndex + 3]; if (r != 0 || g != 0 || b != 0) { } if (a != 255) { } //skip alpha //byte greyScaleValue = // (byte)((0.333f * (float)r) + (0.5f * (float)g) + (0.1666f * (float)b)); greyScaleBuffer[destIndex] = (byte)(((a + 1) / 256f) * 64f); destIndex++; srcImgIndex += 4; } } } srcMemPtr.Dispose(); return(greyScaleBuffer); }
internal unsafe static void NN_StepXBy1(IBitmapSrc bmpsrc, int srcIndex, Drawing.Color[] outputColors, int dstIndex, int len) { using (CpuBlit.TempMemPtr srcBufferPtr = bmpsrc.GetBufferPtr()) { int *pSource = (int *)srcBufferPtr.Ptr + srcIndex; do { int srcColor = *pSource; //separate each component //TODO: review here, color from source buffer //should be in 'pre-multiplied' format. //so it should be converted to 'straight' color by call something like ..'FromPreMult()' outputColors[dstIndex++] = Drawing.Color.FromArgb( (srcColor >> CO.A_SHIFT) & 0xff, //a (srcColor >> CO.R_SHIFT) & 0xff, //r (srcColor >> CO.G_SHIFT) & 0xff, //g (srcColor >> CO.B_SHIFT) & 0xff); //b pSource++; //move next } while (--len != 0); } }
public override void GenerateColors(Color[] outputColors, int startIndex, int x, int y, int len) { ISpanInterpolator spanInterpolator = this.Interpolator; int acc_r, acc_g, acc_b, acc_a; int diameter = _lut.Diameter; int start = _lut.Start; int[] weight_array = _lut.WeightArray; int x_count; int weight_y; unsafe { using (CpuBlit.TempMemPtr srcBufferPtr = _bmpSrc.GetBufferPtr()) { int *srcBuffer = (int *)srcBufferPtr.Ptr; spanInterpolator.Begin(x + base.dx, y + base.dy, len); do { spanInterpolator.GetCoord(out x, out y); x -= base.dxInt; y -= base.dyInt; int x_hr = x; int y_hr = y; int x_lr = x_hr >> subpix_const.SHIFT; int y_lr = y_hr >> subpix_const.SHIFT; //accumualted color components acc_r = acc_g = acc_b = acc_a = filter_const.SCALE / 2; int x_fract = x_hr & subpix_const.MASK; int y_count = diameter; y_hr = subpix_const.MASK - (y_hr & subpix_const.MASK); int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr); int tmp_Y = y_lr; for (; ;) { x_count = diameter; weight_y = weight_array[y_hr]; x_hr = subpix_const.MASK - x_fract; //------------------- for (; ;) { int weight = (weight_y * weight_array[x_hr] + filter_const.SCALE / 2) >> filter_const.SHIFT; int srcColor = srcBuffer[bufferIndex]; acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b if (--x_count == 0) { break; //for } x_hr += subpix_const.SCALE; bufferIndex++; } //------------------- if (--y_count == 0) { break; } y_hr += subpix_const.SCALE; tmp_Y++; //move down to next row-> and find start bufferIndex bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, tmp_Y); } acc_r >>= filter_const.SHIFT; acc_g >>= filter_const.SHIFT; acc_b >>= filter_const.SHIFT; acc_a >>= filter_const.SHIFT; unchecked { if ((uint)acc_r > BASE_MASK) { if (acc_r < 0) { acc_r = 0; } if (acc_r > BASE_MASK) { acc_r = BASE_MASK; } } if ((uint)acc_g > BASE_MASK) { if (acc_g < 0) { acc_g = 0; } if (acc_g > BASE_MASK) { acc_g = BASE_MASK; } } if ((uint)acc_b > BASE_MASK) { if (acc_b < 0) { acc_b = 0; } if (acc_b > BASE_MASK) { acc_b = BASE_MASK; } } if ((uint)acc_a > BASE_MASK) { if (acc_a < 0) { acc_a = 0; } if (acc_a > BASE_MASK) { acc_a = BASE_MASK; } } } outputColors[startIndex] = PixelFarm.Drawing.Color.FromArgb( (byte)acc_a, //a (byte)acc_r, (byte)acc_g, (byte)acc_b); startIndex++; spanInterpolator.Next(); } while (--len != 0); } } }
public sealed override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len) { #if DEBUG int tmp_len = len; #endif unsafe { //TODO: review here if (_noTransformation) { using (CpuBlit.TempMemPtr.FromBmp(_bmpSrc, out int *srcBuffer)) { int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x, y); do { //TODO: review here, match component? //ORDER IS IMPORTANT! //TODO : use CO (color order instead) int srcColor = srcBuffer[bufferIndex++]; outputColors[startIndex] = Drawing.Color.FromArgb( (srcColor >> CO.A_SHIFT) & 0xff, //a (srcColor >> CO.R_SHIFT) & 0xff, //r (srcColor >> CO.G_SHIFT) & 0xff, //g (srcColor >> CO.B_SHIFT) & 0xff); //b ++startIndex; } while (--len != 0); } } else { //Bilinear interpolation, without lookup table ISpanInterpolator spanInterpolator = base.Interpolator; using (CpuBlit.TempMemPtr srcBufferPtr = _bmpSrc.GetBufferPtr()) { int *srcBuffer = (int *)srcBufferPtr.Ptr; spanInterpolator.Begin(x + base.dx, y + base.dy, len); //accumulated color component int acc_r, acc_g, acc_b, acc_a; Color bgColor = this.BackgroundColor; int back_r = bgColor.R; int back_g = bgColor.G; int back_b = bgColor.B; int back_a = bgColor.A; int maxx = _bmpSrc.Width - 1; int maxy = _bmpSrc.Height - 1; int srcColor = 0; do { int x_hr; int y_hr; spanInterpolator.GetCoord(out x_hr, out y_hr); x_hr -= base.dxInt; y_hr -= base.dyInt; int x_lr = x_hr >> subpix_const.SHIFT; int y_lr = y_hr >> subpix_const.SHIFT; int weight; if (x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr); //accumulated color components acc_r = acc_g = acc_b = acc_a = subpix_const.SCALE * subpix_const.SCALE / 2; x_hr &= subpix_const.MASK; y_hr &= subpix_const.MASK; weight = (subpix_const.SCALE - x_hr) * (subpix_const.SCALE - y_hr); if (weight > BASE_MASK) { srcColor = srcBuffer[bufferIndex]; acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } weight = (x_hr * (subpix_const.SCALE - y_hr)); if (weight > BASE_MASK) { bufferIndex++; srcColor = srcBuffer[bufferIndex]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } weight = ((subpix_const.SCALE - x_hr) * y_hr); if (weight > BASE_MASK) { ++y_lr; // bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr); srcColor = srcBuffer[bufferIndex]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } weight = (x_hr * y_hr); if (weight > BASE_MASK) { bufferIndex++; srcColor = srcBuffer[bufferIndex]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } acc_r >>= subpix_const.SHIFT * 2; acc_g >>= subpix_const.SHIFT * 2; acc_b >>= subpix_const.SHIFT * 2; acc_a >>= subpix_const.SHIFT * 2; } else { if (x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { acc_r = back_r; acc_g = back_g; acc_b = back_b; acc_a = back_a; } else { acc_r = acc_g = acc_b = acc_a = subpix_const.SCALE * subpix_const.SCALE / 2; x_hr &= subpix_const.MASK; y_hr &= subpix_const.MASK; weight = (subpix_const.SCALE - x_hr) * (subpix_const.SCALE - y_hr); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { srcColor = srcBuffer[_bmpSrc.GetBufferOffsetXY32(x_lr, y_lr)]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } else { acc_r += back_r * weight; acc_g += back_g * weight; acc_b += back_b * weight; acc_a += back_a * weight; } } x_lr++; weight = x_hr * (subpix_const.SCALE - y_hr); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { srcColor = srcBuffer[_bmpSrc.GetBufferOffsetXY32(x_lr, y_lr)]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } else { acc_r += back_r * weight; acc_g += back_g * weight; acc_b += back_b * weight; acc_a += back_a * weight; } } x_lr--; y_lr++; weight = (subpix_const.SCALE - x_hr) * y_hr; if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { srcColor = srcBuffer[_bmpSrc.GetBufferOffsetXY32(x_lr, y_lr)]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } else { acc_r += back_r * weight; acc_g += back_g * weight; acc_b += back_b * weight; acc_a += back_a * weight; } } x_lr++; weight = (x_hr * y_hr); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { srcColor = srcBuffer[_bmpSrc.GetBufferOffsetXY32(x_lr, y_lr)]; // acc_a += weight * ((srcColor >> CO.A_SHIFT) & 0xff); //a acc_r += weight * ((srcColor >> CO.R_SHIFT) & 0xff); //r acc_g += weight * ((srcColor >> CO.G_SHIFT) & 0xff); //g acc_b += weight * ((srcColor >> CO.B_SHIFT) & 0xff); //b } else { acc_r += back_r * weight; acc_g += back_g * weight; acc_b += back_b * weight; acc_a += back_a * weight; } } acc_r >>= subpix_const.SHIFT * 2; acc_g >>= subpix_const.SHIFT * 2; acc_b >>= subpix_const.SHIFT * 2; acc_a >>= subpix_const.SHIFT * 2; } } #if DEBUG if (startIndex >= outputColors.Length) { } #endif outputColors[startIndex] = PixelFarm.Drawing.Color.FromArgb( (byte)acc_a, (byte)acc_r, (byte)acc_g, (byte)acc_b ); ++startIndex; spanInterpolator.Next(); } while (--len != 0); } //using } //else } //unsafe }