MLibrary.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.IO.Compression;
  8. using System.Runtime.InteropServices;
  9. using System.Text;
  10. using System.Windows.Forms;
  11. namespace LibraryViewer
  12. {
  13. public sealed class MLibrary
  14. {
  15. public const int LibVersion = 3;
  16. public static bool Load = true;
  17. public string FileName;
  18. public List<MImage> Images = new List<MImage>();
  19. public List<int> IndexList = new List<int>();
  20. public int Count;
  21. private bool _initialized;
  22. private BinaryReader _reader;
  23. private FileStream _stream;
  24. public MLibrary(string filename)
  25. {
  26. FileName = filename;
  27. Initialize();
  28. Close();
  29. }
  30. public void Initialize()
  31. {
  32. int CurrentVersion;
  33. _initialized = true;
  34. if (!File.Exists(FileName))
  35. return;
  36. _stream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
  37. _reader = new BinaryReader(_stream);
  38. CurrentVersion = _reader.ReadInt32();
  39. if (CurrentVersion < 2)
  40. {
  41. MessageBox.Show("Wrong version, expecting lib version: " + LibVersion.ToString() + " found version: " + CurrentVersion.ToString() + ".", "Failed to open", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
  42. return;
  43. }
  44. Count = _reader.ReadInt32();
  45. Images = new List<MImage>();
  46. IndexList = new List<int>();
  47. int frameSeek = 0;
  48. if (CurrentVersion >= 3)
  49. {
  50. frameSeek = _reader.ReadInt32();
  51. }
  52. for (int i = 0; i < Count; i++)
  53. IndexList.Add(_reader.ReadInt32());
  54. for (int i = 0; i < Count; i++)
  55. Images.Add(null);
  56. for (int i = 0; i < Count; i++)
  57. CheckImage(i);
  58. }
  59. public void Close()
  60. {
  61. if (_stream != null)
  62. _stream.Dispose();
  63. }
  64. private void CheckImage(int index)
  65. {
  66. if (!_initialized)
  67. Initialize();
  68. if (Images == null || index < 0 || index >= Images.Count)
  69. return;
  70. if (Images[index] == null)
  71. {
  72. _stream.Position = IndexList[index];
  73. Images[index] = new MImage(_reader);
  74. }
  75. if (!Load) return;
  76. MImage mi = Images[index];
  77. if (!mi.TextureValid)
  78. {
  79. _stream.Seek(IndexList[index] + 12, SeekOrigin.Begin);
  80. mi.CreateTexture(_reader);
  81. }
  82. }
  83. public MImage GetMImage(int index)
  84. {
  85. if (index < 0 || index >= Images.Count)
  86. return null;
  87. return Images[index];
  88. }
  89. public Bitmap GetPreview(int index)
  90. {
  91. if (index < 0 || index >= Images.Count)
  92. return new Bitmap(1, 1);
  93. MImage image = Images[index];
  94. if (image == null || image.Image == null)
  95. return new Bitmap(1, 1);
  96. if (image.Preview == null)
  97. image.CreatePreview();
  98. return image.Preview;
  99. }
  100. public void RemoveImage(int index)
  101. {
  102. if (Images == null || Count <= 1)
  103. {
  104. Count = 0;
  105. Images = new List<MImage>();
  106. return;
  107. }
  108. Count--;
  109. Images.RemoveAt(index);
  110. }
  111. public sealed class MImage
  112. {
  113. public short Width, Height, X, Y, ShadowX, ShadowY;
  114. public byte Shadow;
  115. public int Length;
  116. public byte[] FBytes;
  117. public bool TextureValid;
  118. public Bitmap Image, Preview;
  119. //layer 2:
  120. public short MaskWidth, MaskHeight, MaskX, MaskY;
  121. public int MaskLength;
  122. public byte[] MaskFBytes;
  123. public Bitmap MaskImage;
  124. public Boolean HasMask;
  125. public MImage(BinaryReader reader)
  126. {
  127. //read layer 1
  128. Width = reader.ReadInt16();
  129. Height = reader.ReadInt16();
  130. X = reader.ReadInt16();
  131. Y = reader.ReadInt16();
  132. ShadowX = reader.ReadInt16();
  133. ShadowY = reader.ReadInt16();
  134. Shadow = reader.ReadByte();
  135. Length = reader.ReadInt32();
  136. FBytes = reader.ReadBytes(Length);
  137. //check if there's a second layer and read it
  138. HasMask = ((Shadow >> 7) == 1) ? true : false;
  139. if (HasMask)
  140. {
  141. MaskWidth = reader.ReadInt16();
  142. MaskHeight = reader.ReadInt16();
  143. MaskX = reader.ReadInt16();
  144. MaskY = reader.ReadInt16();
  145. MaskLength = reader.ReadInt32();
  146. MaskFBytes = reader.ReadBytes(MaskLength);
  147. }
  148. }
  149. private unsafe byte[] ConvertBitmapToArray(Bitmap input)
  150. {
  151. BitmapData data = input.LockBits(new Rectangle(0, 0, input.Width, input.Height), ImageLockMode.ReadOnly,
  152. PixelFormat.Format32bppArgb);
  153. byte[] pixels = new byte[input.Width * input.Height * 4];
  154. Marshal.Copy(data.Scan0, pixels, 0, pixels.Length);
  155. input.UnlockBits(data);
  156. for (int i = 0; i < pixels.Length; i += 4)
  157. {
  158. if (pixels[i] == 0 && pixels[i + 1] == 0 && pixels[i + 2] == 0)
  159. pixels[i + 3] = 0; //Make Transparent
  160. }
  161. byte[] compressedBytes;
  162. compressedBytes = Compress(pixels);
  163. return compressedBytes;
  164. }
  165. public unsafe void CreateTexture(BinaryReader reader)
  166. {
  167. int w = Width;// +(4 - Width % 4) % 4;
  168. int h = Height;// +(4 - Height % 4) % 4;
  169. if (w == 0 || h == 0)
  170. return;
  171. if ((w < 2) || (h < 2)) return;
  172. Image = new Bitmap(w, h);
  173. BitmapData data = Image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite,
  174. PixelFormat.Format32bppArgb);
  175. byte[] dest = Decompress(FBytes);
  176. Marshal.Copy(dest, 0, data.Scan0, dest.Length);
  177. Image.UnlockBits(data);
  178. dest = null;
  179. if (HasMask)
  180. {
  181. w = MaskWidth;// +(4 - MaskWidth % 4) % 4;
  182. h = MaskHeight;// +(4 - MaskHeight % 4) % 4;
  183. if (w == 0 || h == 0)
  184. {
  185. return;
  186. }
  187. try
  188. {
  189. MaskImage = new Bitmap(w, h);
  190. data = MaskImage.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite,
  191. PixelFormat.Format32bppArgb);
  192. dest = Decompress(MaskFBytes);
  193. Marshal.Copy(dest, 0, data.Scan0, dest.Length);
  194. MaskImage.UnlockBits(data);
  195. }
  196. catch (Exception ex)
  197. {
  198. File.AppendAllText(@".\Error.txt",
  199. string.Format("[{0}] {1}{2}", DateTime.Now, ex, Environment.NewLine));
  200. }
  201. }
  202. dest = null;
  203. }
  204. public static byte[] Compress(byte[] raw)
  205. {
  206. using (MemoryStream memory = new MemoryStream())
  207. {
  208. using (GZipStream gzip = new GZipStream(memory,
  209. CompressionMode.Compress, true))
  210. {
  211. gzip.Write(raw, 0, raw.Length);
  212. }
  213. return memory.ToArray();
  214. }
  215. }
  216. static byte[] Decompress(byte[] gzip)
  217. {
  218. // Create a GZIP stream with decompression mode.
  219. // ... Then create a buffer and write into while reading from the GZIP stream.
  220. using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
  221. {
  222. const int size = 4096;
  223. byte[] buffer = new byte[size];
  224. using (MemoryStream memory = new MemoryStream())
  225. {
  226. int count = 0;
  227. do
  228. {
  229. count = stream.Read(buffer, 0, size);
  230. if (count > 0)
  231. {
  232. memory.Write(buffer, 0, count);
  233. }
  234. }
  235. while (count > 0);
  236. return memory.ToArray();
  237. }
  238. }
  239. }
  240. public void CreatePreview()
  241. {
  242. if (Image == null)
  243. {
  244. Preview = new Bitmap(1, 1);
  245. return;
  246. }
  247. Preview = new Bitmap(64, 64);
  248. using (Graphics g = Graphics.FromImage(Preview))
  249. {
  250. g.InterpolationMode = InterpolationMode.Low;//HighQualityBicubic
  251. g.Clear(Color.Transparent);
  252. int w = Math.Min((int)Width, 64);
  253. int h = Math.Min((int)Height, 64);
  254. g.DrawImage(Image, new Rectangle((64 - w) / 2, (64 - h) / 2, w, h), new Rectangle(0, 0, Width, Height), GraphicsUnit.Pixel);
  255. g.Save();
  256. }
  257. }
  258. }
  259. }
  260. }