public LRLE(Bitmap image) { magic = 0x454C524C; version = 0x32303056; int imageWidth = image.Width; int imageHeight = image.Height; width = (ushort)imageWidth; height = (ushort)imageHeight; List <Command>[] commandLists = new List <Command> [9]; EncodingState currentState = EncodingState.StartNew; uint runLength = 0; List <byte[]> colorArray = new List <byte[]>(); byte[] lastPixel = new byte[4]; ColorTable colors = new ColorTable(); List <byte[]> runColors = new List <byte[]>(); for (int m = 0; m < 9; m++) { byte[] mipPixels = GetMipBytes(image); commandLists[m] = new List <Command>(); Array.Copy(mipPixels, 0, lastPixel, 0, 4); currentState = EncodingState.StartNew; int x = 0, y = 0; int w1 = image.Width * 4; for (int i = 0; i < mipPixels.Length; i += 64) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 16; k += 4) { byte[] tmp = new byte[4]; Array.Copy(mipPixels, (y * w1) + x + k, tmp, 0, 4); switch (currentState) { case EncodingState.StartNew: currentState = EncodingState.Unknown; runLength = 1; colorArray = new List <byte[]>(); colorArray.Add(tmp); break; case EncodingState.Unknown: if (tmp.SequenceEqual(lastPixel)) { currentState = EncodingState.RepeatRun; } else { currentState = EncodingState.ColorRun; } colorArray.Add(tmp); Array.Copy(tmp, 0, lastPixel, 0, 4); runLength++; break; case EncodingState.ColorRun: if (!tmp.SequenceEqual(lastPixel)) { runLength++; } else { colorArray.RemoveAt(colorArray.Count - 1); runLength--; commandLists[m].Add(new Command(currentState, runLength, colorArray)); foreach (var item in colorArray) { colors.AddColor(item); } runLength = 2; colorArray = new List <byte[]>(); currentState = EncodingState.RepeatRun; } Array.Copy(tmp, 0, lastPixel, 0, 4); colorArray.Add(tmp); break; case EncodingState.RepeatRun: if (tmp.SequenceEqual(lastPixel)) { runLength++; Array.Copy(tmp, 0, lastPixel, 0, 4); } else { commandLists[m].Add(new Command(currentState, runLength, colorArray)); foreach (var item in colorArray) { runColors.Add(item); } Array.Copy(tmp, 0, lastPixel, 0, 4); runLength = 1; colorArray = new List <byte[]>(); colorArray.Add(tmp); currentState = EncodingState.Unknown; } break; default: break; } } y++; } x += 16; if (x >= w1) { x = 0; } else { y -= 4; } } commandLists[m].Add(new Command(currentState, runLength, colorArray)); foreach (var item in colorArray) { colors.AddColor(item); } mipPixels = null; imageWidth /= 2; imageHeight /= 2; if (m < 1) { Bitmap mip = new Bitmap(imageWidth, imageHeight); using (Graphics g = Graphics.FromImage(mip)) { g.SmoothingMode = SmoothingMode.Default; g.InterpolationMode = InterpolationMode.High; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.CompositingQuality = CompositingQuality.HighQuality; g.DrawImage(image, new Rectangle(0, 0, imageWidth, imageHeight)); } image = mip; } else if (m < 3) { image = new Bitmap(image, imageWidth, imageHeight); } else { Bitmap mip = new Bitmap(imageWidth, imageHeight); using (Graphics g = Graphics.FromImage(mip)) { g.SmoothingMode = SmoothingMode.Default; g.InterpolationMode = InterpolationMode.NearestNeighbor; g.PixelOffsetMode = PixelOffsetMode.HighSpeed; g.CompositingQuality = CompositingQuality.HighSpeed; g.DrawImage(image, new Rectangle(0, 0, imageWidth, imageHeight)); } image = mip; } } colors.SortColors(); foreach (var item in runColors) { if (!colors.HasColor(item)) { colors.AddColor(item); } } List <byte[]> tmpPixels = new List <byte[]>(); foreach (var item in colors.colors.OrderBy(x => x.Value.Index).Where(x => x.Value.Index < 0x10000).Select(x => x.Key)) { tmpPixels.Add(item.color); } pixelArray = tmpPixels.ToArray(); mips = new byte[9][]; for (int i = 0; i < 9; i++) { List <byte> tmpCommands = new List <byte>(); foreach (var item in commandLists[i]) { tmpCommands.AddRange(item.ToOps(colors).ToArray()); } mips[i] = tmpCommands.ToArray(); } }