public static MemBitmap CopyImgBuffer(this MemBitmap src, int srcX, int srcY, int srcW, int srcH) { //simple copy Rectangle orgSourceRect = new Rectangle(0, 0, src.Width, src.Height); Rectangle requestRect = new Rectangle(srcX, srcY, srcW, srcH); Rectangle toCopyRect = Rectangle.Intersect(new Rectangle(0, 0, src.Width, src.Height), new Rectangle(srcX, srcY, srcW, srcH)); if (toCopyRect.Width == 0 || toCopyRect.Height == 0) { return(null); } //----- MemBitmap copyBmp = new MemBitmap(toCopyRect.Width, toCopyRect.Height); unsafe { using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(src)) using (CpuBlit.Imaging.TempMemPtr dstBufferPtr = MemBitmap.GetBufferPtr(copyBmp)) { int *srcPtr = (int *)srcBufferPtr.Ptr; int *dstPtr = (int *)dstBufferPtr.Ptr; int lineEnd = srcY + srcH; int orgSrcW = src.Width; for (int line = toCopyRect.Top; line < toCopyRect.Bottom; ++line) { NativeMemMx.memcpy((byte *)dstPtr, (byte *)(srcPtr + ((line * orgSrcW) + toCopyRect.Left)), toCopyRect.Width * 4); dstPtr += toCopyRect.Width; } } } return(copyBmp); }
/// <summary> /// attach image buffer and its information to the reader /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="bitsPerPixel"></param> /// <param name="imgbuffer"></param> /// <param name="outputPxBlender"></param> protected void Attach(int width, int height, int bitsPerPixel, CpuBlit.Imaging.TempMemPtr imgbuffer, PixelBlender32 outputPxBlender) { if (width <= 0 || height <= 0) { throw new ArgumentOutOfRangeException("You must have a width and height > than 0."); } if (bitsPerPixel != 32 && bitsPerPixel != 24 && bitsPerPixel != 8) { throw new Exception("Unsupported bits per pixel."); } // // int bytesPerPixel = (bitsPerPixel + 7) / 8; int stride = 4 * ((width * bytesPerPixel + 3) / 4); #if DEBUG if (bytesPerPixel == 0) { } #endif // SetDimmensionAndFormat(width, height, stride, bitsPerPixel, bitsPerPixel / 8); SetUpLookupTables(); // this.OutputPixelBlender = outputPxBlender; // _raw_buffer32 = imgbuffer.Ptr; _rawBufferLenInBytes = imgbuffer.LengthInBytes; }
public static int[] CopyImgBuffer(ActualBitmap img, int width) { //calculate stride for the width int destStride = ActualBitmap.CalculateStride(width, CpuBlit.Imaging.PixelFormat.ARGB32); int h = img.Height; int newBmpW = destStride / 4; int[] buff2 = new int[newBmpW * img.Height]; unsafe { CpuBlit.Imaging.TempMemPtr srcBufferPtr = ActualBitmap.GetBufferPtr(img); byte *srcBuffer = (byte *)srcBufferPtr.Ptr; int srcIndex = 0; int srcStride = img.Stride; fixed(int *destHead = &buff2[0]) { byte *destHead2 = (byte *)destHead; for (int line = 0; line < h; ++line) { //System.Runtime.InteropServices.Marshal.Copy(srcBuffer, srcIndex, (IntPtr)destHead2, destStride); NativeMemMx.memcpy((byte *)destHead2, srcBuffer + srcIndex, destStride); srcIndex += srcStride; destHead2 += destStride; } } srcBufferPtr.Release(); } return(buff2); }
public static int[] CopyImgBuffer(MemBitmap memBmp, int width, int height) { //calculate stride for the width int destStride = MemBitmap.CalculateStride(width, CpuBlit.Imaging.PixelFormat.ARGB32); int newBmpW = destStride / 4; int[] buff2 = new int[newBmpW * height]; unsafe { using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(memBmp)) { byte* srcBuffer = (byte*)srcBufferPtr.Ptr; int srcIndex = 0; int srcStride = memBmp.Stride; fixed (int* destHead = &buff2[0]) { byte* destHead2 = (byte*)destHead; for (int line = 0; line < height; ++line) { //System.Runtime.InteropServices.Marshal.Copy(srcBuffer, srcIndex, (IntPtr)destHead2, destStride); NativeMemMx.memcpy((byte*)destHead2, srcBuffer + srcIndex, destStride); srcIndex += srcStride; destHead2 += destStride; } } } } return buff2; }
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.Imaging.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); }
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.Imaging.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.alpha; 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(); } }
/// <summary> /// copy from actual image direct to hBmpScan0 /// </summary> /// <param name="memBmp"></param> /// <param name="hBmpScan0"></param> public static void CopyToWindowsBitmapSameSize( MemBitmap memBmp, IntPtr hBmpScan0) { //1st, fast CpuBlit.Imaging.TempMemPtr tmp = MemBitmap.GetBufferPtr(memBmp); //System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // hBmpScan0, rawBuffer.Length); unsafe { NativeMemMx.memcpy((byte *)hBmpScan0, (byte *)tmp.Ptr, tmp.LengthInBytes); } }
public override void RenderTo(Image destImg, int srcX, int srcYy, int srcW, int srcH) { //render back buffer to target image unsafe { CpuBlit.MemBitmap memBmp = destImg as CpuBlit.MemBitmap; if (memBmp != null) { CpuBlit.Imaging.TempMemPtr tmpPtr = CpuBlit.MemBitmap.GetBufferPtr(memBmp); byte *head = (byte *)tmpPtr.Ptr; _gdigsx.RenderTo(head); tmpPtr.Dispose(); } } }
public static int[] CopyImgBuffer(ActualBitmap img) { int[] buff2 = new int[img.Width * img.Height]; unsafe { //byte[] pixelBuffer = ActualImage.GetBuffer(img); CpuBlit.Imaging.TempMemPtr pixBuffer = ActualBitmap.GetBufferPtr(img); //fixed (byte* header = &pixelBuffer[0]) byte *header = (byte *)pixBuffer.Ptr; { System.Runtime.InteropServices.Marshal.Copy((IntPtr)header, buff2, 0, buff2.Length);//length in bytes } pixBuffer.Release(); } return(buff2); }
public static int[] CopyImgBuffer(MemBitmap memBmp) { int[] buff2 = new int[memBmp.Width * memBmp.Height]; unsafe { using (CpuBlit.Imaging.TempMemPtr pixBuffer = MemBitmap.GetBufferPtr(memBmp)) { //fixed (byte* header = &pixelBuffer[0]) byte *header = (byte *)pixBuffer.Ptr; { System.Runtime.InteropServices.Marshal.Copy((IntPtr)header, buff2, 0, buff2.Length);//length in bytes } } } return(buff2); }
internal unsafe static void NN_StepXBy1(IBitmapSrc bmpsrc, int srcIndex, Drawing.Color[] outputColors, int dstIndex, int len) { using (CpuBlit.Imaging.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 static int[] CopyImgBuffer(MemBitmap src, int srcX, int srcY, int srcW, int srcH) { //calculate stride for the width int destStride = MemBitmap.CalculateStride(srcW, CpuBlit.Imaging.PixelFormat.ARGB32); int newBmpW = destStride / 4; int[] buff2 = new int[newBmpW * srcH]; unsafe { using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(src)) { byte* srcBuffer = (byte*)srcBufferPtr.Ptr; int srcIndex = 0; int srcStride = src.Stride; fixed (int* destHead = &buff2[0]) { byte* destHead2 = (byte*)destHead; //move to specific src line srcIndex += srcStride * srcY; int lineEnd = srcY + srcH; for (int line = srcY; line < lineEnd; ++line) { //System.Runtime.InteropServices.Marshal.Copy(srcBuffer, srcIndex, (IntPtr)destHead2, destStride); NativeMemMx.memcpy((byte*)destHead2, srcBuffer + srcIndex, destStride); srcIndex += srcStride; destHead2 += destStride; } } } } return buff2; }
// Create //-------------------------------------------------------------------- public void Create(IBitmapSrc src) { // we are going to create a dialated image for filtering // we add m_dilation pixels to every side of the image and then copy the image in the x // dirrection into each end so that we can sample into this image to get filtering on x repeating // if the original image look like this // // 123456 // // the new image would look like this // // 0000000000 // 0000000000 // 5612345612 // 0000000000 // 0000000000 m_height = (int)AggMath.uceil(src.Height); m_width = (int)AggMath.uceil(src.Width); m_width_hr = (int)AggMath.uround(src.Width * LineAA.SUBPIXEL_SCALE); m_half_height_hr = (int)AggMath.uround(src.Height * LineAA.SUBPIXEL_SCALE / 2); m_offset_y_hr = m_dilation_hr + m_half_height_hr - LineAA.SUBPIXEL_SCALE / 2; m_half_height_hr += LineAA.SUBPIXEL_SCALE / 2; int bufferWidth = m_width + m_dilation * 2; int bufferHeight = m_height + m_dilation * 2; int bytesPerPixel = src.BitDepth / 8; int newSizeInBytes = bufferWidth * bufferHeight * bytesPerPixel; if (m_DataSizeInBytes < newSizeInBytes) { m_DataSizeInBytes = newSizeInBytes; m_data = new int[m_DataSizeInBytes / 4]; } m_buf = new PixelProcessing.SubBitmapBlender(m_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel); unsafe { CpuBlit.Imaging.TempMemPtr destMemPtr = m_buf.GetBufferPtr(); CpuBlit.Imaging.TempMemPtr srcMemPtr = src.GetBufferPtr(); int *destBuffer = (int *)destMemPtr.Ptr; int *srcBuffer = (int *)srcMemPtr.Ptr; // copy the image into the middle of the dest for (int y = 0; y < m_height; y++) { for (int x = 0; x < m_width; x++) { int sourceOffset = src.GetBufferOffsetXY32(x, y); int destOffset = m_buf.GetBufferOffsetXY32(m_dilation, y + m_dilation); destBuffer[destOffset] = srcBuffer[sourceOffset]; } } // copy the first two pixels form the end into the begining and from the begining into the end for (int y = 0; y < m_height; y++) { int s1Offset = src.GetBufferOffsetXY32(0, y); int d1Offset = m_buf.GetBufferOffsetXY32(m_dilation + m_width, y); int s2Offset = src.GetBufferOffsetXY32(m_width - m_dilation, y); int d2Offset = m_buf.GetBufferOffsetXY32(0, y); for (int x = 0; x < m_dilation; x++) { destBuffer[d1Offset++] = srcBuffer[s1Offset++]; destBuffer[d2Offset++] = srcBuffer[s2Offset++]; } } srcMemPtr.Release(); destMemPtr.Release(); } }
public sealed override void GenerateColors(Drawing.Color[] outputColors, int startIndex, int x, int y, int len) { ISpanInterpolator spanInterpolator = Interpolator; spanInterpolator.Begin(x + dx, y + dy, len); int x_hr; int y_hr; spanInterpolator.GetCoord(out x_hr, out y_hr); int x_lr = x_hr >> img_subpix_const.SHIFT; int y_lr = y_hr >> img_subpix_const.SHIFT; int bufferIndex = _bmpSrc.GetBufferOffsetXY32(x_lr, y_lr); unsafe { using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = _bmpSrc.GetBufferPtr()) { int *pSource = (int *)srcBufferPtr.Ptr + bufferIndex; do { int src_value = *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[startIndex++] = Drawing.Color.FromArgb( (byte)((src_value >> 24) & 0xff), //a (byte)((src_value >> 16) & 0xff), //r (byte)((src_value >> 8) & 0xff), //g (byte)((src_value) & 0xff)); //b pSource++; //move next } while (--len != 0); } } //version 1 , incorrect //ISpanInterpolator spanInterpolator = Interpolator; //spanInterpolator.Begin(x + dx, y + dy, len); //int x_hr; //int y_hr; //spanInterpolator.GetCoord(out x_hr, out y_hr); //int x_lr = x_hr >> img_subpix_const.SHIFT; //int y_lr = y_hr >> img_subpix_const.SHIFT; //int bufferIndex = srcRW.GetBufferOffsetXY(x_lr, y_lr); //byte[] srcBuffer = srcRW.GetBuffer(); //unsafe //{ // fixed (byte* pSource = srcBuffer) // { // do // { // outputColors[startIndex++] = *(Drawing.Color*)&(pSource[bufferIndex]); // bufferIndex += 4; // } 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 (_mode0) { using (CpuBlit.Imaging.TempMemPtr.FromBmp(_imgsrc, out int *srcBuffer)) { int bufferIndex = _imgsrc.GetBufferOffsetXY32(x, y); //unsafe { #if true do { //TODO: review here, match component? //ORDER IS IMPORTANT! //TODO : use CO (color order instead) int color = srcBuffer[bufferIndex++]; //byte b = (byte)srcBuffer[bufferIndex++]; //byte g = (byte)srcBuffer[bufferIndex++]; //byte r = (byte)srcBuffer[bufferIndex++]; //byte a = (byte)srcBuffer[bufferIndex++]; //outputColors[startIndex] = Drawing.Color.FromArgb(a, r, g, b); outputColors[startIndex] = Drawing.Color.FromArgb( (color >> 24) & 0xff, //a (color >> 16) & 0xff, //r (color >> 8) & 0xff, //b (color) & 0xff //b ); ++startIndex; } while (--len != 0); #else fixed(byte *pSource = &fg_ptr[bufferIndex]) { int *pSourceInt = (int *)pSource; fixed(RGBA_Bytes *pDest = &span[spanIndex]) { int *pDestInt = (int *)pDest; do { *pDestInt++ = *pSourceInt++; } while (--len != 0); } } #endif } } } else { ISpanInterpolator spanInterpolator = base.Interpolator; using (CpuBlit.Imaging.TempMemPtr srcBufferPtr = _imgsrc.GetBufferPtr()) { int *srcBuffer = (int *)srcBufferPtr.Ptr; spanInterpolator.Begin(x + base.dx, y + base.dy, len); int accColor0, accColor1, accColor2, accColor3; int back_r = m_bgcolor.red; int back_g = m_bgcolor.green; int back_b = m_bgcolor.blue; int back_a = m_bgcolor.alpha; int maxx = _imgsrc.Width - 1; int maxy = _imgsrc.Height - 1; int color = 0; unchecked { 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 >> img_subpix_const.SHIFT; int y_lr = y_hr >> img_subpix_const.SHIFT; int weight; if (x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { int bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr); accColor0 = accColor1 = accColor2 = accColor3 = (int)img_subpix_const.SCALE * (int)img_subpix_const.SCALE / 2; x_hr &= img_subpix_const.MASK; y_hr &= img_subpix_const.MASK; //bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr); weight = ((img_subpix_const.SCALE - x_hr) * (img_subpix_const.SCALE - y_hr)); if (weight > BASE_MASK) { color = srcBuffer[bufferIndex]; accColor3 += weight * ((color >> 24) & 0xff); //a accColor0 += weight * ((color >> 16) & 0xff); //r accColor1 += weight * ((color >> 8) & 0xff); //g accColor2 += weight * ((color) & 0xff); //b } weight = (x_hr * ((int)img_subpix_const.SCALE - y_hr)); if (weight > BASE_MASK) { bufferIndex++; color = srcBuffer[bufferIndex]; // accColor3 += weight * ((color >> 24) & 0xff); //a accColor0 += weight * ((color >> 16) & 0xff); //r accColor1 += weight * ((color >> 8) & 0xff); //g accColor2 += weight * ((color) & 0xff); //b } weight = (((int)img_subpix_const.SCALE - x_hr) * y_hr); if (weight > BASE_MASK) { ++y_lr; // bufferIndex = _imgsrc.GetBufferOffsetXY32(x_lr, y_lr); color = srcBuffer[bufferIndex]; // accColor3 += weight * ((color >> 24) & 0xff); //a accColor0 += weight * ((color >> 16) & 0xff); //r accColor1 += weight * ((color >> 8) & 0xff); //g accColor2 += weight * ((color) & 0xff); //b } weight = (x_hr * y_hr); if (weight > BASE_MASK) { bufferIndex++; color = srcBuffer[bufferIndex]; // accColor3 += weight * ((color >> 24) & 0xff); //a accColor0 += weight * ((color >> 16) & 0xff); //r accColor1 += weight * ((color >> 8) & 0xff); //g accColor2 += weight * ((color) & 0xff); //b } accColor0 >>= img_subpix_const.SHIFT * 2; accColor1 >>= img_subpix_const.SHIFT * 2; accColor2 >>= img_subpix_const.SHIFT * 2; accColor3 >>= img_subpix_const.SHIFT * 2; } else { if (x_lr < -1 || y_lr < -1 || x_lr > maxx || y_lr > maxy) { accColor0 = back_r; accColor1 = back_g; accColor2 = back_b; accColor3 = back_a; } else { accColor0 = accColor1 = accColor2 = accColor3 = (int)img_subpix_const.SCALE * (int)img_subpix_const.SCALE / 2; x_hr &= (int)img_subpix_const.MASK; y_hr &= (int)img_subpix_const.MASK; weight = (((int)img_subpix_const.SCALE - x_hr) * ((int)img_subpix_const.SCALE - y_hr)); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { BlendInFilterPixel( ref accColor0, ref accColor1, ref accColor2, ref accColor3, srcBuffer, _imgsrc.GetBufferOffsetXY32(x_lr, y_lr), weight); } else { accColor0 += back_r * weight; accColor1 += back_g * weight; accColor2 += back_b * weight; accColor3 += back_a * weight; } } x_lr++; weight = (x_hr * ((int)img_subpix_const.SCALE - y_hr)); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3, srcBuffer, _imgsrc.GetBufferOffsetXY32(x_lr, y_lr), weight); } else { accColor0 += back_r * weight; accColor1 += back_g * weight; accColor2 += back_b * weight; accColor3 += back_a * weight; } } x_lr--; y_lr++; weight = (((int)img_subpix_const.SCALE - x_hr) * y_hr); if (weight > BASE_MASK) { if ((uint)x_lr <= (uint)maxx && (uint)y_lr <= (uint)maxy) { BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3, srcBuffer, _imgsrc.GetBufferOffsetXY32(x_lr, y_lr), weight); } else { accColor0 += back_r * weight; accColor1 += back_g * weight; accColor2 += back_b * weight; accColor3 += 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) { BlendInFilterPixel(ref accColor0, ref accColor1, ref accColor2, ref accColor3, srcBuffer, _imgsrc.GetBufferOffsetXY32(x_lr, y_lr), weight); } else { accColor0 += back_r * weight; accColor1 += back_g * weight; accColor2 += back_b * weight; accColor3 += back_a * weight; } } accColor0 >>= img_subpix_const.SHIFT * 2; accColor1 >>= img_subpix_const.SHIFT * 2; accColor2 >>= img_subpix_const.SHIFT * 2; accColor3 >>= img_subpix_const.SHIFT * 2; } } #if DEBUG if (startIndex >= outputColors.Length) { } #endif outputColors[startIndex] = PixelFarm.Drawing.Color.FromArgb( (byte)accColor3, (byte)accColor0, (byte)accColor1, (byte)accColor2 ); //outputColors[startIndex].red = (byte)accColor0; //outputColors[startIndex].green = (byte)accColor1; //outputColors[startIndex].blue = (byte)accColor2; //outputColors[startIndex].alpha = (byte)accColor3; ++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.Imaging.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.Imaging.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.red; int back_g = bgColor.green; int back_b = bgColor.blue; int back_a = bgColor.alpha; 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 }
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.Imaging.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 static void CopyToGdiPlusBitmapSameSize( MemBitmap memBmp, SkiaSharp.SKBitmap skBmp) { //agg store image buffer head-down //when copy to window bmp we here to flip //style1: copy row by row *** (fastest)*** { //System.GC.Collect(); //System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); //sss.Start(); //for (int i = 0; i < 1000; ++i) //{ int h = skBmp.Height; int w = skBmp.Width; //BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); skBmp.LockPixels(); IntPtr scan0 = skBmp.GetPixels(); int stride = memBmp.Stride; //byte[] srcBuffer = ActualImage.GetBuffer(actualImage); unsafe { CpuBlit.Imaging.TempMemPtr srcBufferPtr = MemBitmap.GetBufferPtr(memBmp); //fixed (byte* bufferH = &srcBuffer[0]) byte *bufferH = (byte *)srcBufferPtr.Ptr; { byte *target = (byte *)scan0; int startRowAt = ((h - 1) * stride); for (int y = h; y > 0; --y) { //byte* src = bufferH + ((y - 1) * stride); //System.Runtime.InteropServices.Marshal.Copy( // srcBuffer,//src // startRowAt, // (IntPtr)target, // stride); PixelFarm.CpuBlit.MemMx.memcpy(target, bufferH + startRowAt, stride); startRowAt -= stride; target += stride; } } srcBufferPtr.Dispose(); } skBmp.UnlockPixels(); //} //sss.Stop(); //long ms = sss.ElapsedMilliseconds; } //----------------------------------- //style2: copy all, then flip again //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // byte[] rawBuffer = ActualImage.GetBuffer(actualImage); // var bmpdata = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), // System.Drawing.Imaging.ImageLockMode.ReadOnly, // bitmap.PixelFormat); // System.Runtime.InteropServices.Marshal.Copy(rawBuffer, 0, // bmpdata.Scan0, rawBuffer.Length); // bitmap.UnlockBits(bmpdata); // bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} //----------------------------------- //----------------------------------- //style3: copy row by row + //{ // System.GC.Collect(); // System.Diagnostics.Stopwatch sss = new System.Diagnostics.Stopwatch(); // sss.Start(); // for (int i = 0; i < 1000; ++i) // { // int h = bitmap.Height; // int w = bitmap.Width; // BitmapData bitmapData1 = bitmap.LockBits( // new Rectangle(0, 0, // w, // h), // System.Drawing.Imaging.ImageLockMode.ReadWrite, // bitmap.PixelFormat); // IntPtr scan0 = bitmapData1.Scan0; // int stride = bitmapData1.Stride; // byte[] buffer = ActualImage.GetBuffer(actualImage); // unsafe // { // fixed (byte* bufferH = &buffer[0]) // { // byte* target = (byte*)scan0; // for (int y = h; y > 0; --y) // { // byte* src = bufferH + ((y - 1) * stride); // for (int n = stride - 1; n >= 0; --n) // { // *target = *src; // target++; // src++; // } // } // } // } // bitmap.UnlockBits(bitmapData1); // } // sss.Stop(); // long ms = sss.ElapsedMilliseconds; //} }
void CopyFromNoClipping(IBitmapSrc sourceImage, RectInt clippedSourceImageRect, int destXOffset, int destYOffset) { if (BytesBetweenPixelsInclusive != BitDepth / 8 || sourceImage.BytesBetweenPixelsInclusive != sourceImage.BitDepth / 8) { throw new Exception("WIP we only support packed pixel formats at this time."); } if (BitDepth == sourceImage.BitDepth) { int lengthInBytes = clippedSourceImageRect.Width * BytesBetweenPixelsInclusive; int sourceOffset = sourceImage.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom); unsafe { using (CpuBlit.Imaging.TempMemPtr memPtr = sourceImage.GetBufferPtr()) using (CpuBlit.Imaging.TempMemPtr destPtr = this.GetBufferPtr()) { byte *sourceBuffer = (byte *)memPtr.Ptr; byte *destBuffer = (byte *)destPtr.Ptr; int destOffset = GetBufferOffsetXY32(clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + destYOffset); for (int i = 0; i < clippedSourceImageRect.Height; i++) { MemMx.memmove(destBuffer, destOffset * 4, sourceBuffer, sourceOffset, lengthInBytes); sourceOffset += sourceImage.Stride; destOffset += Stride; } } } } else { bool haveConversion = true; switch (sourceImage.BitDepth) { case 24: switch (BitDepth) { case 32: { //TODO: review here, this may not correct int numPixelsToCopy = clippedSourceImageRect.Width; for (int i = clippedSourceImageRect.Bottom; i < clippedSourceImageRect.Top; i++) { int sourceOffset = sourceImage.GetBufferOffsetXY32(clippedSourceImageRect.Left, clippedSourceImageRect.Bottom + i); //byte[] sourceBuffer = sourceImage.GetBuffer(); //byte[] destBuffer = GetBuffer(); using (CpuBlit.Imaging.TempMemPtr srcMemPtr = sourceImage.GetBufferPtr()) using (CpuBlit.Imaging.TempMemPtr destBufferPtr = this.GetBufferPtr()) { int destOffset = GetBufferOffsetXY32( clippedSourceImageRect.Left + destXOffset, clippedSourceImageRect.Bottom + i + destYOffset); unsafe { int *destBuffer = (int *)destBufferPtr.Ptr; int *sourceBuffer = (int *)srcMemPtr.Ptr; for (int x = 0; x < numPixelsToCopy; x++) { int color = sourceBuffer[sourceOffset++]; destBuffer[destOffset++] = (255 << 24) | //a (color & 0xff0000) | //b (color & 0x00ff00) | //g (color & 0xff); //destBuffer[destOffset++] = sourceBuffer[sourceOffset++]; //destBuffer[destOffset++] = sourceBuffer[sourceOffset++]; //destBuffer[destOffset++] = 255; } } } } } break; default: haveConversion = false; break; } break; default: haveConversion = false; break; } if (!haveConversion) { throw new NotImplementedException("You need to write the " + sourceImage.BitDepth.ToString() + " to " + BitDepth.ToString() + " conversion"); } } }
// Create //-------------------------------------------------------------------- public void Create(IBitmapSrc src) { // we are going to create a dialated image for filtering // we add m_dilation pixels to every side of the image and then copy the image in the x // dirrection into each end so that we can sample into this image to get filtering on x repeating // if the original image look like this // // 123456 // // the new image would look like this // // 0000000000 // 0000000000 // 5612345612 // 0000000000 // 0000000000 _height = (int)AggMath.uceil(src.Height); _width = (int)AggMath.uceil(src.Width); _width_hr = (int)AggMath.uround(src.Width * LineAA.SUBPIXEL_SCALE); _half_height_hr = (int)AggMath.uround(src.Height * LineAA.SUBPIXEL_SCALE / 2); _offset_y_hr = _dilation_hr + _half_height_hr - LineAA.SUBPIXEL_SCALE / 2; _half_height_hr += LineAA.SUBPIXEL_SCALE / 2; int bufferWidth = _width + _dilation * 2; int bufferHeight = _height + _dilation * 2; int bytesPerPixel = src.BitDepth / 8; int newSizeInBytes = bufferWidth * bufferHeight * bytesPerPixel; if (_DataSizeInBytes < newSizeInBytes) { _DataSizeInBytes = newSizeInBytes; _data.Dispose(); IntPtr nativeBuff = System.Runtime.InteropServices.Marshal.AllocHGlobal(_DataSizeInBytes); _data = new Imaging.TempMemPtr(nativeBuff, _DataSizeInBytes); } _buf = new PixelProcessing.SubBitmapBlender(_data, 0, bufferWidth, bufferHeight, bufferWidth * bytesPerPixel, src.BitDepth, bytesPerPixel); unsafe { using (CpuBlit.Imaging.TempMemPtr destMemPtr = _buf.GetBufferPtr()) using (CpuBlit.Imaging.TempMemPtr srcMemPtr = src.GetBufferPtr()) { int* destBuffer = (int*)destMemPtr.Ptr; int* srcBuffer = (int*)srcMemPtr.Ptr; // copy the image into the middle of the dest for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { int sourceOffset = src.GetBufferOffsetXY32(x, y); int destOffset = _buf.GetBufferOffsetXY32(_dilation, y + _dilation); destBuffer[destOffset] = srcBuffer[sourceOffset]; } } // copy the first two pixels form the end into the begining and from the begining into the end for (int y = 0; y < _height; y++) { int s1Offset = src.GetBufferOffsetXY32(0, y); int d1Offset = _buf.GetBufferOffsetXY32(_dilation + _width, y); int s2Offset = src.GetBufferOffsetXY32(_width - _dilation, y); int d2Offset = _buf.GetBufferOffsetXY32(0, y); for (int x = 0; x < _dilation; x++) { destBuffer[d1Offset++] = srcBuffer[s1Offset++]; destBuffer[d2Offset++] = srcBuffer[s2Offset++]; } } } } }