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