public void Encode() { IconHeader header = new IconHeader() { reserved = 0, type = 1, count = ( ushort )entries.Count, }; WriteToStream <IconHeader> (outputStream, header); uint totalWritten = ( uint )Marshal.SizeOf <IconHeader> () + ( uint )entries.Count * ( uint )Marshal.SizeOf <EntryHeader> (); foreach (var pair in entries) { var entryHeader = pair.Value; entryHeader.fileOffset = totalWritten; WriteToStream <EntryHeader> (outputStream, entryHeader); totalWritten += ( uint )pair.Key.Length; } byte [] buffer = new byte [4194304]; foreach (var pair in entries) { var stream = pair.Key; int totalCopy = 0; while (totalCopy < stream.Length) { int read = stream.Read(buffer, 0, buffer.Length); outputStream.Write(buffer, 0, read); totalCopy += read; } } outputStream.Flush(); }
private unsafe void Parse(Stream str) { using (BinaryReader br = new BinaryReader(str)) { br.ReadUInt32(); // headerLength ushort version = br.ReadUInt16(); if (version != 1) { throw new InvalidDataException("Only version 1 of BNI files is supported."); } br.ReadUInt16(); uint numIcons = br.ReadUInt32(); br.ReadUInt32(); // dataStart List <IconHeader> icons = new List <IconHeader>(unchecked ((int)numIcons)); for (int i = 0; i < numIcons; i++) { icons.Add(new IconHeader(br)); } // now onto the TGA header byte infoLength = br.ReadByte(); br.ReadByte(); // color map type, unsupported if (br.ReadByte() != 0x0a) // run-length true-color; others unsupported { throw new InvalidDataException("Only run-length true-color TGA icons are supported."); } br.ReadBytes(5); // color map data, ignored br.ReadUInt16(); // xOrigin br.ReadUInt16(); // yOrigin ushort width = br.ReadUInt16(); ushort height = br.ReadUInt16(); byte depth = br.ReadByte(); if (depth != 24) { throw new InvalidDataException("Only 24-bit TGA is supported."); } StartDescriptor descriptor = (StartDescriptor)br.ReadByte(); byte[] info_bytes = br.ReadBytes(infoLength); Trace.WriteLine(Encoding.ASCII.GetString(info_bytes), "BNI header: information"); int numberOfPixels = width * height; using (Bitmap bmp = new Bitmap(width, height)) { BitmapData data = bmp.LockBits(new Rectangle(Point.Empty, new Size(width, height)), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); int * currentPixel = (int *)data.Scan0.ToPointer(); for (int i = 0; i < numberOfPixels;) { byte packetType = br.ReadByte(); byte packetPixelCount = (byte)((packetType & 0x7f) + 1); // number of pixels in the current pixel packet if ((packetType & 0x80) == 0x80) // check to see if MSB is set { byte nextBlue = br.ReadByte(); byte nextGreen = br.ReadByte(); byte nextRed = br.ReadByte(); Color c = Color.FromArgb(255, nextRed, nextGreen, nextBlue); for (int pixel = 0; pixel < packetPixelCount; pixel++) { *currentPixel = c.ToArgb(); currentPixel++; } } else { for (int pixel = 0; pixel < packetPixelCount; pixel++) { byte nextBlue = br.ReadByte(); byte nextGreen = br.ReadByte(); byte nextRed = br.ReadByte(); Color c = Color.FromArgb(255, nextRed, nextGreen, nextBlue); * currentPixel = c.ToArgb(); currentPixel++; } } i += packetPixelCount; } currentPixel = null; bmp.UnlockBits(data); m_fullImage = new Bitmap(width, height); if (descriptor == StartDescriptor.TopRight) { //m_fullImage.RotateFlip(RotateFlipType.RotateNoneFlipX); bmp.RotateFlip(RotateFlipType.RotateNoneFlipX); } else if (descriptor == StartDescriptor.BottomLeft) { //m_fullImage.RotateFlip(RotateFlipType.RotateNoneFlipY); bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } else if (descriptor == StartDescriptor.BottomRight) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipXY); } using (Graphics g = Graphics.FromImage(m_fullImage)) { g.DrawImage(bmp, Point.Empty); } int currentY = 0; for (int i = 0; i < numIcons; i++) { IconHeader header = icons[i]; Bitmap icon = new Bitmap(bmp, (int)width, (int)header.height); using (Graphics g = Graphics.FromImage(icon)) { Size nextIcon = new Size((int)width, (int)header.height); g.DrawImage(bmp, new Rectangle(Point.Empty, nextIcon), new Rectangle(new Point(0, currentY), nextIcon), GraphicsUnit.Pixel); } BniIcon curIcon = new BniIcon(icon, unchecked ((int)header.flagValue), header.software); m_icons.Add(curIcon); currentY += unchecked ((int)header.height); } } } }