Example #1
0
        public static IconFile FromFile(string filename)
        {
            var instance    = new IconFile();
            var fileBytes   = File.ReadAllBytes(filename);
            var pinnedBytes = GCHandle.Alloc(fileBytes, GCHandleType.Pinned);

            instance.iconDir   = (ICONDIR)Marshal.PtrToStructure(pinnedBytes.AddrOfPinnedObject(), typeof(ICONDIR));
            instance.iconEntry = new ICONDIRENTRY[instance.iconDir.Count];
            instance.iconImage = new byte[instance.iconDir.Count][];
            int offset           = Marshal.SizeOf(instance.iconDir);
            var iconDirEntryType = typeof(ICONDIRENTRY);
            int size             = Marshal.SizeOf(iconDirEntryType);

            for (int i = 0, loopTo = instance.iconDir.Count - 1; i <= loopTo; i++)
            {
                ICONDIRENTRY entry = (ICONDIRENTRY)Marshal.PtrToStructure(new IntPtr(pinnedBytes.AddrOfPinnedObject().ToInt64() + offset), iconDirEntryType);
                instance.iconEntry[i] = entry;
                instance.iconImage[i] = new byte[entry.BytesInRes];
                Buffer.BlockCopy(fileBytes, entry.ImageOffset, instance.iconImage[i], 0, entry.BytesInRes);
                offset += size;
            }

            pinnedBytes.Free();
            return(instance);
        }
Example #2
0
        public unsafe MultiIcon Load(Stream stream)
        {
            stream.Position = 0;
            SingleIcon singleIcon = new SingleIcon("Untitled");
            ICONDIR    iconDir    = new ICONDIR(stream);

            if (iconDir.idReserved != 0)
            {
                throw new InvalidMultiIconFileException();
            }

            if (iconDir.idType != 1)
            {
                throw new InvalidMultiIconFileException();
            }

            int entryOffset = sizeof(ICONDIR);

            // Add Icon Images one by one to the new entry created
            for (int i = 0; i < iconDir.idCount; i++)
            {
                stream.Seek(entryOffset, SeekOrigin.Begin);
                ICONDIRENTRY entry = new ICONDIRENTRY(stream);

                // If there is missing information in the header... lets try to calculate it
                entry = CheckAndRepairEntry(entry);

                stream.Seek(entry.dwImageOffset, SeekOrigin.Begin);

                singleIcon.Add(new IconImage(stream, (int)(stream.Length - stream.Position)));
                entryOffset += sizeof(ICONDIRENTRY);
            }

            return(new MultiIcon(singleIcon));
        }
Example #3
0
        public unsafe MultiIcon Load(Stream stream)
        {
            stream.Position = 0;
            SingleIcon singleIcon = new SingleIcon("Untitled");
            ICONDIR iconDir = new ICONDIR(stream);
            if (iconDir.idReserved != 0)
                throw new InvalidMultiIconFileException();

            if (iconDir.idType != 1)
                throw new InvalidMultiIconFileException();

            int entryOffset = sizeof(ICONDIR);

            // Add Icon Images one by one to the new entry created
            for(int i=0; i<iconDir.idCount; i++)
            {
                stream.Seek(entryOffset, SeekOrigin.Begin);
                ICONDIRENTRY entry = new ICONDIRENTRY(stream);

                // If there is missing information in the header... lets try to calculate it
                entry = CheckAndRepairEntry(entry);

                stream.Seek(entry.dwImageOffset, SeekOrigin.Begin);

                singleIcon.Add(new IconImage(stream, (int) (stream.Length - stream.Position)));
                entryOffset += sizeof(ICONDIRENTRY);
            }

            return new MultiIcon(singleIcon);
        }
Example #4
0
            internal ICONDIR(RESOURCE_ICONDIR resdir)
            {
                idReserved = resdir.idReserved;
                idType     = resdir.idType;
                idCount    = resdir.idCount;
                uint offset = (uint)Marshal.SizeOf(typeof(ICONDIR)) + (uint)((idCount - 1) * Marshal.SizeOf(typeof(ICONDIRENTRY)));

                idEntries = new ICONDIRENTRY(resdir.idEntries, offset);
            }
Example #5
0
        public void Save(System.IO.Stream Stream)
        {
            _frames.SortAscending();
            System.IO.BinaryWriter writer = new System.IO.BinaryWriter(Stream, System.Text.Encoding.UTF32);

            ushort FramesCount       = Convert.ToUInt16(_frames.Count);
            ushort FileHeaderLength  = 6;
            ushort FrameHeaderLength = 16;

            ICONDIR FileHeader = new ICONDIR(FramesCount);

            writer.Write(FileHeader.idReserved);
            writer.Write(FileHeader.idType);
            writer.Write(FileHeader.idCount);

            byte[][] data = new byte[FramesCount][];

            foreach (BitmapFrame Frame in _frames)
            {
                int FrameIndex = _frames.IndexOf(Frame);
                if (Frame.PixelWidth == 256)
                {
                    data[FrameIndex] = GetPNGData(Frame);
                }
                else
                {
                    data[FrameIndex] = GetBMPData(Frame);
                }
            }

            uint FrameDataOffset = FileHeaderLength;

            FrameDataOffset += (uint)(FrameHeaderLength * FramesCount);

            foreach (BitmapFrame Frame in _frames)
            {
                int FrameIndex = _frames.IndexOf(Frame);
                if (FrameIndex > 0)
                {
                    FrameDataOffset += Convert.ToUInt32(data[FrameIndex - 1].Length);
                }
                ICONDIRENTRY FrameHeader = new ICONDIRENTRY((ushort)Frame.PixelWidth, (ushort)Frame.PixelHeight, Convert.ToUInt16(Frame.Format.BitsPerPixel), Convert.ToUInt32(data[FrameIndex].Length), FrameDataOffset);
                writer.Write(FrameHeader.bWidth);
                writer.Write(FrameHeader.bHeight);
                writer.Write(FrameHeader.bColorCount);
                writer.Write(FrameHeader.bReserved);
                writer.Write(FrameHeader.wPlanes);
                writer.Write(FrameHeader.wBitCount);
                writer.Write(FrameHeader.dwBytesInRes);
                writer.Write(FrameHeader.dwImageOffset);
            }

            foreach (byte[] FrameData in data)
            {
                writer.Write(FrameData);
            }
        }
