Пример #1
0
 /// <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);
     }
 }
Пример #2
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);
            }
        }
Пример #3
0
        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();
        }
Пример #4
0
        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;
        }
Пример #5
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;
            }
        }