Utilities/IconFactory.cs
author moel.mich
Sun, 08 Aug 2010 13:57:26 +0000
changeset 165 813d8bc3192f
child 344 3145aadca3d2
permissions -rw-r--r--
Refactored the hardware monitoring code into a library (Issue 101).
moel@40
     1
/*
moel@40
     2
  
moel@40
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@40
     4
moel@40
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@40
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@40
     7
  the License. You may obtain a copy of the License at
moel@40
     8
 
moel@40
     9
  http://www.mozilla.org/MPL/
moel@40
    10
moel@40
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@40
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@40
    13
  for the specific language governing rights and limitations under the License.
moel@40
    14
moel@40
    15
  The Original Code is the Open Hardware Monitor code.
moel@40
    16
moel@40
    17
  The Initial Developer of the Original Code is 
moel@40
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@40
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@40
    20
  the Initial Developer. All Rights Reserved.
moel@40
    21
moel@40
    22
  Contributor(s):
moel@40
    23
moel@40
    24
  Alternatively, the contents of this file may be used under the terms of
moel@40
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@40
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@40
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@40
    28
  of those above. If you wish to allow use of your version of this file only
moel@40
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@40
    30
  use your version of this file under the terms of the MPL, indicate your
moel@40
    31
  decision by deleting the provisions above and replace them with the notice
moel@40
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@40
    33
  the provisions above, a recipient may use your version of this file under
moel@40
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@40
    35
 
moel@40
    36
*/
moel@40
    37
moel@40
    38
using System;
moel@40
    39
using System.Collections.Generic;
moel@40
    40
using System.Drawing;
moel@40
    41
using System.Drawing.Imaging;
moel@40
    42
using System.IO;
moel@40
    43
using System.Text;
moel@40
    44
moel@40
    45
