unsafe Form1.frame transcode(Bitmap b, Form1.frame oldframe) { Form1.frame f = new Form1.frame(); f.OldVersion = oldframe; f.W = (ushort)b.Width; f.H = (ushort)b.Height; f.X = oldframe.X; f.Y = oldframe.Y; f.Raw = new byte[f.W * f.H]; var d = b.LockBits(new Rectangle(0, 0, f.W, f.H), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); try { for (int y = 0; y < d.Height; y++) { int *ptr = (int *)(d.Scan0 + d.Stride * y); for (int x = 0; x < d.Width; x++) { int pixel = *ptr++; if (colorToIndex.TryGetValue(pixel, out byte idx)) { f.Raw[x + f.W * y] = idx; } else { if (MessageBox.Show(string.Format("Unknown color {0:X8} at ({1},{2})", pixel, x, y), "Unknown color", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { return(null); } } } } } finally { b.UnlockBits(d); } return(f); }
unsafe void rerender(bool noReset = false) { if (!noReset) { spriteSavedLabel.Hide(); replacementFrame = null; pictureBox2.Image = null; button3.Enabled = false; } int rx = comboBox1.SelectedIndex + 2; int index = (int)numericUpDown1.Value; if (index >= Form1.allRX[rx].Length || Form1.allRX[rx][index] == null) { pictureBox1.Image = null; button1.Enabled = false; button2.Enabled = false; } else { button1.Enabled = true; button2.Enabled = true; pictureBox1.Image = null; var d = buffer.LockBits(new Rectangle(0, 0, 400, 400), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); for (int i = 0; i < d.Height; i++) { int *ptr = (int *)(d.Scan0 + i * d.Stride); for (int j = 0; j < d.Width; j++) { *ptr++ = 0; } } Form1.drawSprite(d, rx, (short)index, 0, 0); buffer.UnlockBits(d); pictureBox1.Image = buffer; } }
void saveIndexedPNG(Stream fs, Form1.frame sprite) { MemoryStream ms = new MemoryStream(); BinaryWriter w = new BinaryWriter(ms); w.Write(0x474E5089); w.Write(0x0A1A0A0D); // IHDR w.Write(toBE(13)); long pos = ms.Position; w.Write(0x52444849); w.Write(toBE(sprite.W)); w.Write(toBE(sprite.H)); w.Write((byte)8); w.Write((byte)3); w.Write((byte)0); w.Write((byte)0); w.Write((byte)0); w.Write(toBE(CRC(ms, pos, ms.Position))); // PLTE w.Write(toBE(3 * 256)); pos = ms.Position; w.Write(0x45544C50); w.Write((byte)0xff); w.Write((byte)0); w.Write((byte)0xff); for (int i = 1; i < pal.Length; i++) { w.Write((byte)(pal[i] >> 16)); w.Write((byte)(pal[i] >> 8)); w.Write((byte)(pal[i])); } w.Write(toBE(CRC(ms, pos, ms.Position))); // tRNS w.Write(toBE(1)); pos = ms.Position; w.Write(0x534E5274); w.Write((byte)0); w.Write(toBE(CRC(ms, pos, ms.Position))); MemoryStream pixeldata = new MemoryStream(); for (int y = 0; y < sprite.H; y++) { pixeldata.WriteByte(0); pixeldata.Write(sprite.Raw, y * sprite.W, sprite.W); } pixeldata.Position = 0; MemoryStream compressedPixels = new MemoryStream(); compressedPixels.WriteByte(0x78); compressedPixels.WriteByte(0x5E); var c = new System.IO.Compression.DeflateStream(compressedPixels, System.IO.Compression.CompressionMode.Compress, true); pixeldata.CopyTo(c); c.Close(); compressedPixels.Position = 0; // IDAT w.Write(toBE((int)compressedPixels.Length)); pos = ms.Position; w.Write(0x54414449); compressedPixels.CopyTo(ms); w.Write(toBE(CRC(ms, pos, ms.Position))); // IEND w.Write(0); w.Write(0x444E4549); w.Write(0x826042AE); ms.Position = 0; ms.CopyTo(fs); fs.Close(); }