| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- using ManagedSquish;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace LibraryEditor
- {
- /// <summary>
- /// V1 Library
- /// Uses DXT1 Images
- /// </summary>
- public sealed class MLibraryV1
- {
- public const int LibVersion = 1;
- public static bool Load = true;
- public string FileName;
-
- public List<MImage> Images = new List<MImage>();
- public List<int> IndexList = new List<int>();
- public int Count;
- private bool _initialized;
- private BinaryReader _reader;
- private FileStream _stream;
- public MLibraryV1(string filename)
- {
- FileName = filename;
- Initialize();
- Close();
- }
- public void Initialize()
- {
- int CurrentVersion;
- _initialized = true;
- if (!File.Exists(FileName))
- return;
- _stream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
- _reader = new BinaryReader(_stream);
- CurrentVersion = _reader.ReadInt32();
- if (CurrentVersion != LibVersion)
- {
- MessageBox.Show("Wrong version, expecting lib version: " + LibVersion.ToString() + " found version: " + CurrentVersion.ToString() + ".", "Failed to open", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
- return;
- }
- Count = _reader.ReadInt32();
- Images = new List<MImage>();
- IndexList = new List<int>();
- for (int i = 0; i < Count; i++)
- IndexList.Add(_reader.ReadInt32());
- for (int i = 0; i < Count; i++)
- Images.Add(null);
- for (int i = 0; i < Count; i++)
- CheckImage(i);
- }
- public void Close()
- {
- if (_stream != null)
- _stream.Dispose();
- // if (_reader != null)
- // _reader.Dispose();
- }
- public void Save()
- {
- Close();
- MemoryStream stream = new MemoryStream();
- BinaryWriter writer = new BinaryWriter(stream);
- Count = Images.Count;
- IndexList.Clear();
- int offSet = 8 + Count * 4;
- for (int i = 0; i < Count; i++)
- {
- IndexList.Add((int)stream.Length + offSet);
- Images[i].Save(writer);
- }
- writer.Flush();
- byte[] fBytes = stream.ToArray();
- // writer.Dispose();
- _stream = File.Create(FileName);
- writer = new BinaryWriter(_stream);
- writer.Write(LibVersion);
- writer.Write(Count);
- for (int i = 0; i < Count; i++)
- writer.Write(IndexList[i]);
- writer.Write(fBytes);
- writer.Flush();
- writer.Close();
- writer.Dispose();
- Close();
- }
- private void CheckImage(int index)
- {
- if (!_initialized)
- Initialize();
- if (Images == null || index < 0 || index >= Images.Count)
- return;
- if (Images[index] == null)
- {
- _stream.Position = IndexList[index];
- Images[index] = new MImage(_reader);
- }
- if (!Load) return;
- MImage mi = Images[index];
- if (!mi.TextureValid)
- {
- _stream.Seek(IndexList[index] + 12, SeekOrigin.Begin);
- mi.CreateTexture(_reader);
- }
- }
- public void ToMLibrary()
- {
- string fileName = Path.ChangeExtension(FileName, ".Lib");
- fileName = fileName.Replace(".Lib", "-converted.Lib");
- if (File.Exists(fileName))
- File.Delete(fileName);
- MLibraryV2 library = new MLibraryV2(fileName) { Images = new List<MLibraryV2.MImage>(), IndexList = new List<int>(), Count = Images.Count };
- //library.Save();
- for (int i = 0; i < library.Count; i++)
- library.Images.Add(null);
- ParallelOptions options = new ParallelOptions { MaxDegreeOfParallelism = 8 };
- try
- {
- Parallel.For(0, Images.Count, options, i =>
- {
- MImage image = Images[i];
- if (image.HasMask)
- library.Images[i] = new MLibraryV2.MImage(image.Image, image.MaskImage) { X = image.X, Y = image.Y, ShadowX = image.ShadowX, ShadowY = image.ShadowY, Shadow = image.Shadow, MaskX = image.X, MaskY = image.Y };
- else
- library.Images[i] = new MLibraryV2.MImage(image.Image) { X = image.X, Y = image.Y, ShadowX = image.ShadowX, ShadowY = image.ShadowY, Shadow = image.Shadow };
- });
- }
- catch (System.Exception)
- {
- throw;
- }
- finally
- {
- library.Save();
- }
- // Operation finished.
- // System.Windows.Forms.MessageBox.Show("Converted " + fileName + " successfully.",
- // "Wemade Information",
- // System.Windows.Forms.MessageBoxButtons.OK,
- // System.Windows.Forms.MessageBoxIcon.Information,
- // System.Windows.Forms.MessageBoxDefaultButton.Button1);
- }
- public Point GetOffSet(int index)
- {
- if (!_initialized)
- Initialize();
- if (Images == null || index < 0 || index >= Images.Count)
- return Point.Empty;
- if (Images[index] == null)
- {
- _stream.Seek(IndexList[index], SeekOrigin.Begin);
- Images[index] = new MImage(_reader);
- }
- return new Point(Images[index].X, Images[index].Y);
- }
- public Size GetSize(int index)
- {
- if (!_initialized)
- Initialize();
- if (Images == null || index < 0 || index >= Images.Count)
- return Size.Empty;
- if (Images[index] == null)
- {
- _stream.Seek(IndexList[index], SeekOrigin.Begin);
- Images[index] = new MImage(_reader);
- }
- return new Size(Images[index].Width, Images[index].Height);
- }
- public MImage GetMImage(int index)
- {
- if (index < 0 || index >= Images.Count)
- return null;
- return Images[index];
- }
- public Bitmap GetPreview(int index)
- {
- if (index < 0 || index >= Images.Count)
- return new Bitmap(1, 1);
- MImage image = Images[index];
- if (image == null || image.Image == null)
- return new Bitmap(1, 1);
- if (image.Preview == null)
- image.CreatePreview();
- return image.Preview;
- }
- public void AddImage(Bitmap image, short x, short y)
- {
- MImage mImage = new MImage(image) { X = x, Y = y };
- Count++;
- Images.Add(mImage);
- }
- public void ReplaceImage(int Index, Bitmap image, short x, short y)
- {
- MImage mImage = new MImage(image) { X = x, Y = y };
- Images[Index] = mImage;
- }
- public void InsertImage(int index, Bitmap image, short x, short y)
- {
- MImage mImage = new MImage(image) { X = x, Y = y };
- Count++;
- Images.Insert(index, mImage);
- }
- public void RemoveImage(int index)
- {
- if (Images == null || Count <= 1)
- {
- Count = 0;
- Images = new List<MImage>();
- return;
- }
- Count--;
- Images.RemoveAt(index);
- }
- public static bool CompareBytes(byte[] a, byte[] b)
- {
- if (a == b) return true;
- if (a == null || b == null || a.Length != b.Length) return false;
- for (int i = 0; i < a.Length; i++) if (a[i] != b[i]) return false;
- return true;
- }
- public void RemoveBlanks(bool safe = false)
- {
- for (int i = Count - 1; i >= 0; i--)
- {
- if (Images[i].FBytes == null || Images[i].FBytes.Length <= 8)
- {
- if (!safe)
- RemoveImage(i);
- else if (Images[i].X == 0 && Images[i].Y == 0)
- RemoveImage(i);
- }
- }
- }
- public sealed class MImage
- {
- public short Width, Height, X, Y, ShadowX, ShadowY;
- public byte Shadow;
- public int Length;
- public byte[] FBytes;
- public bool TextureValid;
- public Bitmap Image, Preview;
- //layer 2:
- public short MaskWidth, MaskHeight, MaskX, MaskY;
- public int MaskLength;
- public byte[] MaskFBytes;
- public Bitmap MaskImage;
- public Boolean HasMask;
- public MImage(BinaryReader reader)
- {
- //read layer 1
- Width = reader.ReadInt16();
- Height = reader.ReadInt16();
- X = reader.ReadInt16();
- Y = reader.ReadInt16();
- ShadowX = reader.ReadInt16();
- ShadowY = reader.ReadInt16();
- Shadow = reader.ReadByte();
- Length = reader.ReadInt32();
- FBytes = reader.ReadBytes(Length);
- //check if there's a second layer and read it
- HasMask = ((Shadow >> 7) == 1) ? true : false;
- if (HasMask)
- {
- MaskWidth = reader.ReadInt16();
- MaskHeight = reader.ReadInt16();
- MaskX = reader.ReadInt16();
- MaskY = reader.ReadInt16();
- MaskLength = reader.ReadInt32();
- MaskFBytes = reader.ReadBytes(MaskLength);
- }
- }
- public MImage(byte[] image, short Width, short Height)//only use this when converting from old to new type!
- {
- FBytes = image;
- this.Width = Width;
- this.Height = Height;
- }
- public MImage(Bitmap image)
- {
- if (image == null)
- {
- FBytes = new byte[0];
- return;
- }
- Width = (short)image.Width;
- Height = (short)image.Height;
- Image = FixImageSize(image);
- FBytes = ConvertBitmapToArray(Image);
- }
- public MImage(Bitmap image, Bitmap Maskimage)
- {
- if (image == null)
- {
- FBytes = new byte[0];
- return;
- }
- Width = (short)image.Width;
- Height = (short)image.Height;
- Image = FixImageSize(image);
- FBytes = ConvertBitmapToArray(Image);
- if (Maskimage == null)
- {
- MaskFBytes = new byte[0];
- return;
- }
- HasMask = true;
- MaskWidth = (short)Maskimage.Width;
- MaskHeight = (short)Maskimage.Height;
- MaskImage = FixImageSize(Maskimage);
- MaskFBytes = ConvertBitmapToArray(MaskImage);
- }
- private Bitmap FixImageSize(Bitmap input)
- {
- int w = input.Width + (4 - input.Width % 4) % 4;
- int h = input.Height + (4 - input.Height % 4) % 4;
- if (input.Width != w || input.Height != h)
- {
- Bitmap temp = new Bitmap(w, h);
- using (Graphics g = Graphics.FromImage(temp))
- {
- g.Clear(Color.Transparent);
- g.InterpolationMode = InterpolationMode.NearestNeighbor;
- g.DrawImage(input, 0, 0);
- g.Save();
- }
- input.Dispose();
- input = temp;
- }
- return input;
- }
- private unsafe byte[] ConvertBitmapToArray(Bitmap input)
- {
- byte[] output;
- BitmapData data = input.LockBits(new Rectangle(0, 0, input.Width, input.Height), ImageLockMode.ReadOnly,
- PixelFormat.Format32bppArgb);
- byte[] pixels = new byte[input.Width * input.Height * 4];
- Marshal.Copy(data.Scan0, pixels, 0, pixels.Length);
- input.UnlockBits(data);
- for (int i = 0; i < pixels.Length; i += 4)
- {
- //Reverse Red/Blue
- byte b = pixels[i];
- pixels[i] = pixels[i + 2];
- pixels[i + 2] = b;
- if (pixels[i] == 0 && pixels[i + 1] == 0 && pixels[i + 2] == 0)
- pixels[i + 3] = 0; //Make Transparent
- }
- int count = Squish.GetStorageRequirements(input.Width, input.Height, SquishFlags.Dxt1);
- output = new byte[count];
- fixed (byte* dest = output)
- fixed (byte* source = pixels)
- {
- Squish.CompressImage((IntPtr)source, input.Width, input.Height, (IntPtr)dest, SquishFlags.Dxt1);
- }
- return output;
- }
- public void Save(BinaryWriter writer)
- {
- writer.Write(Width);
- writer.Write(Height);
- writer.Write(X);
- writer.Write(Y);
- writer.Write(ShadowX);
- writer.Write(ShadowY);
- writer.Write(HasMask ? (byte)(Shadow | 0x80) : (byte)Shadow);
- writer.Write(FBytes.Length);
- writer.Write(FBytes);
- if (HasMask)
- {
- writer.Write(MaskWidth);
- writer.Write(MaskHeight);
- writer.Write(MaskX);
- writer.Write(MaskY);
- writer.Write(MaskFBytes.Length);
- writer.Write(MaskFBytes);
- }
- }
- public unsafe void CreateTexture(BinaryReader reader)
- {
- int w = Width + (4 - Width % 4) % 4;
- int h = Height + (4 - Height % 4) % 4;
- if (w == 0 || h == 0)
- {
- return;
- }
- Image = new Bitmap(w, h);
- BitmapData data = Image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite,
- PixelFormat.Format32bppArgb);
- fixed (byte* source = FBytes)
- Squish.DecompressImage(data.Scan0, w, h, (IntPtr)source, SquishFlags.Dxt1);
- byte* dest = (byte*)data.Scan0;
- for (int i = 0; i < h * w * 4; i += 4)
- {
- //Reverse Red/Blue
- byte b = dest[i];
- dest[i] = dest[i + 2];
- dest[i + 2] = b;
- }
- Image.UnlockBits(data);
- if (HasMask)
- {
- w = MaskWidth + (4 - MaskWidth % 4) % 4;
- h = MaskHeight + (4 - MaskHeight % 4) % 4;
- if (w == 0 || h == 0)
- {
- return;
- }
- MaskImage = new Bitmap(w, h);
- data = MaskImage.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite,
- PixelFormat.Format32bppArgb);
- fixed (byte* source = MaskFBytes)
- Squish.DecompressImage(data.Scan0, w, h, (IntPtr)source, SquishFlags.Dxt1);
- dest = (byte*)data.Scan0;
- for (int i = 0; i < h * w * 4; i += 4)
- {
- //Reverse Red/Blue
- byte b = dest[i];
- dest[i] = dest[i + 2];
- dest[i + 2] = b;
- }
- MaskImage.UnlockBits(data);
- }
- }
- public void CreatePreview()
- {
- if (Image == null)
- {
- Preview = new Bitmap(1, 1);
- return;
- }
- Preview = new Bitmap(64, 64);
- using (Graphics g = Graphics.FromImage(Preview))
- {
- g.InterpolationMode = InterpolationMode.NearestNeighbor;//HighQualityBicubic
- g.Clear(Color.Transparent);
- int w = Math.Min((int)Width, 64);
- int h = Math.Min((int)Height, 64);
- g.DrawImage(Image, new Rectangle((64 - w) / 2, (64 - h) / 2, w, h), new Rectangle(0, 0, Width, Height), GraphicsUnit.Pixel);
- g.Save();
- }
- }
- }
- }
- }
|