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