Example #6
0
            public short nID;          // ID

            public void CopyFrom(ICONDIRENTRY other)
            {
                this.bWidth       = other.bWidth;
                this.bHeight      = other.bHeight;
                this.bColorCount  = other.bColorCount;
                this.bReserved    = other.bReserved;
                this.wPlanes      = other.wPlanes;
                this.wBitCount    = other.wBitCount;
                this.dwBytesInRes = other.dwBytesInRes;
            }
Example #7
0
        const ushort BitCount         = 32; // (Because 32bppArgb)

        private static unsafe ICONDIRENTRY Make_ICONDIRENTRY(IconImage iconImage)
        {
            ICONDIRENTRY iconEntry = new ICONDIRENTRY();

            iconEntry.bColorCount   = NumColorsInPalette;
            iconEntry.bHeight       = (byte)iconImage.ImageSize.Height;
            iconEntry.bReserved     = 0;
            iconEntry.bWidth        = (byte)iconImage.ImageSize.Width;
            iconEntry.dwBytesInRes  = (uint)(sizeof(BITMAPINFOHEADER) + iconImage.XOR.Length /* + this.AND.Length*/);
            iconEntry.dwImageOffset = (uint)(sizeof(ICONDIR) + sizeof(ICONDIRENTRY));
            iconEntry.wBitCount     = BitCount;
            iconEntry.wPlanes       = NumPlanes;
            return(iconEntry);
        }
Example #8
0
        public unsafe void Save(MultiIcon multiIcon, Stream stream)
        {
            if (multiIcon.SelectedIndex == -1)
            {
                return;
            }

            SingleIcon singleIcon = multiIcon[multiIcon.SelectedIndex];

            // ICONDIR header
            ICONDIR iconDir = ICONDIR.Initalizated;

            iconDir.idCount = (ushort)singleIcon.Count;
            iconDir.Write(stream);

            // ICONENTRIES
            int entryPos  = sizeof(ICONDIR);
            int imagesPos = sizeof(ICONDIR) + iconDir.idCount * sizeof(ICONDIRENTRY);

            foreach (IconImage iconImage in singleIcon)
            {
                // for some formats We don't know the size until we write,
                // so we have to write first the image then later the header

                // IconImage
                stream.Seek(imagesPos, SeekOrigin.Begin);
                iconImage.Write(stream);
                long bytesInRes = stream.Position - imagesPos;

                // IconDirHeader
                stream.Seek(entryPos, SeekOrigin.Begin);
                ICONDIRENTRY iconEntry = iconImage.ICONDIRENTRY;
                stream.Seek(entryPos, SeekOrigin.Begin);
                iconEntry.dwImageOffset = (uint)imagesPos;
                iconEntry.dwBytesInRes  = (uint)bytesInRes;
                iconEntry.Write(stream);

                entryPos  += sizeof(ICONDIRENTRY);
                imagesPos += (int)bytesInRes;
            }
        }
Example #9
0
        public unsafe void Save(Stream stream)
        {
            ICONDIR iconDir = ICONDIR.Initalizated;

            iconDir.idCount = (ushort)this.IconImages.Count;
            iconDir.Write(stream);

            int entryPos = sizeof(ICONDIR);
            // Placeholder for an array if ICONDIRENTRY here
            int imagesPos = entryPos + iconDir.idCount * sizeof(ICONDIRENTRY);

            foreach (IconImage iconImage in this.IconImages)
            {
                // IconImage
                stream.Seek(imagesPos, SeekOrigin.Begin);
                // Header
                BITMAPINFOHEADER header = Make_BITMAPINFOHEADER(iconImage);
                header.Write(stream);

                // Palette - (none)

                // XOR Image
                stream.Write(iconImage.XOR, 0, iconImage.XOR.Length);

                // AND Image - (not needed)


                long bytesInRes = stream.Position - imagesPos;

                // IconDirHeader
                stream.Seek(entryPos, SeekOrigin.Begin);
                ICONDIRENTRY iconEntry = Make_ICONDIRENTRY(iconImage);
                stream.Seek(entryPos, SeekOrigin.Begin);
                iconEntry.dwImageOffset = (uint)imagesPos;
                iconEntry.dwBytesInRes  = (uint)bytesInRes;
                iconEntry.Write(stream);

                entryPos  += sizeof(ICONDIRENTRY);
                imagesPos += (int)bytesInRes;
            }
        }
Example #10
0
        private static unsafe ICONDIRENTRY CheckAndRepairEntry(ICONDIRENTRY entry)
        {
            // If there is missing information in the header... lets try to calculate it
            if (entry.wBitCount == 0)
            {
                int stride, CLSSize, palette;
                int bmpSize  = ((ushort)entry.dwBytesInRes - sizeof(BITMAPINFOHEADER));
                int BWStride = ((entry.bWidth * 1 + 31) & ~31) >> 3;
                int BWSize   = BWStride * entry.bHeight;
                bmpSize -= BWSize;

                // Lets find the value;
                byte[] bpp = { 1, 4, 8, 16, 24, 32 };
                int    j   = 0;
                while (j <= 5)
                {
                    stride  = ((entry.bWidth * bpp[j] + 31) & ~31) >> 3;
                    CLSSize = entry.bHeight * stride;
                    palette = bpp[j] <= 8 ? ((int)(1 << bpp[j]) * 4) : 0;
                    if (palette + CLSSize == bmpSize)
                    {
                        entry.wBitCount = bpp[j];
                        break;
                    }
                    j++;
                }
            }

            if (entry.wBitCount < 8 && entry.bColorCount == 0)
            {
                entry.bColorCount = (byte)(1 << entry.wBitCount);
            }
            if (entry.wPlanes == 0)
            {
                entry.wPlanes = 1;
            }

            return(entry);
        }