namespace OpenHardwareMonitor.Utilities {
moel@40
    46
  public class IconFactory {
moel@40
    47
moel@40
    48
    private struct BITMAPINFOHEADER {
moel@40
    49
      public uint Size;
moel@40
    50
      public int Width;
moel@40
    51
      public int Height;
moel@40
    52
      public ushort Planes;
moel@40
    53
      public ushort BitCount;
moel@40
    54
      public uint Compression;
moel@40
    55
      public uint SizeImage;
moel@40
    56
      public int XPelsPerMeter;
moel@40
    57
      public int YPelsPerMeter;
moel@40
    58
      public uint ClrUsed;
moel@40
    59
      public uint ClrImportant;
moel@40
    60
moel@40
    61
      public BITMAPINFOHEADER(int width, int height, int bitCount) {
moel@40
    62
        this.Size = 40;
moel@40
    63
        this.Width = width;
moel@40
    64
        this.Height = height;
moel@40
    65
        this.Planes = 1;
moel@40
    66
        this.BitCount = (ushort)bitCount;
moel@40
    67
        this.Compression = 0;
moel@40
    68
        this.SizeImage = 0;
moel@40
    69
        this.XPelsPerMeter = 0;
moel@40
    70
        this.YPelsPerMeter = 0;
moel@40
    71
        this.ClrUsed = 0;
moel@40
    72
        this.ClrImportant = 0;
moel@40
    73
      }
moel@40
    74
moel@40
    75
      public void Write(BinaryWriter bw) {
moel@40
    76
        bw.Write(Size);
moel@40
    77
			  bw.Write(Width);
moel@40
    78
			  bw.Write(Height);
moel@40
    79
			  bw.Write(Planes);
moel@40
    80
			  bw.Write(BitCount);
moel@40
    81
			  bw.Write(Compression);
moel@40
    82
			  bw.Write(SizeImage);
moel@40
    83
			  bw.Write(XPelsPerMeter);
moel@40
    84
			  bw.Write(YPelsPerMeter);
moel@40
    85
			  bw.Write(ClrUsed);
moel@40
    86
			  bw.Write(ClrImportant);
moel@40
    87
      }
moel@40
    88
    }
moel@40
    89
moel@40
    90
    private struct ICONIMAGE {
moel@40
    91
      public BITMAPINFOHEADER Header;
moel@40
    92
      public byte[] Colors;
moel@40
    93
      public byte[] XOR;
moel@40
    94
      public byte[] AND;
moel@40
    95
moel@40
    96
      public ICONIMAGE(int width, int height, byte[] colors) {
moel@40
    97
        this.Header = new BITMAPINFOHEADER(width, height << 1, 
moel@40
    98
          (8 * colors.Length) / (width * height));
moel@40
    99
        this.Colors = colors;
moel@40
   100
        int maskSize = (width * height) >> 3;
moel@40
   101
        this.XOR = new byte[maskSize];
moel@40
   102
        this.AND = new byte[maskSize];
moel@40
   103
      }
moel@40
   104
moel@40
   105
      public void Write(BinaryWriter bw) {
moel@40
   106
        Header.Write(bw);
moel@40
   107
        int stride = Header.Width << 2;
moel@40
   108
        for (int i = (Header.Height >> 1) - 1; i >= 0; i--)
moel@40
   109
          bw.Write(Colors, i * stride, stride);
moel@40
   110
        bw.Write(XOR);        
moel@40
   111
        bw.Write(AND);
moel@40
   112
      }
moel@40
   113
    }
moel@40
   114
moel@40
   115
    private struct ICONDIRENTRY {
moel@40
   116
      public byte Width;
moel@40
   117
      public byte Height;
moel@40
   118
      public byte ColorCount;
moel@40
   119
      public byte Reserved;
moel@40
   120
      public ushort Planes;
moel@40
   121
      public ushort BitCount;
moel@40
   122
      public uint BytesInRes;
moel@40
   123
      public uint ImageOffset;
moel@40
   124
moel@40
   125
      public ICONDIRENTRY(ICONIMAGE image, int imageOffset) {
moel@40
   126
        this.Width = (byte)image.Header.Width;
moel@40
   127
        this.Height = (byte)(image.Header.Height >> 1);
moel@40
   128
        this.ColorCount = 0;
moel@40
   129
        this.Reserved = 0;
moel@40
   130
        this.Planes = image.Header.Planes;
moel@40
   131
        this.BitCount = image.Header.BitCount;
moel@40
   132
        this.BytesInRes = (uint)(image.Header.Size +
moel@40
   133
          image.Colors.Length + image.XOR.Length + image.AND.Length);
moel@40
   134
        this.ImageOffset = (uint)imageOffset;
moel@40
   135
      }
moel@40
   136
moel@40
   137
      public void Write(BinaryWriter bw) {
moel@40
   138
        bw.Write(Width);
moel@40
   139
        bw.Write(Height);
moel@40
   140
        bw.Write(ColorCount);
moel@40
   141
        bw.Write(Reserved);
moel@40
   142
        bw.Write(Planes);
moel@40
   143
        bw.Write(BitCount);
moel@40
   144
        bw.Write(BytesInRes);
moel@40
   145
        bw.Write(ImageOffset);
moel@40
   146
      }
moel@40
   147
moel@40
   148
      public uint Size {
moel@40
   149
        get { return 16; }
moel@40
   150
      }
moel@40
   151
    }
moel@40
   152
moel@40
   153
    private struct ICONDIR {
moel@40
   154
      public ushort Reserved;
moel@40
   155
      public ushort Type;
moel@40
   156
      public ushort Count;
moel@40
   157
      public ICONDIRENTRY[] Entries;
moel@40
   158
moel@40
   159
      public ICONDIR(ICONDIRENTRY[] entries) {
moel@40
   160
        this.Reserved = 0;
moel@40
   161
        this.Type = 1;
moel@40
   162
        this.Count = (ushort)entries.Length;
moel@40
   163
        this.Entries = entries;
moel@40
   164
      }
moel@40
   165
moel@40
   166
      public void Write(BinaryWriter bw) {
moel@40
   167
        bw.Write(Reserved);
moel@40
   168
        bw.Write(Type);
moel@40
   169
        bw.Write(Count);
moel@40
   170
        for (int i = 0; i < Entries.Length; i++)
moel@40
   171
          Entries[i].Write(bw);
moel@40
   172
      }
moel@40
   173
moel@40
   174
      public uint Size {
moel@40
   175
        get { return (uint)(6 + Entries.Length * 
moel@40
   176
          (Entries.Length > 0 ? Entries[0].Size : 0)); } 
moel@40
   177
      }
moel@40
   178
    }
moel@40
   179
	
moel@40
   180
    public static Icon Create(byte[] colors, int width, int height, 
moel@40
   181
      PixelFormat format) {
moel@40
   182
      if (format != PixelFormat.Format32bppArgb)
moel@40
   183
        throw new NotImplementedException();
moel@40
   184
moel@40
   185
      ICONIMAGE image = new ICONIMAGE(width, height, colors);
moel@40
   186
      ICONDIR dir = new ICONDIR(
moel@40
   187
        new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) } );
moel@40
   188
      dir.Entries[0].ImageOffset = dir.Size;
moel@40
   189
moel@40
   190
      Icon icon;
moel@40
   191
      using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) {
moel@40
   192
				dir.Write(bw);
moel@40
   193
        image.Write(bw);
moel@40
   194
moel@40
   195
				bw.BaseStream.Position = 0;
moel@40
   196
        icon = new Icon(bw.BaseStream);
moel@40
   197
			}
moel@40
   198
moel@40
   199
      return icon;
moel@40
   200
    }
moel@40
   201
moel@40
   202
  }
moel@40
   203
}