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 +}