Example #11
0
        // Layout: ICONDIR, ICONDIRENTRY[], PngData[]
        static void WriteIcoFile(string fileName,
                                 IEnumerable <Bitmap> smallerBmps,
                                 Bitmap big256PxSource)
        {
            var dir = new ICONDIR
            {
                reserved  = 0,
                imageType = 1,
                numImages = (UInt16)(1 + smallerBmps.Count())
            };

            var entries = new ICONDIRENTRY[dir.numImages];

            var pngsToWrite = new Queue <MemoryStream>();

            // Smaller entries go first
            var i      = 0;
            var offset = Marshal.SizeOf(dir) +
                         (Marshal.SizeOf(entries[0]) * entries.Length);

            foreach (var img in smallerBmps)
            {
                entries[i].imageWidth   = (byte)img.Size.Width;
                entries[i].imageHeight  = (byte)img.Size.Height;
                entries[i].numColors    = 0;
                entries[i].reserved     = 0;
                entries[i].colorPlanes  = 0;
                entries[i].bitsPerPixel = 32;

                var stream = new MemoryStream();
                img.Save(stream, ImageFormat.Png);
                pngsToWrite.Enqueue(stream);

                entries[i].imageDataSize   = (UInt32)stream.Length;
                entries[i].imageDataOffset = (UInt32)offset;

                Debug.WriteLine($"Storing {img.Size.Width}x{img.Size.Height} image with size {stream.Length} at offset {offset}");

                offset += (int)stream.Length;
                i++;
            }

            // 256x256 goes last
            entries[i].imageWidth   = (byte)big256PxSource.Size.Width;
            entries[i].imageHeight  = (byte)big256PxSource.Size.Height;
            entries[i].numColors    = 0;
            entries[i].reserved     = 0;
            entries[i].colorPlanes  = 0;
            entries[i].bitsPerPixel = 32;

            var bigImageStream = new MemoryStream();

            big256PxSource.Save(bigImageStream, ImageFormat.Png);
            pngsToWrite.Enqueue(bigImageStream);

            entries[i].imageDataSize   = (UInt32)bigImageStream.Length;
            entries[i].imageDataOffset = (UInt32)offset;

            Debug.WriteLine($"Storing {big256PxSource.Size.Width}x{big256PxSource.Size.Height} image with size {bigImageStream.Length} at offset {offset}");

            offset = 0;
            // Write all of the data out to the ICO file
            using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                var header = GetBytesForStruct(dir);
                fileStream.Write(header, 0, header.Length);

                Debug.WriteLine($"Wrote header ({header.Length} bytes, offset = {offset})");
                offset += header.Length;

                i = 0;
                foreach (var entry in entries)
                {
                    var entryBytes = GetBytesForStruct(entry);
                    fileStream.Write(entryBytes, 0, entryBytes.Length);

                    Debug.WriteLine($"Wrote directory entry {i++} ({entryBytes.Length} bytes, offset = {offset})");
                    offset += entryBytes.Length;
                }
                while (pngsToWrite.Count > 0)
                {
                    var pngStream = pngsToWrite.Dequeue();
                    pngStream.Position = 0;
                    pngStream.CopyTo(fileStream);
                    Debug.WriteLine($"Wrote PNG ({pngStream.Length} bytes, offset = {offset})");
                    offset += (int)pngStream.Length;
                }
            }
        }
Example #12
0
        internal static void AppendIconToResourceStream(Stream resStream, Stream iconStream)
        {
            var iconReader = new BinaryReader(iconStream);

            //read magic reserved WORD
            var reserved = iconReader.ReadUInt16();

            if (reserved != 0)
            {
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);
            }

            var type = iconReader.ReadUInt16();

            if (type != 1)
            {
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);
            }

            var count = iconReader.ReadUInt16();

            if (count == 0)
            {
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);
            }

            var iconDirEntries = new ICONDIRENTRY[count];

            for (ushort i = 0; i < count; i++)
            {
                // Read the Icon header
                iconDirEntries[i].bWidth        = iconReader.ReadByte();
                iconDirEntries[i].bHeight       = iconReader.ReadByte();
                iconDirEntries[i].bColorCount   = iconReader.ReadByte();
                iconDirEntries[i].bReserved     = iconReader.ReadByte();
                iconDirEntries[i].wPlanes       = iconReader.ReadUInt16();
                iconDirEntries[i].wBitCount     = iconReader.ReadUInt16();
                iconDirEntries[i].dwBytesInRes  = iconReader.ReadUInt32();
                iconDirEntries[i].dwImageOffset = iconReader.ReadUInt32();
            }

            // Because Icon files don't seem to record the actual w and BitCount in
            // the ICONDIRENTRY, get the info from the BITMAPINFOHEADER at the beginning
            // of the data here:
            //EDMAURER: PNG compressed icons must be treated differently. Do what has always
            //been done for uncompressed icons. Assume modern, compressed icons set the
            //ICONDIRENTRY fields correctly.
            //if (*(DWORD*)icoBuffer == sizeof(BITMAPINFOHEADER))
            //{
            //    grp[i].Planes = ((BITMAPINFOHEADER*)icoBuffer)->biPlanes;
            //    grp[i].BitCount = ((BITMAPINFOHEADER*)icoBuffer)->biBitCount;
            //}

            for (ushort i = 0; i < count; i++)
            {
                iconStream.Position = iconDirEntries[i].dwImageOffset;
                if (iconReader.ReadUInt32() == 40)
                {
                    iconStream.Position        += 8;
                    iconDirEntries[i].wPlanes   = iconReader.ReadUInt16();
                    iconDirEntries[i].wBitCount = iconReader.ReadUInt16();
                }
            }

            //read everything and no exceptions. time to write.
            var resWriter = new BinaryWriter(resStream);

            //write all of the icon images as individual resources, then follow up with
            //a resource that groups them.
            const WORD RT_ICON = 3;

            for (ushort i = 0; i < count; i++)
            {
                /* write resource header.
                 * struct RESOURCEHEADER
                 * {
                 *  DWORD DataSize;
                 *  DWORD HeaderSize;
                 *  WORD Magic1;
                 *  WORD Type;
                 *  WORD Magic2;
                 *  WORD Name;
                 *  DWORD DataVersion;
                 *  WORD MemoryFlags;
                 *  WORD LanguageId;
                 *  DWORD Version;
                 *  DWORD Characteristics;
                 * };
                 */

                resStream.Position = (resStream.Position + 3) & ~3; //headers begin on 4-byte boundaries.
                resWriter.Write((DWORD)iconDirEntries[i].dwBytesInRes);
                resWriter.Write((DWORD)0x00000020);
                resWriter.Write((WORD)0xFFFF);
                resWriter.Write((WORD)RT_ICON);
                resWriter.Write((WORD)0xFFFF);
                resWriter.Write((WORD)(i + 1));       //EDMAURER this is not general. Implies you can only append one icon to the resources.
                                                      //This icon ID would seem to be global among all of the icons not just this group.
                                                      //Zero appears to not be an acceptable ID. Note that this ID is referred to below.
                resWriter.Write((DWORD)0x00000000);
                resWriter.Write((WORD)0x1010);
                resWriter.Write((WORD)0x0000);
                resWriter.Write((DWORD)0x00000000);
                resWriter.Write((DWORD)0x00000000);

                //write the data.
                iconStream.Position = iconDirEntries[i].dwImageOffset;
                resWriter.Write(iconReader.ReadBytes(checked ((int)iconDirEntries[i].dwBytesInRes)));
            }

            /*
             *
             * struct ICONDIR
             * {
             *  WORD           idReserved;   // Reserved (must be 0)
             *  WORD           idType;       // Resource Type (1 for icons)
             *  WORD           idCount;      // How many images?
             *  ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
             * }/
             *
             * struct ICONRESDIR
             * {
             *  BYTE Width;        // = ICONDIRENTRY.bWidth;
             *  BYTE Height;       // = ICONDIRENTRY.bHeight;
             *  BYTE ColorCount;   // = ICONDIRENTRY.bColorCount;
             *  BYTE reserved;     // = ICONDIRENTRY.bReserved;
             *  WORD Planes;       // = ICONDIRENTRY.wPlanes;
             *  WORD BitCount;     // = ICONDIRENTRY.wBitCount;
             *  DWORD BytesInRes;   // = ICONDIRENTRY.dwBytesInRes;
             *  WORD IconId;       // = RESOURCEHEADER.Name
             * };
             */

            const WORD RT_GROUP_ICON = RT_ICON + 11;

            resStream.Position = (resStream.Position + 3) & ~3; //align 4-byte boundary
            //write the icon group. first a RESOURCEHEADER. the data is the ICONDIR
            resWriter.Write((DWORD)(3 * sizeof(WORD) + count * /*sizeof(ICONRESDIR)*/ 14));
            resWriter.Write((DWORD)0x00000020);
            resWriter.Write((WORD)0xFFFF);
            resWriter.Write((WORD)RT_GROUP_ICON);
            resWriter.Write((WORD)0xFFFF);
            resWriter.Write((WORD)0x7F00);  //IDI_APPLICATION
            resWriter.Write((DWORD)0x00000000);
            resWriter.Write((WORD)0x1030);
            resWriter.Write((WORD)0x0000);
            resWriter.Write((DWORD)0x00000000);
            resWriter.Write((DWORD)0x00000000);

            //the ICONDIR
            resWriter.Write((WORD)0x0000);
            resWriter.Write((WORD)0x0001);
            resWriter.Write((WORD)count);

            for (ushort i = 0; i < count; i++)
            {
                resWriter.Write((BYTE)iconDirEntries[i].bWidth);
                resWriter.Write((BYTE)iconDirEntries[i].bHeight);
                resWriter.Write((BYTE)iconDirEntries[i].bColorCount);
                resWriter.Write((BYTE)iconDirEntries[i].bReserved);
                resWriter.Write((WORD)iconDirEntries[i].wPlanes);
                resWriter.Write((WORD)iconDirEntries[i].wBitCount);
                resWriter.Write((DWORD)iconDirEntries[i].dwBytesInRes);
                resWriter.Write((WORD)(i + 1));   //ID
            }
        }
