private unsafe void SquishSurfaceTo24Bpp(Surface surface) { byte *dst = (byte *)surface.GetRowAddress(0); int byteWidth = surface.Width * 3; int stride24bpp = ((byteWidth + 3) / 4) * 4; // round up to multiple of 4 int delta = stride24bpp - byteWidth; for (int y = 0; y < surface.Height; ++y) { ColorBgra *src = surface.GetRowAddress(y); ColorBgra *srcEnd = src + surface.Width; while (src < srcEnd) { dst[0] = src->B; dst[1] = src->G; dst[2] = src->R; ++src; dst += 3; } dst += delta; } return; }
public void Clear(bool newValue) { unsafe { uint val = newValue ? 0xffffffff : 0; for (int y = 0; y < Height; ++y) { ColorBgra *row = surface.GetRowAddress(y); int w = (this.Width + 31) / 32; while (w > 0) { row->Bgra = val; ++row; --w; } } } }
private unsafe void Analyze(Surface scratchSurface, out bool allOpaque, out bool all0or255Alpha, out int uniqueColorCount) { allOpaque = true; all0or255Alpha = true; Set <ColorBgra> uniqueColors = new Set <ColorBgra>(); for (int y = 0; y < scratchSurface.Height; ++y) { ColorBgra *srcPtr = scratchSurface.GetRowAddress(y); ColorBgra *endPtr = srcPtr + scratchSurface.Width; while (srcPtr < endPtr) { ColorBgra p = *srcPtr; if (p.A != 255) { allOpaque = false; } if (p.A > 0 && p.A < 255) { all0or255Alpha = false; } if (p.A == 255 && !uniqueColors.Contains(p) && uniqueColors.Count < 300) { uniqueColors.Add(*srcPtr); } ++srcPtr; } } uniqueColorCount = uniqueColors.Count; }
public unsafe override void Render(Surface dst, System.Drawing.Point offset) { if (OwnerList.ScaleFactor < new ScaleFactor(2, 1)) { return; } int[] d2SLookupX = OwnerList.Dst2SrcLookupX; int[] d2SLookupY = OwnerList.Dst2SrcLookupY; int[] s2DLookupX = OwnerList.Src2DstLookupX; int[] s2DLookupY = OwnerList.Src2DstLookupY; ColorBgra[] blackAndWhite = new ColorBgra[2] { ColorBgra.White, ColorBgra.Black }; // draw horizontal lines int sTop = d2SLookupY[offset.Y]; int sBottom = d2SLookupY[offset.Y + dst.Height]; for (int srcY = sTop; srcY <= sBottom; ++srcY) { int dstY = s2DLookupY[srcY]; int dstRow = dstY - offset.Y; if (dst.IsRowVisible(dstRow)) { ColorBgra *dstRowPtr = dst.GetRowAddress(dstRow); ColorBgra *dstRowEndPtr = dstRowPtr + dst.Width; dstRowPtr += offset.X & 1; while (dstRowPtr < dstRowEndPtr) { *dstRowPtr = ColorBgra.Black; dstRowPtr += 2; } } } // draw vertical lines int sLeft = d2SLookupX[offset.X]; int sRight = d2SLookupX[offset.X + dst.Width]; for (int srcX = sLeft; srcX <= sRight; ++srcX) { int dstX = s2DLookupX[srcX]; int dstCol = dstX - offset.X; if (dst.IsColumnVisible(dstX - offset.X)) { byte *dstColPtr = (byte *)dst.GetPointAddress(dstCol, 0); byte *dstColEndPtr = dstColPtr + dst.Stride * dst.Height; dstColPtr += (offset.Y & 1) * dst.Stride; while (dstColPtr < dstColEndPtr) { *((ColorBgra *)dstColPtr) = ColorBgra.Black; dstColPtr += 2 * dst.Stride; } } } }
/// <summary> /// Creates a new Surface and copies the pixels from a Bitmap to it. /// </summary> /// <param name="bitmap">The Bitmap to duplicate.</param> /// <returns>A new Surface that is the same size as the given Bitmap and that has the same pixel values.</returns> public static Surface CopyFromBitmap(Bitmap bitmap) { Surface surface = new Surface(bitmap.Width, bitmap.Height); BitmapData bd = bitmap.LockBits(surface.Bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); unsafe { for (int y = 0; y < bd.Height; ++y) { Memory.Copy((void *)surface.GetRowAddress(y), (byte *)bd.Scan0.ToPointer() + (y * bd.Stride), (ulong)bd.Width * ColorBgra.SizeOf); } } bitmap.UnlockBits(bd); return surface; }