Utilities/IconFactory.cs
changeset 40 2392f7402fb6
child 344 3145aadca3d2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Utilities/IconFactory.cs	Fri Feb 12 00:36:56 2010 +0000
     1.3 @@ -0,0 +1,203 @@
     1.4 +/*
     1.5 +  
     1.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     1.7 +
     1.8 +  The contents of this file are subject to the Mozilla Public License Version
     1.9 +  1.1 (the "License"); you may not use this file except in compliance with
    1.10 +  the License. You may obtain a copy of the License at
    1.11 + 
    1.12 +  http://www.mozilla.org/MPL/
    1.13 +
    1.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    1.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    1.16 +  for the specific language governing rights and limitations under the License.
    1.17 +
    1.18 +  The Original Code is the Open Hardware Monitor code.
    1.19 +
    1.20 +  The Initial Developer of the Original Code is 
    1.21 +  Michael Möller <m.moeller@gmx.ch>.
    1.22 +  Portions created by the Initial Developer are Copyright (C) 2009-2010
    1.23 +  the Initial Developer. All Rights Reserved.
    1.24 +
    1.25 +  Contributor(s):
    1.26 +
    1.27 +  Alternatively, the contents of this file may be used under the terms of
    1.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    1.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    1.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    1.31 +  of those above. If you wish to allow use of your version of this file only
    1.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    1.33 +  use your version of this file under the terms of the MPL, indicate your
    1.34 +  decision by deleting the provisions above and replace them with the notice
    1.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    1.36 +  the provisions above, a recipient may use your version of this file under
    1.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    1.38 + 
    1.39 +*/
    1.40 +
    1.41 +using System;
    1.42 +using System.Collections.Generic;
    1.43 +using System.Drawing;
    1.44 +using System.Drawing.Imaging;
    1.45 +using System.IO;
    1.46 +using System.Text;
    1.47 +
    1.48 +namespace OpenHardwareMonitor.Utilities {
    1.49 +  public class IconFactory {
    1.50 +
    1.51 +    private struct BITMAPINFOHEADER {
    1.52 +      public uint Size;
    1.53 +      public int Width;
    1.54 +      public int Height;
    1.55 +      public ushort Planes;
    1.56 +      public ushort BitCount;
    1.57 +      public uint Compression;
    1.58 +      public uint SizeImage;
    1.59 +      public int XPelsPerMeter;
    1.60 +      public int YPelsPerMeter;
    1.61 +      public uint ClrUsed;
    1.62 +      public uint ClrImportant;
    1.63 +
    1.64 +      public BITMAPINFOHEADER(int width, int height, int bitCount) {
    1.65 +        this.Size = 40;
    1.66 +        this.Width = width;
    1.67 +        this.Height = height;
    1.68 +        this.Planes = 1;
    1.69 +        this.BitCount = (ushort)bitCount;
    1.70 +        this.Compression = 0;
    1.71 +        this.SizeImage = 0;
    1.72 +        this.XPelsPerMeter = 0;
    1.73 +        this.YPelsPerMeter = 0;
    1.74 +        this.ClrUsed = 0;
    1.75 +        this.ClrImportant = 0;
    1.76 +      }
    1.77 +
    1.78 +      public void Write(BinaryWriter bw) {
    1.79 +        bw.Write(Size);
    1.80 +			  bw.Write(Width);
    1.81 +			  bw.Write(Height);
    1.82 +			  bw.Write(Planes);
    1.83 +			  bw.Write(BitCount);
    1.84 +			  bw.Write(Compression);
    1.85 +			  bw.Write(SizeImage);
    1.86 +			  bw.Write(XPelsPerMeter);
    1.87 +			  bw.Write(YPelsPerMeter);
    1.88 +			  bw.Write(ClrUsed);
    1.89 +			  bw.Write(ClrImportant);
    1.90 +      }
    1.91 +    }
    1.92 +
    1.93 +    private struct ICONIMAGE {
    1.94 +      public BITMAPINFOHEADER Header;
    1.95 +      public byte[] Colors;
    1.96 +      public byte[] XOR;
    1.97 +      public byte[] AND;
    1.98 +
    1.99 +      public ICONIMAGE(int width, int height, byte[] colors) {
   1.100 +        this.Header = new BITMAPINFOHEADER(width, height << 1, 
   1.101 +          (8 * colors.Length) / (width * height));
   1.102 +        this.Colors = colors;
   1.103 +        int maskSize = (width * height) >> 3;
   1.104 +        this.XOR = new byte[maskSize];
   1.105 +        this.AND = new byte[maskSize];
   1.106 +      }
   1.107 +
   1.108 +      public void Write(BinaryWriter bw) {
   1.109 +        Header.Write(bw);
   1.110 +        int stride = Header.Width << 2;
   1.111 +        for (int i = (Header.Height >> 1) - 1; i >= 0; i--)
   1.112 +          bw.Write(Colors, i * stride, stride);
   1.113 +        bw.Write(XOR);        
   1.114 +        bw.Write(AND);
   1.115 +      }
   1.116 +    }
   1.117 +
   1.118 +    private struct ICONDIRENTRY {
   1.119 +      public byte Width;
   1.120 +      public byte Height;
   1.121 +      public byte ColorCount;
   1.122 +      public byte Reserved;
   1.123 +      public ushort Planes;
   1.124 +      public ushort BitCount;
   1.125 +      public uint BytesInRes;
   1.126 +      public uint ImageOffset;
   1.127 +
   1.128 +      public ICONDIRENTRY(ICONIMAGE image, int imageOffset) {
   1.129 +        this.Width = (byte)image.Header.Width;
   1.130 +        this.Height = (byte)(image.Header.Height >> 1);
   1.131 +        this.ColorCount = 0;
   1.132 +        this.Reserved = 0;
   1.133 +        this.Planes = image.Header.Planes;
   1.134 +        this.BitCount = image.Header.BitCount;
   1.135 +        this.BytesInRes = (uint)(image.Header.Size +
   1.136 +          image.Colors.Length + image.XOR.Length + image.AND.Length);
   1.137 +        this.ImageOffset = (uint)imageOffset;
   1.138 +      }
   1.139 +
   1.140 +      public void Write(BinaryWriter bw) {
   1.141 +        bw.Write(Width);
   1.142 +        bw.Write(Height);
   1.143 +        bw.Write(ColorCount);
   1.144 +        bw.Write(Reserved);
   1.145 +        bw.Write(Planes);
   1.146 +        bw.Write(BitCount);
   1.147 +        bw.Write(BytesInRes);
   1.148 +        bw.Write(ImageOffset);
   1.149 +      }
   1.150 +
   1.151 +      public uint Size {
   1.152 +        get { return 16; }
   1.153 +      }
   1.154 +    }
   1.155 +
   1.156 +    private struct ICONDIR {
   1.157 +      public ushort Reserved;
   1.158 +      public ushort Type;
   1.159 +      public ushort Count;
   1.160 +      public ICONDIRENTRY[] Entries;
   1.161 +
   1.162 +      public ICONDIR(ICONDIRENTRY[] entries) {
   1.163 +        this.Reserved = 0;
   1.164 +        this.Type = 1;
   1.165 +        this.Count = (ushort)entries.Length;
   1.166 +        this.Entries = entries;
   1.167 +      }
   1.168 +
   1.169 +      public void Write(BinaryWriter bw) {
   1.170 +        bw.Write(Reserved);
   1.171 +        bw.Write(Type);
   1.172 +        bw.Write(Count);
   1.173 +        for (int i = 0; i < Entries.Length; i++)
   1.174 +          Entries[i].Write(bw);
   1.175 +      }
   1.176 +
   1.177 +      public uint Size {
   1.178 +        get { return (uint)(6 + Entries.Length * 
   1.179 +          (Entries.Length > 0 ? Entries[0].Size : 0)); } 
   1.180 +      }
   1.181 +    }
   1.182 +	
   1.183 +    public static Icon Create(byte[] colors, int width, int height, 
   1.184 +      PixelFormat format) {
   1.185 +      if (format != PixelFormat.Format32bppArgb)
   1.186 +        throw new NotImplementedException();
   1.187 +
   1.188 +      ICONIMAGE image = new ICONIMAGE(width, height, colors);
   1.189 +      ICONDIR dir = new ICONDIR(
   1.190 +        new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) } );
   1.191 +      dir.Entries[0].ImageOffset = dir.Size;
   1.192 +
   1.193 +      Icon icon;
   1.194 +      using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) {
   1.195 +				dir.Write(bw);
   1.196 +        image.Write(bw);
   1.197 +
   1.198 +				bw.BaseStream.Position = 0;
   1.199 +        icon = new Icon(bw.BaseStream);
   1.200 +			}
   1.201 +
   1.202 +      return icon;
   1.203 +    }
   1.204 +
   1.205 +  }
   1.206 +}