Example #13
0
        private static unsafe ICONDIRENTRY CheckAndRepairEntry(ICONDIRENTRY entry)
        {
            // If there is missing information in the header... lets try to calculate it
            if (entry.wBitCount == 0)
            {
                int stride, CLSSize, palette;
                int bmpSize  = ((ushort) entry.dwBytesInRes - sizeof(BITMAPINFOHEADER));
                int BWStride = ((entry.bWidth * 1 + 31) & ~31) >> 3;
                int BWSize   = BWStride * entry.bHeight;
                bmpSize     -= BWSize;

                // Lets find the value;
                byte[] bpp = {1, 4, 8, 16, 24, 32};
                int j=0;
                while(j<=5)
                {
                    stride   = ((entry.bWidth * bpp[j] + 31) & ~31) >> 3;
                    CLSSize  = entry.bHeight * stride ;
                    palette  = bpp[j]<=8 ? ((int) (1 << bpp[j]) * 4) : 0;
                    if (palette + CLSSize == bmpSize)
                    {
                        entry.wBitCount = bpp[j];
                        break;
                    }
                    j++;
                }
            }

            if (entry.wBitCount < 8 && entry.bColorCount == 0)
                entry.bColorCount = (byte) (1 << entry.wBitCount);
            if (entry.wPlanes == 0)
                entry.wPlanes = 1;

            return entry;
        }
Example #14
0
 private void loadFromFile(string iconFile)
 {
     this.loadInitialise();
     FileStream input = new FileStream(iconFile, FileMode.Open, FileAccess.Read, FileShare.Read);
     BinaryReader br = new BinaryReader(input);
     try
     {
         int num = this.readIconFileHeader(br);
         ICONDIRENTRY[] icondirentryArray = new ICONDIRENTRY[num];
         for (int i = 0; i < num; i++)
         {
             icondirentryArray[i] = new ICONDIRENTRY(br);
         }
         IcDvImg[] icons = new IcDvImg[num];
         for (int j = 0; j < num; j++)
         {
             input.Seek((long)icondirentryArray[j].dwImageOffset, SeekOrigin.Begin);
             byte[] buffer = new byte[icondirentryArray[j].dwBytesInRes];
             br.Read(buffer, 0, icondirentryArray[j].dwBytesInRes);
             icons[j] = new IcDvImg(buffer);
         }
         this.iconCollection = new IconDeviceImageCollection(icons);
     }
     catch (Exception exception)
     {
         if (exception is SystemException)
         {
             throw exception;
         }
         throw new IconExException("Failed to read icon file.", exception);
     }
     finally
     {
         br.Close();
     }
     this.iconFile = iconFile;
 }
