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