/// <summary> /// Creates a Blp2 object from the specified file path. /// </summary> /// <param name="filename">A file path that contains the data of a Blp2 or System.Drawing.Image picture.</param> /// <returns>Blp2 object containing the image of the file.</returns> /// <exception cref=""></exception> public static Blp2 FromFile(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { Blp2 ret = FromStream(fs); return(ret); } }
/// <summary> /// Creates a Blp2 object from the specified data stream. /// </summary> /// <param name="stream">A stream that contains the data of a Blp2 or System.Drawing.Image picture.</param> /// <returns>Blp2 object containing the image of the stream.</returns> /// <exception cref=""></exception> public static Blp2 FromStream(Stream stream) { using (BinaryReader br = new BinaryReader(stream)) { Blp2Header header = Blp2Header.FromBinaryReader(br); Blp2 ret = new Blp2(); if (new string(header.fourCC) == "BLP2") { ret.bmp = new Bitmap((int)header.width, (int)header.height, PixelFormat.Format32bppArgb); BitmapData bmpData = ret.bmp.LockBits(new Rectangle(0, 0, ret.bmp.Width, ret.bmp.Height), ImageLockMode.ReadWrite, ret.bmp.PixelFormat); byte[] imgData = new byte[header.lengths[0]]; br.BaseStream.Seek(header.offsets[0], SeekOrigin.Begin); imgData = br.ReadBytes(imgData.Length); // BLP2 conversion if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.RAW1 && (header.alphaDepth == AlphaDepth.NoAlpha || header.alphaDepth == AlphaDepth.Alpha1Bit || header.alphaDepth == AlphaDepth.Alpha8Bit)) { // Uncompressed paletted image ret.format = FileFormat.Raw; // Load palette (4-byte BGRA color values) br.BaseStream.Seek(Marshal.SizeOf(typeof(Blp2Header)), SeekOrigin.Begin); byte[] colorData = br.ReadBytes(256 * 4); Color[] c = new Color[256]; for (int i = 0; i < 1024; i += 4) { c[i / 4] = Color.FromArgb(255, colorData[i], colorData[i + 1], colorData[i + 2]); } // Read indexed bitmap byte[] decompImgData = new byte[header.width * header.height * 4]; for (int i = 0; i < (header.width * header.height); i++) { decompImgData[i * 4] = c[imgData[i]].R; decompImgData[i * 4 + 1] = c[imgData[i]].G; decompImgData[i * 4 + 2] = c[imgData[i]].B; decompImgData[i * 4 + 3] = 255; } // Apply alpha channels if (header.alphaDepth == AlphaDepth.Alpha8Bit) { // 8-bits alpha br.BaseStream.Seek(header.offsets[0] + header.width * header.height, SeekOrigin.Begin); byte[] alphaData = br.ReadBytes((int)(header.width * header.height)); for (int i = 0; i < (header.width * header.height); i++) { decompImgData[i * 4 + 3] = alphaData[i]; } } else if (header.alphaDepth == AlphaDepth.Alpha1Bit) { // 1-bits alpha br.BaseStream.Seek(header.offsets[0] + (header.width * header.height), SeekOrigin.Begin); byte[] alphaData = br.ReadBytes((int)(header.width * header.height / 8)); for (int i = 0; i < (header.width * header.height / 8); i++) { for (int j = 0; j < 8; j++) { decompImgData[i * 32 + ((j + 1) * 4) - 1] = (byte)((alphaData[i] & 1 << j) == 1 << j ? 255 : 0); } } } Marshal.Copy(decompImgData, 0, bmpData.Scan0, decompImgData.Length); } else if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.RAW3 && (header.alphaDepth == AlphaDepth.NoAlpha || header.alphaDepth == AlphaDepth.Alpha1Bit || header.alphaDepth == AlphaDepth.Alpha8Bit)) { // Uncompressed BGRA image ret.format = FileFormat.Raw; Marshal.Copy(imgData, 0, bmpData.Scan0, imgData.Length); } else if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.DXT && (header.alphaEncoding == AlphaEncoding.DXT1 || header.alphaEncoding == AlphaEncoding.DXT3 || header.alphaEncoding == AlphaEncoding.DXT5)) { // DXT1/3/5 ret.format = FileFormat.Dxt; byte[] decompImgData = new byte[header.width * header.height * 4]; LibSquish.DxtFormat flags = 0; switch (header.alphaEncoding) { case AlphaEncoding.DXT1: flags = LibSquish.DxtFormat.Dxt1; break; case AlphaEncoding.DXT3: flags = LibSquish.DxtFormat.Dxt3; break; case AlphaEncoding.DXT5: flags = LibSquish.DxtFormat.Dxt5; break; } LibSquish.DecompressImage(decompImgData, header.width, header.height, imgData, (int)flags); RemapRGBA(ref decompImgData); Marshal.Copy(decompImgData, 0, bmpData.Scan0, decompImgData.Length); } else if (header.type == DataType.JPEG) { ret.format = FileFormat.Jpeg; ret.bmp.UnlockBits(bmpData); throw new NotImplementedException(); } else { ret.bmp.UnlockBits(bmpData); throw new BlpFormatException("The given BLP2 format is not supported."); } ret.bmp.UnlockBits(bmpData); } else { try { // Let System.Drawing.Image handle loading ret.bmp = (Bitmap)Image.FromStream(stream); ret.format = FileFormat.Image; } catch (ArgumentException e) { throw new BlpFormatException("The stream did not contain valid image data.", e.InnerException); } } ret.header = header; return(ret); } }
private void listTalentTab_SelectedIndexChanged(object sender, EventArgs e) { Blp2 blpFile = new Blp2(); icons.Clear(); listTalents.Items.Clear(); TalentTabEntry tab = (TalentTabEntry)listTalentTab.SelectedItem; foreach (TalentEntry t in DBCStores.Talent.Records.Where(th => th.TabId == tab.Id)) { listTalents.Items.Add(t); if (DBCStores.Spell.ContainsKey(t.RankId[0]) && DBCStores.SpellIcon.ContainsKey(DBCStores.Spell[t.RankId[0]].SpellIconID) && Stormlib.MPQFile.Exists(DBCStores.SpellIcon[DBCStores.Spell[t.RankId[0]].SpellIconID].IconPath + ".blp") && !icons.ContainsKey("SpellIcon." + t.Row.ToString() + "." + t.Col.ToString())) { blpFile = Blp2.FromStream(new Stormlib.MPQFile(DBCStores.SpellIcon[DBCStores.Spell[t.RankId[0]].SpellIconID].IconPath + ".blp")); icons.Add("SpellIcon." + t.Row.ToString() + "." + t.Col.ToString(), ResizeBitmap(blpFile, 40, 40)); } } listTalents.SelectedIndex = 0; LoadTalentTab(); }
private void MainForm_Load(object sender, EventArgs e) { talentTabScroll.Maximum = panelIn.Height - panelOut.Height; listTalentTab.Items.Clear(); foreach (TalentTabEntry t in DBCStores.TalentTab.Records) listTalentTab.Items.Add(t); Blp2 blpFile = new Blp2(); images.Add("TalentBack", Blp2.FromFile("Ressources\\DefaultTalentBack.blp")); blpFile = Blp2.FromFile("Ressources\\UI-TalentArrows.blp"); images.Add("TalentArrowsBottom", CropBitmap((Bitmap)blpFile, new Rectangle(0, 0, 32, 32))); images.Add("TalentArrowsRight", CropBitmap((Bitmap)blpFile, new Rectangle(32, 0, 32, 32))); images.Add("TalentArrowsLeft", RotateBitmap(CropBitmap((Bitmap)blpFile, new Rectangle(32, 0, 32, 32)), 180.0f)); images.Add("TalentRankBorder", Blp2.FromFile("Ressources\\TalentFrame-RankBorder.blp")); images.Add("TalentIdBorder", Blp2.FromFile("Ressources\\TalentFrame-IdBorder.blp")); blpFile = Blp2.FromFile("Ressources\\UI-TalentBranches.blp"); images.Add("TalentBarH", CropBitmap((Bitmap)blpFile, new Rectangle(32, 0, 32, 32))); images.Add("TalentBarHLittle", CropBitmap((Bitmap)blpFile, new Rectangle(32, 0, 32, 20))); images.Add("TalentBarV", CropBitmap((Bitmap)blpFile, new Rectangle(64, 0, 32, 32))); images.Add("TalentBarVLittle", CropBitmap((Bitmap)blpFile, new Rectangle(64, 0, 28, 32))); Bitmap bTmp = CropBitmap((Bitmap)blpFile, new Rectangle(128, 0, 32, 32)); bTmp.RotateFlip(RotateFlipType.RotateNoneFlipX); images.Add("TalentBarCR", bTmp); images.Add("TalentBarCL", CropBitmap((Bitmap)blpFile, new Rectangle(128, 0, 32, 32))); images.Add("SpellIconDefault", ResizeBitmap(Blp2.FromFile("Ressources\\DefaultTalentIcon.blp"), 45, 45)); listTalentTab.SelectedIndex = 0; }
/// <summary> /// Creates a Blp2 object from the specified data stream. /// </summary> /// <param name="stream">A stream that contains the data of a Blp2 or System.Drawing.Image picture.</param> /// <returns>Blp2 object containing the image of the stream.</returns> /// <exception cref=""></exception> public static Blp2 FromStream(Stream stream) { using (BinaryReader br = new BinaryReader(stream)) { Blp2Header header = Blp2Header.FromBinaryReader(br); Blp2 ret = new Blp2(); if (new string(header.fourCC) == "BLP2") { ret.bmp = new Bitmap((int)header.width, (int)header.height, PixelFormat.Format32bppArgb); BitmapData bmpData = ret.bmp.LockBits(new Rectangle(0, 0, ret.bmp.Width, ret.bmp.Height), ImageLockMode.ReadWrite, ret.bmp.PixelFormat); byte[] imgData = new byte[header.lengths[0]]; br.BaseStream.Seek(header.offsets[0], SeekOrigin.Begin); imgData = br.ReadBytes(imgData.Length); // BLP2 conversion if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.RAW1 && (header.alphaDepth == AlphaDepth.NoAlpha || header.alphaDepth == AlphaDepth.Alpha1Bit || header.alphaDepth == AlphaDepth.Alpha8Bit)) { // Uncompressed paletted image ret.format = FileFormat.Raw; // Load palette (4-byte BGRA color values) br.BaseStream.Seek(Marshal.SizeOf(typeof(Blp2Header)), SeekOrigin.Begin); byte[] colorData = br.ReadBytes(256 * 4); Color[] c = new Color[256]; for (int i = 0; i < 1024; i += 4) { c[i / 4] = Color.FromArgb(255, colorData[i], colorData[i + 1], colorData[i + 2]); } // Read indexed bitmap byte[] decompImgData = new byte[header.width * header.height * 4]; for (int i = 0; i < (header.width * header.height); i++) { decompImgData[i * 4] = c[imgData[i]].R; decompImgData[i * 4 + 1] = c[imgData[i]].G; decompImgData[i * 4 + 2] = c[imgData[i]].B; decompImgData[i * 4 + 3] = 255; } // Apply alpha channels if (header.alphaDepth == AlphaDepth.Alpha8Bit) { // 8-bits alpha br.BaseStream.Seek(header.offsets[0] + header.width * header.height, SeekOrigin.Begin); byte[] alphaData = br.ReadBytes((int)(header.width * header.height)); for (int i = 0; i < (header.width * header.height); i++) { decompImgData[i * 4 + 3] = alphaData[i]; } } else if (header.alphaDepth == AlphaDepth.Alpha1Bit) { // 1-bits alpha br.BaseStream.Seek(header.offsets[0] + (header.width * header.height), SeekOrigin.Begin); byte[] alphaData = br.ReadBytes((int)(header.width * header.height / 8)); for (int i = 0; i < (header.width * header.height / 8); i++) for (int j = 0; j < 8; j++) decompImgData[i * 32 + ((j + 1) * 4) - 1] = (byte)((alphaData[i] & 1 << j) == 1 << j ? 255 : 0); } Marshal.Copy(decompImgData, 0, bmpData.Scan0, decompImgData.Length); } else if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.RAW3 && (header.alphaDepth == AlphaDepth.NoAlpha || header.alphaDepth == AlphaDepth.Alpha1Bit || header.alphaDepth == AlphaDepth.Alpha8Bit)) { // Uncompressed BGRA image ret.format = FileFormat.Raw; Marshal.Copy(imgData, 0, bmpData.Scan0, imgData.Length); } else if (header.type == DataType.Uncompressed_DirectX && header.encoding == Encoding.DXT && (header.alphaEncoding == AlphaEncoding.DXT1 || header.alphaEncoding == AlphaEncoding.DXT3 || header.alphaEncoding == AlphaEncoding.DXT5)) { // DXT1/3/5 ret.format = FileFormat.Dxt; byte[] decompImgData = new byte[header.width * header.height * 4]; LibSquish.DxtFormat flags = 0; switch (header.alphaEncoding) { case AlphaEncoding.DXT1: flags = LibSquish.DxtFormat.Dxt1; break; case AlphaEncoding.DXT3: flags = LibSquish.DxtFormat.Dxt3; break; case AlphaEncoding.DXT5: flags = LibSquish.DxtFormat.Dxt5; break; } LibSquish.DecompressImage(decompImgData, header.width, header.height, imgData, (int)flags); RemapRGBA(ref decompImgData); Marshal.Copy(decompImgData, 0, bmpData.Scan0, decompImgData.Length); } else if (header.type == DataType.JPEG) { ret.format = FileFormat.Jpeg; ret.bmp.UnlockBits(bmpData); throw new NotImplementedException(); } else { ret.bmp.UnlockBits(bmpData); throw new BlpFormatException("The given BLP2 format is not supported."); } ret.bmp.UnlockBits(bmpData); } else { try { // Let System.Drawing.Image handle loading ret.bmp = (Bitmap)Image.FromStream(stream); ret.format = FileFormat.Image; } catch (ArgumentException e) { throw new BlpFormatException("The stream did not contain valid image data.", e.InnerException); } } ret.header = header; return ret; } }