Example #15
0
        public void Save(string iconFile)
        {
            FileStream output = new FileStream(iconFile, FileMode.Create, FileAccess.Write, FileShare.Read);
            BinaryWriter bw = null;
            try
            {
                bw = new BinaryWriter(output);
                this.writeIconFileHeader(bw);
                int num = 6 + (0x10 * this.iconCollection.Count);
                foreach (IcDvImg image in this.iconCollection)
                {
                    int num2 = image.IconImageDataBytes();
                    ICONDIRENTRY icondirentry = new ICONDIRENTRY();
                    icondirentry.width = (byte)image.IconSize.Width;
                    icondirentry.height = (byte)image.IconSize.Height;
                    switch (image.ColorDepth)
                    {
                        case ColorDepth.Depth16Bit:
                            icondirentry.colorCount = 0;
                            icondirentry.wBitCount = 0x10;
                            break;

                        case ColorDepth.Depth24Bit:
                            icondirentry.colorCount = 0;
                            icondirentry.wBitCount = 0x18;
                            break;

                        case ColorDepth.Depth32Bit:
                            icondirentry.colorCount = 0;
                            icondirentry.wBitCount = 0x20;
                            break;

                        case ColorDepth.Depth4Bit:
                            icondirentry.colorCount = 0x10;
                            icondirentry.wBitCount = 4;
                            break;

                        case ColorDepth.Depth8Bit:
                            icondirentry.colorCount = 0xff;
                            icondirentry.wBitCount = 8;
                            break;
                    }
                    icondirentry.wPlanes = 1;
                    icondirentry.dwBytesInRes = num2;
                    icondirentry.dwImageOffset = num;
                    icondirentry.Write(bw);
                    num += num2;
                }
                foreach (IcDvImg image2 in this.iconCollection)
                {
                    image2.SaveIconBitmapData(bw);
                }
            }
            catch (Exception exception)
            {
                if (exception is SystemException)
                {
                    throw exception;
                }
                throw new IconExException(exception.Message, exception);
            }
            finally
            {
                if (bw != null)
                {
                    bw.Close();
                }
            }
        }
Example #16
0
    internal static string makeIconEx(string icon, int size, int depth, string icoFormat)
    {
        // Header of the whole file, the file may contain more than one Icon

        byte[] bytes           = System.Convert.FromBase64String(icon);
        int    colorsInPalette = depth > 8 ? 0 : 1 << depth;

        ICONDIR          iconDir      = ICONDIR.Initalizated;
        ICONDIRENTRY     iconEntry    = new ICONDIRENTRY();
        BITMAPINFOHEADER bitMapHeader = new BITMAPINFOHEADER();

        iconEntry.bWidth        = (byte)size;
        iconEntry.bHeight       = (byte)size;
        iconEntry.bColorCount   = (byte)colorsInPalette; // 4 = 16 colors, 8 = 256
        iconEntry.wBitCount     = (ushort)depth;
        iconEntry.bReserved     = 0;
        iconEntry.dwBytesInRes  = (uint)(bytes.Length + Marshal.SizeOf(bitMapHeader) + colorsInPalette * 4); // Each color requires 4 bytes in the palette
        iconEntry.dwImageOffset = (uint)(Marshal.SizeOf(iconDir) + Marshal.SizeOf(iconEntry));
        iconEntry.wPlanes       = 1;

        bitMapHeader.biSize          = (uint)Marshal.SizeOf(bitMapHeader);
        bitMapHeader.biWidth         = (uint)size;
        bitMapHeader.biHeight        = (uint)size * 2;
        bitMapHeader.biBitCount      = (ushort)depth;
        bitMapHeader.biPlanes        = 1;
        bitMapHeader.biCompression   = IconImageFormat.BMP;
        bitMapHeader.biXPelsPerMeter = 0;
        bitMapHeader.biYPelsPerMeter = 0;
        bitMapHeader.biClrUsed       = (uint)colorsInPalette;
        bitMapHeader.biClrImportant  = 0;
        bitMapHeader.biSizeImage     = (uint)bytes.Length;

        //
        // The icon is recieved flipped vertically, we need first to flip it before sending
        // it to the consumer
        //
        byte[] data = null;
        int    len = 0, revIndex = 0, rowWidth = 0, ANDmapSize;

        len        = bytes.Length;
        data       = new byte[bytes.Length];
        rowWidth   = size * depth / 8;
        ANDmapSize = len - size * size * depth / 8;
        int step = 4;

        for (int k = len - rowWidth; k >= ANDmapSize; k -= rowWidth)
        {
            for (int r = 0; r < rowWidth; r++, revIndex++)
            {
                data[revIndex] = bytes[k + r];
            }
        }

        for (int l = 0, m = ANDmapSize - step; l < ANDmapSize; l += step, m -= step)
        {
            for (int n = 0; n < step; n++, revIndex++)
            {
                data[revIndex] = bytes[m + n];
            }
        }

        MemoryStream mStream = new MemoryStream();

        //
        // Write the Icon directory
        //
        iconDir.Write(mStream);

        //
        // Write the icon directory entry
        //
        iconEntry.Write(mStream);

        //
        // Write the bitmap header
        //
        bitMapHeader.Write(mStream);

        //
        // Write the appropriate palette if required
        //
        if (depth == 4)
        {
            mStream.Write(palette_16, 0, palette_16.Length);
        }

        //
        // Write the icon data recieved from the CPS server
        //
        mStream.Write(data, 0, data.Length);

        byte[] outBytes;

        //
        // If the consumer requested an ico format return the stream as is without any conversion
        //
        if (icoFormat.ToLower() == "ico")
        {
            outBytes = mStream.GetBuffer();
            mStream.Dispose();
            return(Convert.ToBase64String(outBytes));
        }

        //
        // Store the stream in an Icon object, this will solve the transparency problem
        //
        mStream.Position = 0;
        Icon iconStream = new Icon(mStream, depth, depth);

        //
        // Retrieve the icon as bitmap for conversion
        //
        Bitmap      bitMap    = iconStream.ToBitmap();
        ImageFormat imgFormat = ImageFormat.Png;

        switch (icoFormat.ToLower())
        {
        case "png":
            imgFormat = ImageFormat.Png;
            break;

        case "gif":
            imgFormat = ImageFormat.Gif;
            break;

        case "tiff":
            imgFormat = ImageFormat.Tiff;
            break;
        }

        //
        // Save the icon in the requested format to an icon to be sent to the consumer
        //
        MemoryStream oMStream = new MemoryStream();

        bitMap.Save(oMStream, imgFormat);
        outBytes = oMStream.GetBuffer();
        mStream.Dispose();
        oMStream.Close();
        oMStream.Dispose();
        bitMap.Dispose();

        //
        // Return the icon as base64 string
        //
        return(Convert.ToBase64String(outBytes));
    }
