Utilities/IconFactory.cs
author moel.mich
Sun, 27 May 2012 14:23:31 +0000
changeset 344 3145aadca3d2
parent 40 2392f7402fb6
child 384 76f859f4aea1
permissions -rw-r--r--
Changed the license to the Mozilla Public License 2.0 and update the licensing information.
moel@40
     1
/*
moel@40
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@40
     6
 
moel@344
     7
  Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@40
     9
*/
moel@40
    10
moel@40
    11
using System;
moel@40
    12
using System.Collections.Generic;
moel@40
    13
using System.Drawing;
moel@40
    14
using System.Drawing.Imaging;
moel@40
    15
using System.IO;
moel@40
    16
using System.Text;
moel@40
    17
moel@40
    18
namespace OpenHardwareMonitor.Utilities {
moel@40
    19
  public class IconFactory {
moel@40
    20
moel@40
    21
    private struct BITMAPINFOHEADER {
moel@40
    22
      public uint Size;
moel@40
    23
      public int Width;
moel@40
    24
      public int Height;
moel@40
    25
      public ushort Planes;
moel@40
    26
      public ushort BitCount;
moel@40
    27
      public uint Compression;
moel@40
    28
      public uint SizeImage;
moel@40
    29
      public int XPelsPerMeter;
moel@40
    30
      public int YPelsPerMeter;
moel@40
    31
      public uint ClrUsed;
moel@40
    32
      public uint ClrImportant;
moel@40
    33
moel@40
    34
      public BITMAPINFOHEADER(int width, int height, int bitCount) {
moel@40
    35
        this.Size = 40;
moel@40
    36
        this.Width = width;
moel@40
    37
        this.Height = height;
moel@40
    38
        this.Planes = 1;
moel@40
    39
        this.BitCount = (ushort)bitCount;
moel@40
    40
        this.Compression = 0;
moel@40
    41
        this.SizeImage = 0;
moel@40
    42
        this.XPelsPerMeter = 0;
moel@40
    43
        this.YPelsPerMeter = 0;
moel@40
    44
        this.ClrUsed = 0;
moel@40
    45
        this.ClrImportant = 0;
moel@40
    46
      }
moel@40
    47
moel@40
    48
      public void Write(BinaryWriter bw) {
moel@40
    49
        bw.Write(Size);
moel@40
    50
			  bw.Write(Width);
moel@40
    51
			  bw.Write(Height);
moel@40
    52
			  bw.Write(Planes);
moel@40
    53
			  bw.Write(BitCount);
moel@40
    54
			  bw.Write(Compression);
moel@40
    55
			  bw.Write(SizeImage);
moel@40
    56
			  bw.Write(XPelsPerMeter);
moel@40
    57
			  bw.Write(YPelsPerMeter);
moel@40
    58
			  bw.Write(ClrUsed);
moel@40
    59
			  bw.Write(ClrImportant);
moel@40
    60
      }
moel@40
    61
    }
moel@40
    62
moel@40
    63
    private struct ICONIMAGE {
moel@40
    64
      public BITMAPINFOHEADER Header;
moel@40
    65
      public byte[] Colors;
moel@40
    66
      public byte[] XOR;
moel@40
    67
      public byte[] AND;
moel@40
    68
moel@40
    69
      public ICONIMAGE(int width, int height, byte[] colors) {
moel@40
    70
        this.Header = new BITMAPINFOHEADER(width, height << 1, 
moel@40
    71
          (8 * colors.Length) / (width * height));
moel@40
    72
        this.Colors = colors;
moel@40
    73
        int maskSize = (width * height) >> 3;
moel@40
    74
        this.XOR = new byte[maskSize];
moel@40
    75
        this.AND = new byte[maskSize];
moel@40
    76
      }
moel@40
    77
moel@40
    78
      public void Write(BinaryWriter bw) {
moel@40
    79
        Header.Write(bw);
moel@40
    80
        int stride = Header.Width << 2;
moel@40
    81
        for (int i = (Header.Height >> 1) - 1; i >= 0; i--)
moel@40
    82
          bw.Write(Colors, i * stride, stride);
moel@40
    83
        bw.Write(XOR);        
moel@40
    84
        bw.Write(AND);
moel@40
    85
      }
moel@40
    86
    }
moel@40
    87
moel@40
    88
    private struct ICONDIRENTRY {
moel@40
    89
      public byte Width;
moel@40
    90
      public byte Height;
moel@40
    91
      public byte ColorCount;
moel@40
    92
      public byte Reserved;
moel@40
    93
      public ushort Planes;
moel@40
    94
      public ushort BitCount;
moel@40
    95
      public uint BytesInRes;
moel@40
    96
      public uint ImageOffset;
moel@40
    97
moel@40
    98
      public ICONDIRENTRY(ICONIMAGE image, int imageOffset) {
moel@40
    99
        this.Width = (byte)image.Header.Width;
moel@40
   100
        this.Height = (byte)(image.Header.Height >> 1);
moel@40
   101
        this.ColorCount = 0;
moel@40
   102
        this.Reserved = 0;
moel@40
   103
        this.Planes = image.Header.Planes;
moel@40
   104
        this.BitCount = image.Header.BitCount;
moel@40
   105
        this.BytesInRes = (uint)(image.Header.Size +
moel@40
   106
          image.Colors.Length + image.XOR.Length + image.AND.Length);
moel@40
   107
        this.ImageOffset = (uint)imageOffset;
moel@40
   108
      }
moel@40
   109
moel@40
   110
      public void Write(BinaryWriter bw) {
moel@40
   111
        bw.Write(Width);
moel@40
   112
        bw.Write(Height);
moel@40
   113
        bw.Write(ColorCount);
moel@40
   114
        bw.Write(Reserved);
moel@40
   115
        bw.Write(Planes);
moel@40
   116
        bw.Write(BitCount);
moel@40
   117
        bw.Write(BytesInRes);
moel@40
   118
        bw.Write(ImageOffset);
moel@40
   119
      }
moel@40
   120
moel@40
   121
      public uint Size {
moel@40
   122
        get { return 16; }
moel@40
   123
      }
moel@40
   124
    }
moel@40
   125
moel@40
   126
    private struct ICONDIR {
moel@40
   127
      public ushort Reserved;
moel@40
   128
      public ushort Type;
moel@40
   129
      public ushort Count;
moel@40
   130
      public ICONDIRENTRY[] Entries;
moel@40
   131
moel@40
   132
      public ICONDIR(ICONDIRENTRY[] entries) {
moel@40
   133
        this.Reserved = 0;
moel@40
   134
        this.Type = 1;
moel@40
   135
        this.Count = (ushort)entries.Length;
moel@40
   136
        this.Entries = entries;
moel@40
   137
      }
moel@40
   138
moel@40
   139
      public void Write(BinaryWriter bw) {
moel@40
   140
        bw.Write(Reserved);
moel@40
   141
        bw.Write(Type);
moel@40
   142
        bw.Write(Count);
moel@40
   143
        for (int i = 0; i < Entries.Length; i++)
moel@40
   144
          Entries[i].Write(bw);
moel@40
   145
      }
moel@40
   146
moel@40
   147
      public uint Size {
moel@40
   148
        get { return (uint)(6 + Entries.Length * 
moel@40
   149
          (Entries.Length > 0 ? Entries[0].Size : 0)); } 
moel@40
   150
      }
moel@40
   151
    }
moel@40
   152
	
moel@40
   153
    public static Icon Create(byte[] colors, int width, int height, 
moel@40
   154
      PixelFormat format) {
moel@40
   155
      if (format != PixelFormat.Format32bppArgb)
moel@40
   156
        throw new NotImplementedException();
moel@40
   157
moel@40
   158
      ICONIMAGE image = new ICONIMAGE(width, height, colors);
moel@40
   159
      ICONDIR dir = new ICONDIR(
moel@40
   160
        new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) } );
moel@40
   161
      dir.Entries[0].ImageOffset = dir.Size;
moel@40
   162
moel@40
   163
      Icon icon;
moel@40
   164
      using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) {
moel@40
   165
				dir.Write(bw);
moel@40
   166
        image.Write(bw);
moel@40
   167
moel@40
   168
				bw.BaseStream.Position = 0;
moel@40
   169
        icon = new Icon(bw.BaseStream);
moel@40
   170
			}
moel@40
   171
moel@40
   172
      return icon;
moel@40
   173
    }
moel@40
   174
moel@40
   175
  }
moel@40
   176
}