public override Image GetMipmapImage(int mipmapIndex) { if (mipmapIndex < 0 || mipmapIndex >= m_mipmaps.Count) { throw new ArgumentOutOfRangeException("mipmapIndex", mipmapIndex, "Index must be non-negative and less than the number of mipmaps in this BLP file."); } Blp2MipMap mipmap = m_mipmaps[mipmapIndex]; Image result = null; if (m_cmpType == Blp2CompressionType.Palette) { result = FromPalette(mipmap); } else if (m_cmpType == Blp2CompressionType.DirectX) { if (m_alphaBits == 0 || m_alphaBits == 1) { result = FromDxt1(mipmap); } else if (m_alphaBits == 8) { result = FromDxt5(mipmap); } } else { result = FromJpeg(mipmap); } return(result); }
private Image FromJpeg(Blp2MipMap mipmap) { byte[] result = new byte[BLP1_JPG_HEADER_SIZE + mipmap.Data.Length]; Buffer.BlockCopy(m_jpgHeader, 0, result, 0, m_jpgHeader.Length); Buffer.BlockCopy(mipmap.Data, 0, result, BLP1_JPG_HEADER_SIZE, mipmap.Data.Length); Image img; using (MemoryStream ms = new MemoryStream(result, false)) { img = Image.FromStream(ms, false, false); } return(img); }
private Image FromPalette(Blp2MipMap mipmap) { Bitmap bmp = new Bitmap(mipmap.Size.Width, mipmap.Size.Height, PixelFormat.Format32bppArgb); byte[] mipmapData = mipmap.Data; int[] result = new int[mipmap.Size.Width * mipmap.Size.Height]; for (int i = 0; i < result.Length; i++) { Color paletteEntry = m_palette[mipmapData[i]]; result[i] = paletteEntry.ToArgb(); } BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, mipmap.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(result, 0, bmpData.Scan0, result.Length); bmp.UnlockBits(bmpData); return(bmp); }
private void ParseInternal(Stream stream) { using (BinaryReader br = new BinaryReader(stream)) { br.ReadInt32(); // unknown m_cmpType = (Blp2CompressionType)br.ReadByte(); m_alphaBits = br.ReadByte(); int paletteBits = br.ReadByte(); br.ReadByte(); // unknown int width = br.ReadInt32(); int height = br.ReadInt32(); Size fullImageSize = new Size(width, height); m_mainSize = fullImageSize; int[] mipmapOffsets = new int[MAX_MIPMAP_COUNT]; for (int i = 0; i < MAX_MIPMAP_COUNT; i++) { mipmapOffsets[i] = br.ReadInt32(); } int[] sizes = new int[MAX_MIPMAP_COUNT]; for (int i = 0; i < MAX_MIPMAP_COUNT; i++) { sizes[i] = br.ReadInt32(); } if (m_cmpType == Blp2CompressionType.Palette) { if (paletteBits != 8) { throw new ArgumentException("Palettized data can only have 8 bits per pixel.", "stream"); } } else if (m_cmpType == Blp2CompressionType.DirectX) { if (m_alphaBits != 0 && m_alphaBits != 8 && m_alphaBits != 1) { throw new ArgumentException("DXT2/DXT4-compressed images are not yet supported."); } } else if (m_cmpType == Blp2CompressionType.Jpeg) { } else { throw new ArgumentException("Unknown file format."); } if (m_cmpType == Blp2CompressionType.Palette) { ParsePalette(stream, br); } else if (m_cmpType == Blp2CompressionType.Jpeg) { ParseJpegHeader(stream, br); } for (int i = 0; i < MAX_MIPMAP_COUNT; i++) { int currentOffset = mipmapOffsets[i]; int currentSize = sizes[i]; if (currentOffset == 0 || currentSize == 0) { break; } Size mipmapSize = Blp1Parser.GetSize(fullImageSize, i); byte[] data = new byte[currentSize]; stream.Seek(currentOffset, SeekOrigin.Begin); br.Read(data, 0, currentSize); Blp2MipMap mipmap = new Blp2MipMap(mipmapSize, i, data); m_mipmaps.Add(mipmap); } } }
private Image FromDxt1(Blp2MipMap mipmap) { int[] data = DXTCFormat.DecodeDXT1(mipmap.Size.Width, mipmap.Size.Height, mipmap.Data); return(FromBinary(mipmap.Size.Width, mipmap.Size.Height, data)); }
private void ParseInternal(Stream stream) { using (BinaryReader br = new BinaryReader(stream)) { br.ReadInt32(); // unknown m_cmpType = (Blp2CompressionType)br.ReadByte(); m_alphaBits = br.ReadByte(); int paletteBits = br.ReadByte(); br.ReadByte(); // unknown int width = br.ReadInt32(); int height = br.ReadInt32(); Size fullImageSize = new Size(width, height); m_mainSize = fullImageSize; int[] mipmapOffsets = new int[MAX_MIPMAP_COUNT]; for (int i = 0; i < MAX_MIPMAP_COUNT; i++) mipmapOffsets[i] = br.ReadInt32(); int[] sizes = new int[MAX_MIPMAP_COUNT]; for (int i = 0; i < MAX_MIPMAP_COUNT; i++) sizes[i] = br.ReadInt32(); if (m_cmpType == Blp2CompressionType.Palette) { if (paletteBits != 8) throw new ArgumentException("Palettized data can only have 8 bits per pixel.", "stream"); } else if (m_cmpType == Blp2CompressionType.DirectX) { if (m_alphaBits != 0 && m_alphaBits != 8 && m_alphaBits != 1) throw new ArgumentException("DXT2/DXT4-compressed images are not yet supported."); } else if (m_cmpType == Blp2CompressionType.Jpeg) { } else { throw new ArgumentException("Unknown file format."); } if (m_cmpType == Blp2CompressionType.Palette) { ParsePalette(stream, br); } else if (m_cmpType == Blp2CompressionType.Jpeg) { ParseJpegHeader(stream, br); } for (int i = 0; i < MAX_MIPMAP_COUNT; i++) { int currentOffset = mipmapOffsets[i]; int currentSize = sizes[i]; if (currentOffset == 0 || currentSize == 0) break; Size mipmapSize = Blp1Parser.GetSize(fullImageSize, i); byte[] data = new byte[currentSize]; stream.Seek(currentOffset, SeekOrigin.Begin); br.Read(data, 0, currentSize); Blp2MipMap mipmap = new Blp2MipMap(mipmapSize, i, data); m_mipmaps.Add(mipmap); } } }
private Image FromPalette(Blp2MipMap mipmap) { Bitmap bmp = new Bitmap(mipmap.Size.Width, mipmap.Size.Height, PixelFormat.Format32bppArgb); byte[] mipmapData = mipmap.Data; int[] result = new int[mipmap.Size.Width * mipmap.Size.Height]; for (int i = 0; i < result.Length; i++) { Color paletteEntry = m_palette[mipmapData[i]]; result[i] = paletteEntry.ToArgb(); } BitmapData bmpData = bmp.LockBits(new Rectangle(Point.Empty, mipmap.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(result, 0, bmpData.Scan0, result.Length); bmp.UnlockBits(bmpData); return bmp; }
private Image FromJpeg(Blp2MipMap mipmap) { byte[] result = new byte[BLP1_JPG_HEADER_SIZE + mipmap.Data.Length]; Buffer.BlockCopy(m_jpgHeader, 0, result, 0, m_jpgHeader.Length); Buffer.BlockCopy(mipmap.Data, 0, result, BLP1_JPG_HEADER_SIZE, mipmap.Data.Length); Image img; using (MemoryStream ms = new MemoryStream(result, false)) { img = Image.FromStream(ms, false, false); } return img; }
private Image FromDxt5(Blp2MipMap mipmap) { int[] data = DXTCFormat.DecodeDXT2(mipmap.Size.Width, mipmap.Size.Height, mipmap.Data); return FromBinary(mipmap.Size.Width, mipmap.Size.Height, data); }