Example #17
0
        private static Icon LoadIconFromResource(UIntPtr lpIconName)
        {
            HandleRef hmodule = new HandleRef(null, GetModuleHandle(null));

            uint totalsize;

            RESOURCE_ICONDIRENTRY[] entries;
            SafeResourceBuffer[]    entrybuffers;
            RESOURCE_ICONDIR        dir;

            using (SafeResourceBuffer buffer = GetResourceBuffer(hmodule, lpIconName, MAKEINTRESOURCE(RT_GROUP_ICON)))
            {
                dir = buffer.Read <RESOURCE_ICONDIR>(0);
                if (dir.idReserved != 0 || dir.idType != IMAGE_ICON || dir.idCount == 0)
                {
                    throw new InvalidDataException("There is no icon directory in resource data.");
                }

                entries      = new RESOURCE_ICONDIRENTRY[dir.idCount];
                entrybuffers = new SafeResourceBuffer[dir.idCount];
                uint  entrysize = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIRENTRY));
                ulong offset    = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIR)) - entrysize;
                totalsize = (uint)(Marshal.SizeOf(typeof(ICONDIR)) + (Marshal.SizeOf(typeof(ICONDIRENTRY)) * (dir.idCount - 1)));

                entries[0] = dir.idEntries;
                for (int i = 0; i < dir.idCount; i++, offset += entrysize)
                {
                    if (i > 0)
                    {
                        entries[i] = buffer.Read <RESOURCE_ICONDIRENTRY>(offset);
                    }

                    uint iconsize = entries[i].dwBytesInRes;
                    SafeResourceBuffer entrybuffer = GetResourceBuffer(hmodule, MAKEINTRESOURCE(entries[i].nID), MAKEINTRESOURCE(RT_ICON));
                    if (iconsize != entrybuffer.ByteLength)
                    {
                        throw new InvalidDataException("Reported resource size is not equal to the icon size.");
                    }

                    entrybuffers[i] = entrybuffer;
                    totalsize      += iconsize;
                }
            }

            using (SafeLocalAllocHandle iconbuffer = SafeLocalAlloc(LMEM_ZEROINIT | LMEM_FIXED, totalsize))
            {
                using (UnmanagedMemoryStream outstream = iconbuffer.ToStream(FileAccess.ReadWrite))
                {
                    ICONDIR icondir = new ICONDIR(dir);
                    iconbuffer.Write(0, icondir);

                    uint iconoffset = icondir.idEntries.dwImageOffset;
                    outstream.Position = iconoffset;
                    uint         entrysize = (uint)Marshal.SizeOf(typeof(ICONDIRENTRY));
                    ulong        offset    = (uint)Marshal.SizeOf(typeof(ICONDIR));
                    ICONDIRENTRY entry     = icondir.idEntries;
                    for (int i = 0; i < dir.idCount; i++, offset += entrysize)
                    {
                        if (i > 0)
                        {
                            entry = new ICONDIRENTRY(entries[i], iconoffset);
                            iconbuffer.Write(offset, entry);
                        }

                        using (UnmanagedMemoryStream instream = entrybuffers[i].ToStream())
                        {
                            instream.CopyTo(outstream);
                        }

                        if (outstream.Position != (iconoffset + entry.dwBytesInRes))
                        {
                            throw new InvalidOperationException();
                        }

                        iconoffset += entry.dwBytesInRes;
                    }

                    outstream.Position = 0;
                    return(new Icon(outstream));
                }
            }
        }
      private void loadFromFile(
         string iconFile)
      {
         loadInitialise();

         // Open the file
         FileStream fs = new FileStream(
            iconFile,
            FileMode.Open,
            FileAccess.Read,
            FileShare.Read);
         BinaryReader br = new BinaryReader(fs);

         try
         {
            // read the header:
            int iconCount = readIconFileHeader(br);
            // read the directory:
            ICONDIRENTRY[] ide = new ICONDIRENTRY[iconCount];
            for (int iconEntry = 0; iconEntry < iconCount; iconEntry++)
            {
               ide[iconEntry] = new ICONDIRENTRY(br);
            }
            IconDeviceImage[] icons = new IconDeviceImage[iconCount];
            // read the actual icons:
            for (int iconEntry = 0; iconEntry < iconCount; iconEntry++)
            {
               fs.Seek(ide[iconEntry].dwImageOffset, SeekOrigin.Begin);
               byte[] b = new byte[ide[iconEntry].dwBytesInRes];
               br.Read(b, 0, ide[iconEntry].dwBytesInRes);
               icons[iconEntry] = new IconDeviceImage(b);
            }
            // Add the icons to the collection:
            this.iconCollection = new IconDeviceImageCollection(icons);
         }
         catch (Exception ex)
         {
            if (ex is SystemException)
            {
               throw ex;
            }
            else
            {
               throw new IconExException("Failed to read icon file.", ex);   
            }
         }
         finally
         {
            br.Close();            
         }

         this.iconFile = iconFile;
      }
      /// <summary>
      /// Saves the icon to the specified file
      /// </summary>
      /// <param name="iconFile">File to save to</param>
      public void Save(
         string iconFile
         )
      {
         // open the file for writing, truncate if exists
         FileStream fs = new FileStream(
            iconFile, 
            FileMode.Create,
            FileAccess.Write,
            FileShare.Read);
         BinaryWriter bw = null;
         try
         {
            bw = new BinaryWriter(fs);

            // write out the icon header:
            writeIconFileHeader(bw);
            // write out the icon directory entries:
            int iconOffset = 6 + 16 * this.iconCollection.Count;
            foreach (IconDeviceImage idi in this.iconCollection)
            {
               int bytesInRes = idi.IconImageDataBytes();

               ICONDIRENTRY ide = new ICONDIRENTRY();
               ide.width = (byte)idi.IconSize.Width;
               ide.height = (byte)idi.IconSize.Height;
               switch (idi.ColorDepth)
               {
                  case ColorDepth.Depth4Bit:
                     ide.colorCount = 16;
                     ide.wBitCount = 4;
                     break;
                  case ColorDepth.Depth8Bit:
                     ide.colorCount = 0; //BUG CORRECTED, vasian, old was 255, based on http://www.daubnet.com/formats/ICO.html
                     ide.wBitCount = 8;
                     break;
                  case ColorDepth.Depth16Bit:
                     ide.colorCount = 0;
                     ide.wBitCount = 16;
                     break;
                  case ColorDepth.Depth24Bit:
                     ide.colorCount = 0;
                     ide.wBitCount = 24;
                     break;
                  case ColorDepth.Depth32Bit:
                     ide.colorCount = 0;
                     ide.wBitCount = 32;
                     break;
               }
               ide.wPlanes = 1;
               ide.dwBytesInRes = bytesInRes;
               ide.dwImageOffset = iconOffset;
               ide.Write(bw);
               iconOffset += bytesInRes;
            }

            // write out the icon data:
            foreach (IconDeviceImage idi in this.iconCollection)
            {
               idi.SaveIconBitmapData(bw);
            }
         }
         catch (Exception ex)
         {
            if (ex is SystemException)
            {
               throw ex;
            }
            else
            {
               throw new IconExException(ex.Message, ex);
            }
         }
         finally
         {
            if (bw != null)
            {
               bw.Close();
            }
         }

      }
 public ICONDIR(ICONDIRENTRY[] entries) {
   this.Reserved = 0;
   this.Type = 1;
   this.Count = (ushort)entries.Length;
   this.Entries = entries;
 }
