private void button3_Click(object sender, EventArgs e) { if (selectedImage == null || selectedImage.replacementLen <= 0) { return; } DialogResult res = saveFileDialog3.ShowDialog(); if (res != DialogResult.OK) { return; } Bitmap bm = new Bitmap(selectedImage.width, selectedImage.height); CBitReader cr = new CBitReader(selectedImage.replacement); switch (selectedImage.flags & 0xFF) { case 2: CR6Ti.DecodeOpaque1(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; case 3: CR6Ti.DecodeTransparent(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; } bm.Save(saveFileDialog3.FileName); bm.Dispose(); }
private void button1_Click(object sender, EventArgs e) { if (selectedImage == null) { return; } DialogResult res = openFileDialog3.ShowDialog(); if (res == DialogResult.OK) { Bitmap bitmap = new Bitmap(selectedImage.width, selectedImage.height); statusLabel.Text = "Resizing image and creating bitmap ..."; using (Graphics g = Graphics.FromImage((Image)bitmap)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(Image.FromFile(openFileDialog3.FileName), 0, 0, selectedImage.width, selectedImage.height); } MemoryStream stream = new MemoryStream(); CBitWriter bw = new CBitWriter(); switch (selectedImage.flags & 0xFF) { case 2: if ((selectedImage.depth & 0x4) != 0) { statusLabel.Text = "Encoding opaque image (might take a while) ..."; CR6Ti.WriteOpaque1(bitmap, bw, selectedImage.width, selectedImage.height); } else { throw new NotSupportedException("Writing Opaque2 images is not supported"); } break; case 3: statusLabel.Text = "Encoding transparent image (might take a while) ..."; CR6Ti.WriteTransparent(bitmap, bw, selectedImage.width, selectedImage.height); break; default: throw new NotSupportedException("Unknown image type"); } statusLabel.Text = "Saving in byte format ..."; bw.CopyToStream(stream); stream.Flush(); selectedImage.replacement = stream.ToArray(); selectedImage.replacementLen = (UInt32)stream.Length; checkBoxReplaced.Checked = true; button2.Enabled = true; stream.Dispose(); stream.Close(); bitmap.Dispose(); if ((selectedImage.flags & 0xFF) == 2 || (selectedImage.flags & 0xFF) == 3) { Bitmap bm = new Bitmap(selectedImage.width, selectedImage.height); CBitReader cr = new CBitReader(selectedImage.replacement); switch (selectedImage.flags & 0xFF) { case 2: CR6Ti.DecodeOpaque1(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; case 3: CR6Ti.DecodeTransparent(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; } pictureBox2.Image = bm; } else { if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); } pictureBox2.Image = null; } statusLabel.Text = "Ready"; } }
static public void DecodeTransparent(CBitReader s, Bitmap image, int width, int height, int depth) { int[] pr = new int[width]; int[] pg = new int[width]; int[] pb = new int[width]; int[] pa = new int[width]; for (int y = 0; y < height; y++) { int r = 0; int g = 0; int b = 0; int a = 0; int dg = 0; int ta = 0; bool f = true; int samea = 0; int samef = 0; for (int x = 0; x < width;) { if (--samea < 0) { ta += s.ReadSigned(); if (ta == 0) { int n = (int)s.ReadUnsigned(); for (int i = 0; i < n + 1; i++) { pr[x] = 0; pg[x] = 0; pb[x] = 0; pa[x] = 0; image.SetPixel(x++, y, Color.FromArgb(0, 0, 0, 0)); } continue; } if (ta == 32) { samea = (int)s.ReadUnsigned(); } a = ta * 8; if (a >= 256) { a = 255; } } if (--samef < 0) { f = f ? false : true; samef = (int)s.ReadUnsigned(); dg = 0; } if (f) { if (samea < samef) { pr[x] = r; pg[x] = g; pb[x] = b; pa[x] = a; image.SetPixel(x++, y, Color.FromArgb(a, b, g, r)); } else { if (samef > 0) { samea -= samef; } for (int i = 0; i < samef + 1; i++) { pr[x] = r; pg[x] = g; pb[x] = b; pa[x] = a; image.SetPixel(x++, y, Color.FromArgb(a, b, g, r)); } samef = 0; } } else { if (s.ReadBit() == 1) { r = pr[x]; g = pg[x]; b = pb[x]; pa[x] = a; image.SetPixel(x++, y, Color.FromArgb(a, b, g, r)); dg = 0; } else { int tg = g + dg * 2; if (tg < 0) { tg = 0; } if (tg > 255) { tg = 255; } tg -= g; if (tg < -128) { tg += 256; } if (tg > 127) { tg -= 256; } dg = tg / 2 + s.ReadSigned(); if (dg < -128) { dg = -128; } if (dg > 127) { dg = 127; } r += dg * 2; g += dg * 2; b += dg * 2; r += s.ReadSigned() * 2; b += s.ReadSigned() * 2; if (r > 255) { r = 255; } if (g > 255) { g = 255; } if (b > 255) { b = 255; } if (r < 0) { r = 0; } if (g < 0) { g = 0; } if (b < 0) { b = 0; } r &= 0xfe; g &= 0xfe; b &= 0xfe; pr[x] = r; pg[x] = g; pb[x] = b; pa[x] = a; image.SetPixel(x++, y, Color.FromArgb(a, b, g, r)); } } } } }
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (comboBox1.SelectedIndex == -1) { textBoxTitle.Clear(); textBoxTitle.ReadOnly = true; comboBox1.Enabled = false; button1.Enabled = false; button2.Enabled = false; checkBoxReplaced.Checked = false; selectedImage = null; return; } selectedImage = (PackageImage)comboBox1.SelectedItem; button1.Enabled = true; textBoxTitle.Text = selectedImage.title; textBoxTitle.ReadOnly = false; labelHash.Text = selectedImage.hash; labelSize.Text = selectedImage.width + " x " + selectedImage.height; if (File.Exists(Path.Combine(pkgLocation, Path.Combine("Dump", selectedImage.hash + ".png")))) { pictureBox1.Image = Image.FromFile(Path.Combine(pkgLocation, Path.Combine("Dump", selectedImage.hash + ".png"))); } else { if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); } pictureBox1.Image = null; } if (selectedImage.replacementLen > 0) { checkBoxReplaced.Checked = true; button2.Enabled = true; if ((selectedImage.flags & 0xFF) == 2 || (selectedImage.flags & 0xFF) == 3) { Bitmap bm = new Bitmap(selectedImage.width, selectedImage.height); CBitReader cr = new CBitReader(selectedImage.replacement); switch (selectedImage.flags & 0xFF) { case 2: CR6Ti.DecodeOpaque1(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; case 3: CR6Ti.DecodeTransparent(cr, bm, selectedImage.width, selectedImage.height, selectedImage.depth); break; } pictureBox2.Image = bm; } else { if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); } pictureBox2.Image = null; } } else { checkBoxReplaced.Checked = false; if (pictureBox2.Image != null) { pictureBox2.Image.Dispose(); } pictureBox2.Image = null; } switch (selectedImage.flags & 0xFF) { case 2: if ((selectedImage.depth & 0x4) != 0) { labelType.Text = "Opaque1"; } else { labelType.Text = "Opaque2"; } break; case 3: labelType.Text = "Transparent"; break; default: labelType.Text = "Unknown"; break; } }
// Now this is basically 99% copied from alterdec static public void DecodeOpaque1(CBitReader s, Bitmap image, int width, int height, int depth) { int[] pr = new int[width]; int[] pg = new int[width]; int[] pb = new int[width]; for (int y = 0; y < height; y++) { int count = -1; int r, g, b; int dr, dg, db; r = g = b = 0; dr = dg = db = 0; for (int x = 0; x < width;) { if (count == -1) { count = (int)s.ReadUnsigned(); } if (s.ReadBit() == 1) { r = pr[x]; g = pg[x]; b = pb[x]; dr = dg = db = 0; } else { int t = g + dg * 2; if (t > 255) { t = 255; } if (t < 0) { t = 0; } t -= g; dg = s.ReadSigned(); dg += t / 2; if (dg < -128) { dg = -128; } if (dg > 127) { dg = 127; } db = dr = dg; r += dr * 2; g += dg * 2; b += db * 2; if (r > 255) { r = 255; } if (g > 255) { g = 255; } if (b > 255) { b = 255; } if (r < 0) { r = 0; } if (g < 0) { g = 0; } if (b < 0) { b = 0; } r += s.ReadSigned() * 2; if (r > 255) { r = 255; } if (r < 0) { r = 0; } b += s.ReadSigned() * 2; if (b > 255) { b = 255; } if (b < 0) { b = 0; } } pr[x] = r; pg[x] = g; pb[x] = b; image.SetPixel(x++, y, Color.FromArgb(b, g, r)); if (count-- == 0 && x < width) { int n = (int)s.ReadUnsigned() + 1; for (int i = 0; i < n; i++) { pr[x] = r; pg[x] = g; pb[x] = b; image.SetPixel(x++, y, Color.FromArgb(b, g, r)); } dr = dg = db = 0; } } } }