public static unsafe byte[] FromBitmap(Bitmap Picture, ImageFormat Format, bool ExactSize = false) { if (ExactSize && ((Picture.Width % 8) != 0 || (Picture.Height % 8) != 0)) { return(null); } int physicalwidth = Picture.Width; int physicalheight = Picture.Height; int ConvWidth = Picture.Width; int ConvHeight = Picture.Height; if (!ExactSize) { ConvWidth = 1 << (int)Math.Ceiling(Math.Log(Picture.Width, 2)); ConvHeight = 1 << (int)Math.Ceiling(Math.Log(Picture.Height, 2)); } BitmapData d = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); uint * res = (uint *)d.Scan0; byte[] result = new byte[ConvWidth * ConvHeight * GetBpp(Format) / 8]; int offs = 0; switch (Format) { case ImageFormat.RGB8: for (int y = 0; y < ConvHeight; y += 8) { for (int x = 0; x < ConvWidth; x += 8) { for (int i = 0; i < 64; i++) { int x2 = i % 8; if (x + x2 >= physicalwidth) { continue; } int y2 = i / 8; if (y + y2 >= physicalheight) { continue; } int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4); Color c = Color.FromArgb((int)res[(y + y2) * d.Stride / 4 + x + x2]); result[offs + pos * 3 + 0] = c.B; result[offs + pos * 3 + 1] = c.G; result[offs + pos * 3 + 2] = c.R; } offs += 64 * 3; } } break; case ImageFormat.RGB565: for (int y = 0; y < ConvHeight; y += 8) { for (int x = 0; x < ConvWidth; x += 8) { for (int i = 0; i < 64; i++) { int x2 = i % 8; if (x + x2 >= physicalwidth) { continue; } int y2 = i / 8; if (y + y2 >= physicalheight) { continue; } int pos = TileOrder[x2 % 4 + y2 % 4 * 4] + 16 * (x2 / 4) + 32 * (y2 / 4); IOUtil.WriteU16LE(result, offs + pos * 2, GFXUtil.ArgbToRGB565(res[(y + y2) * d.Stride / 4 + x + x2])); } offs += 64 * 2; } } break; case ImageFormat.ETC1: case ImageFormat.ETC1A4: for (int y = 0; y < ConvHeight; y += 8) { for (int x = 0; x < ConvWidth; x += 8) { for (int i = 0; i < 8; i += 4) { for (int j = 0; j < 8; j += 4) { if (Format == ImageFormat.ETC1A4) { ulong alpha = 0; int iiii = 0; for (int xx = 0; xx < 4; xx++) { for (int yy = 0; yy < 4; yy++) { uint color = res[((y + i + yy) * (d.Stride / 4)) + x + j + xx]; uint a = color >> 24; a >>= 4; alpha |= (ulong)a << (iiii * 4); iiii++; } } IOUtil.WriteU64LE(result, offs, alpha); offs += 8; } Color[] pixels = new Color[4 * 4]; for (int yy = 0; yy < 4; yy++) { for (int xx = 0; xx < 4; xx++) { pixels[yy * 4 + xx] = Color.FromArgb((int)res[((y + i + yy) * (d.Stride / 4)) + x + j + xx]); } } IOUtil.WriteU64LE(result, offs, ETC1.GenETC1(pixels)); offs += 8; } } } } break; default: throw new NotImplementedException("This format is not implemented yet."); } return(result); }