Example #21
0
        /// <summary>
        /// Convert this IconEx to Icon
        /// </summary>
        /// <returns>icon</returns>
        public Icon GetIcon()
        {
            Icon icon = null;

            try
            {
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);

                // write out the icon header:
                writeIconFileHeader(bw);

                // write out the icon directory entries:
                int iconOffset = 6 + 16 * this.iconCollection.Count;
                foreach (IconDeviceImage idi in this.iconCollection)
                {
                    int bytesInRes = idi.IconImageDataBytes();

                    ICONDIRENTRY ide = new ICONDIRENTRY();
                    ide.width = (byte)idi.IconSize.Width;
                    ide.height = (byte)idi.IconSize.Height;
                    switch (idi.ColorDepth)
                    {
                        case ColorDepth.Depth4Bit:
                            ide.colorCount = 16;
                            ide.wBitCount = 4;
                            break;
                        case ColorDepth.Depth8Bit:
                            ide.colorCount = 255;
                            ide.wBitCount = 8;
                            break;
                        case ColorDepth.Depth16Bit:
                            ide.colorCount = 0;
                            ide.wBitCount = 16;
                            break;
                        case ColorDepth.Depth24Bit:
                            ide.colorCount = 0;
                            ide.wBitCount = 24;
                            break;
                        case ColorDepth.Depth32Bit:
                            ide.colorCount = 0;
                            ide.wBitCount = 32;
                            break;
                    }
                    ide.wPlanes = 1;
                    ide.dwBytesInRes = bytesInRes;
                    ide.dwImageOffset = iconOffset;
                    ide.Write(bw);

                    iconOffset += bytesInRes;
                }

                // write out the icon data:
                foreach (IconDeviceImage idi in this.iconCollection)
                {
                    idi.SaveIconBitmapData(bw);
                }

                ms.Position = 0;
                icon = new Icon(ms);
            }
            catch (Exception ex)
            {
                if (ex is SystemException)
                {
                    throw ex;
                }
                else
                {
                    throw new IconExException(ex.Message, ex);
                }
            }

            return icon;
        }
Example #22
0
        public static void ChangeIcon(string exeFilePath, string icoFilePath)
        {
            int len = Marshal.SizeOf(typeof(GRPICONDIR));

            using (FileStream fs = new FileStream(icoFilePath, FileMode.Open, FileAccess.Read))
            {
                // 读取图标目录
                ICONDIR iconDir = fs.Read <ICONDIR>();
                // 读取图标头列表
                List <ICONDIRENTRY> iconDirEntrys = new List <ICONDIRENTRY>();
                for (int i = 0; i < iconDir.idCount; i++)
                {
                    ICONDIRENTRY iconDirEntry = fs.Read <ICONDIRENTRY>();
                    iconDirEntrys.Add(iconDirEntry);
                }
                // 读取图标数据列表
                List <byte[]> iconDatas = new List <byte[]>();
                for (int i = 0; i < iconDir.idCount; i++)
                {
                    byte[] iconData = new byte[iconDirEntrys[i].dwBytesInRes];
                    fs.Seek(iconDirEntrys[i].dwImageOffset, SeekOrigin.Begin);
                    fs.Read(iconData, 0, iconData.Length);
                    iconDatas.Add(iconData);
                }

                // 生成GRPICONDIR
                GRPICONDIR grpIconDir = new GRPICONDIR();
                grpIconDir.idCount    = iconDir.idCount;
                grpIconDir.idReserved = 0;
                grpIconDir.idType     = 1; // 1代表图标

                // 生成List<GRPICONDIRENTRY>
                List <GRPICONDIRENTRY> grpIconDirEntrys = new List <GRPICONDIRENTRY>();
                for (int i = 0; i < iconDirEntrys.Count; i++)
                {
                    GRPICONDIRENTRY grpIconDirEntry = new GRPICONDIRENTRY();
                    grpIconDirEntry.CopyFrom(iconDirEntrys[i]);
                    grpIconDirEntry.nID = (short)(i + 1);
                    grpIconDirEntrys.Add(grpIconDirEntry);
                }
                List <byte> grpData = new List <byte>();
                grpData.AddRange(grpIconDir.ToByteArray());
                for (int i = 0; i < grpIconDirEntrys.Count; i++)
                {
                    grpData.AddRange(grpIconDirEntrys[i].ToByteArray());
                }
                IntPtr grpDataPtr = grpData.ToArray().ToPtr();

                bool   ret        = false;
                IntPtr pUpdateRes = BeginUpdateResource(exeFilePath, false);
                for (int i = 0; i < grpIconDirEntrys.Count; i++)
                {
                    // 更新图标数据
                    int id = grpIconDirEntrys[i].nID;
                    ret = UpdateResource(pUpdateRes, new IntPtr((int)eResourceTypes.RT_ICON), new IntPtr(id), 0, iconDatas[i].ToPtr(), iconDatas[i].Length);
                }
                // 更新图标目录和图标头
                // 32512为当前exe中Icon Group下id号
                ret = UpdateResource(pUpdateRes, new IntPtr((int)eResourceTypes.RT_GROUP_ICON), new IntPtr(32512), 0, grpDataPtr, grpData.Count);
                ret = EndUpdateResource(pUpdateRes, false);
            }
        }
