예제 #1
0
        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();
        }
예제 #2
0
        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);
                    }
                }
            }
        }