aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.Resources/GroupIconInfo.cs
blob: 0fb56223ccdffde8964763dbf67ffbed4cdc165a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.

namespace WixToolset.Dtf.Resources
{
    using System;
    using System.IO;
    using System.Text;
    using System.Reflection;
    using System.Collections;
    using System.Globalization;
    using System.Diagnostics.CodeAnalysis;

    internal enum GroupIconType
    {
        Unknown,
        Icon,
        Cursor,
    }

    internal struct GroupIconDirectoryInfo
    {
        public byte width;
        public byte height;
        public byte colors;
        public byte reserved;
        public ushort planes;
        public ushort bitsPerPixel;
        public uint imageSize;
        public uint imageOffset; // only valid when icon group is read from .ico file.
        public ushort imageIndex; // only valid when icon group is read from PE resource.
    }

    internal class GroupIconInfo
    {
        private ushort reserved;
        private GroupIconType type;
        private GroupIconDirectoryInfo[] images;

        public GroupIconInfo()
        {
            this.images = new GroupIconDirectoryInfo[0];
        }

        public GroupIconDirectoryInfo[] DirectoryInfo { get { return this.images; } }

        public void ReadFromFile(Stream stream)
        {
            BinaryReader reader = new BinaryReader(stream);
            this.Read(reader, true);
        }

        public void ReadFromResource(byte[] data)
        {
            using (BinaryReader reader = new BinaryReader(new MemoryStream(data, false)))
            {
                this.Read(reader, false);
            }
        }

        public byte[] GetResourceData()
        {
            byte[] data = null;

            using (MemoryStream stream = new MemoryStream())
            {
                BinaryWriter writer = new BinaryWriter(stream);
                writer.Write(this.reserved);
                writer.Write((ushort)this.type);
                writer.Write((ushort)this.images.Length);
                for (int i = 0; i < this.images.Length; ++i)
                {
                    writer.Write(this.images[i].width);
                    writer.Write(this.images[i].height);
                    writer.Write(this.images[i].colors);
                    writer.Write(this.images[i].reserved);
                    writer.Write(this.images[i].planes);
                    writer.Write(this.images[i].bitsPerPixel);
                    writer.Write(this.images[i].imageSize);
                    writer.Write(this.images[i].imageIndex);
                }

                data = new byte[stream.Length];
                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(data, 0, data.Length);
            }

            return data;
        }

        private void Read(BinaryReader reader, bool readFromFile)
        {
            this.reserved = reader.ReadUInt16();
            this.type = (GroupIconType)reader.ReadUInt16();

            int imageCount = reader.ReadUInt16();
            this.images = new GroupIconDirectoryInfo[imageCount];
            for (int i = 0; i < imageCount; ++i)
            {
                this.images[i].width = reader.ReadByte();
                this.images[i].height = reader.ReadByte();
                this.images[i].colors = reader.ReadByte();
                this.images[i].reserved = reader.ReadByte();
                this.images[i].planes = reader.ReadUInt16();
                this.images[i].bitsPerPixel = reader.ReadUInt16();
                this.images[i].imageSize = reader.ReadUInt32();
                if (readFromFile)
                {
                    this.images[i].imageOffset = reader.ReadUInt32();
                    this.images[i].imageIndex = (ushort)(i + 1);
                }
                else
                {
                    this.images[i].imageIndex = reader.ReadUInt16();
                }
            }
        }

    }
}