Example #23
0
        internal static void AppendIconToResourceStream(Stream resStream, Stream iconStream)
        {
            var iconReader = new BinaryReader(iconStream);

            //read magic reserved WORD
            var reserved = iconReader.ReadUInt16();
            if (reserved != 0)
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);

            var type = iconReader.ReadUInt16();
            if (type != 1)
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);

            var count = iconReader.ReadUInt16();
            if (count == 0)
                throw new ResourceException(CodeAnalysisResources.IconStreamUnexpectedFormat);

            var iconDirEntries = new ICONDIRENTRY[count];
            for (ushort i = 0; i < count; i++)
            {
                // Read the Icon header
                iconDirEntries[i].bWidth = iconReader.ReadByte();
                iconDirEntries[i].bHeight = iconReader.ReadByte();
                iconDirEntries[i].bColorCount = iconReader.ReadByte();
                iconDirEntries[i].bReserved = iconReader.ReadByte();
                iconDirEntries[i].wPlanes = iconReader.ReadUInt16();
                iconDirEntries[i].wBitCount = iconReader.ReadUInt16();
                iconDirEntries[i].dwBytesInRes = iconReader.ReadUInt32();
                iconDirEntries[i].dwImageOffset = iconReader.ReadUInt32();
            }

            // Because Icon files don't seem to record the actual w and BitCount in
            // the ICONDIRENTRY, get the info from the BITMAPINFOHEADER at the beginning
            // of the data here:
            //EDMAURER: PNG compressed icons must be treated differently. Do what has always
            //been done for uncompressed icons. Assume modern, compressed icons set the 
            //ICONDIRENTRY fields correctly.
            //if (*(DWORD*)icoBuffer == sizeof(BITMAPINFOHEADER))
            //{
            //    grp[i].Planes = ((BITMAPINFOHEADER*)icoBuffer)->biPlanes;
            //    grp[i].BitCount = ((BITMAPINFOHEADER*)icoBuffer)->biBitCount;
            //}

            for (ushort i = 0; i < count; i++)
            {
                iconStream.Position = iconDirEntries[i].dwImageOffset;
                if (iconReader.ReadUInt32() == 40)
                {
                    iconStream.Position += 8;
                    iconDirEntries[i].wPlanes = iconReader.ReadUInt16();
                    iconDirEntries[i].wBitCount = iconReader.ReadUInt16();
                }
            }

            //read everything and no exceptions. time to write.
            var resWriter = new BinaryWriter(resStream);

            //write all of the icon images as individual resources, then follow up with
            //a resource that groups them.
            const WORD RT_ICON = 3;

            for (ushort i = 0; i < count; i++)
            {
                /* write resource header.
                struct RESOURCEHEADER
                {
                    DWORD DataSize;
                    DWORD HeaderSize;
                    WORD Magic1;
                    WORD Type;
                    WORD Magic2;
                    WORD Name;
                    DWORD DataVersion;
                    WORD MemoryFlags;
                    WORD LanguageId;
                    DWORD Version;
                    DWORD Characteristics;
                };
                */

                resStream.Position = (resStream.Position + 3) & ~3; //headers begin on 4-byte boundaries.
                resWriter.Write((DWORD)iconDirEntries[i].dwBytesInRes);
                resWriter.Write((DWORD)0x00000020);
                resWriter.Write((WORD)0xFFFF);
                resWriter.Write((WORD)RT_ICON);
                resWriter.Write((WORD)0xFFFF);
                resWriter.Write((WORD)(i + 1));       //EDMAURER this is not general. Implies you can only append one icon to the resources.
                                                      //This icon ID would seem to be global among all of the icons not just this group.
                                                      //Zero appears to not be an acceptable ID. Note that this ID is referred to below.
                resWriter.Write((DWORD)0x00000000);
                resWriter.Write((WORD)0x1010);
                resWriter.Write((WORD)0x0000);
                resWriter.Write((DWORD)0x00000000);
                resWriter.Write((DWORD)0x00000000);

                //write the data.
                iconStream.Position = iconDirEntries[i].dwImageOffset;
                resWriter.Write(iconReader.ReadBytes(checked((int)iconDirEntries[i].dwBytesInRes)));
            }

            /*
            
            struct ICONDIR
            {
                WORD           idReserved;   // Reserved (must be 0)
                WORD           idType;       // Resource Type (1 for icons)
                WORD           idCount;      // How many images?
                ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
            }/
             
            struct ICONRESDIR
            {
                BYTE Width;        // = ICONDIRENTRY.bWidth;
                BYTE Height;       // = ICONDIRENTRY.bHeight;
                BYTE ColorCount;   // = ICONDIRENTRY.bColorCount;
                BYTE reserved;     // = ICONDIRENTRY.bReserved;
                WORD Planes;       // = ICONDIRENTRY.wPlanes;
                WORD BitCount;     // = ICONDIRENTRY.wBitCount;
                DWORD BytesInRes;   // = ICONDIRENTRY.dwBytesInRes;
                WORD IconId;       // = RESOURCEHEADER.Name
            };
            */

            const WORD RT_GROUP_ICON = RT_ICON + 11;

            resStream.Position = (resStream.Position + 3) & ~3; //align 4-byte boundary
            //write the icon group. first a RESOURCEHEADER. the data is the ICONDIR
            resWriter.Write((DWORD)(3 * sizeof(WORD) + count * /*sizeof(ICONRESDIR)*/ 14));
            resWriter.Write((DWORD)0x00000020);
            resWriter.Write((WORD)0xFFFF);
            resWriter.Write((WORD)RT_GROUP_ICON);
            resWriter.Write((WORD)0xFFFF);
            resWriter.Write((WORD)0x7F00);  //IDI_APPLICATION
            resWriter.Write((DWORD)0x00000000);
            resWriter.Write((WORD)0x1030);
            resWriter.Write((WORD)0x0000);
            resWriter.Write((DWORD)0x00000000);
            resWriter.Write((DWORD)0x00000000);

            //the ICONDIR
            resWriter.Write((WORD)0x0000);
            resWriter.Write((WORD)0x0001);
            resWriter.Write((WORD)count);

            for (ushort i = 0; i < count; i++)
            {
                resWriter.Write((BYTE)iconDirEntries[i].bWidth);
                resWriter.Write((BYTE)iconDirEntries[i].bHeight);
                resWriter.Write((BYTE)iconDirEntries[i].bColorCount);
                resWriter.Write((BYTE)iconDirEntries[i].bReserved);
                resWriter.Write((WORD)iconDirEntries[i].wPlanes);
                resWriter.Write((WORD)iconDirEntries[i].wBitCount);
                resWriter.Write((DWORD)iconDirEntries[i].dwBytesInRes);
                resWriter.Write((WORD)(i + 1));   //ID
            }
        }