-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathDibToImage.cs
128 lines (108 loc) · 4.95 KB
/
DibToImage.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* Ýòîò ôàéë ÿâëÿåòñÿ ÷àñòüþ áèáëèîòåêè Saraff.Twain.NET
* © SARAFF SOFTWARE (Êèðíîæèöêèé Àíäðåé), 2011.
* Saraff.Twain.NET - ñâîáîäíàÿ ïðîãðàììà: âû ìîæåòå ïåðåðàñïðîñòðàíÿòü åå è/èëè
* èçìåíÿòü åå íà óñëîâèÿõ Ìåíüøåé Ñòàíäàðòíîé îáùåñòâåííîé ëèöåíçèè GNU â òîì âèäå,
* â êàêîì îíà áûëà îïóáëèêîâàíà Ôîíäîì ñâîáîäíîãî ïðîãðàììíîãî îáåñïå÷åíèÿ;
* ëèáî âåðñèè 3 ëèöåíçèè, ëèáî (ïî âàøåìó âûáîðó) ëþáîé áîëåå ïîçäíåé
* âåðñèè.
* Saraff.Twain.NET ðàñïðîñòðàíÿåòñÿ â íàäåæäå, ÷òî îíà áóäåò ïîëåçíîé,
* íî ÁÅÇÎ ÂÑßÊÈÕ ÃÀÐÀÍÒÈÉ; äàæå áåç íåÿâíîé ãàðàíòèè ÒÎÂÀÐÍÎÃÎ ÂÈÄÀ
* èëè ÏÐÈÃÎÄÍÎÑÒÈ ÄËß ÎÏÐÅÄÅËÅÍÍÛÕ ÖÅËÅÉ. Ïîäðîáíåå ñì. â Ìåíüøåé Ñòàíäàðòíîé
* îáùåñòâåííîé ëèöåíçèè GNU.
* Âû äîëæíû áûëè ïîëó÷èòü êîïèþ Ìåíüøåé Ñòàíäàðòíîé îáùåñòâåííîé ëèöåíçèè GNU
* âìåñòå ñ ýòîé ïðîãðàììîé. Åñëè ýòî íå òàê, ñì.
* <http://www.gnu.org/licenses/>.)
*
* This file is part of Saraff.Twain.NET.
* © SARAFF SOFTWARE (Kirnazhytski Andrei), 2011.
* Saraff.Twain.NET is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Saraff.Twain.NET is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with Saraff.Twain.NET. If not, see <http://www.gnu.org/licenses/>.
*
* PLEASE SEND EMAIL TO: [email protected].
*/
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
namespace Saraff.Twain {
internal sealed class DibToImage : _ImageHandler {
/// <summary>
/// Convert a block of unmanaged memory to stream.
/// </summary>
/// <param name="ptr">The pointer to block of unmanaged memory.</param>
/// <param name="stream"></param>
protected override void PtrToStreamCore(IntPtr ptr, Stream stream) {
BinaryWriter _writer = new BinaryWriter(stream);
#region BITMAPFILEHEADER
BITMAPINFOHEADER _header = this.Header;
_writer.Write((ushort)0x4d42);
_writer.Write(14 + this.GetSize());
_writer.Write(0);
_writer.Write(14 + _header.biSize + (_header.ClrUsed << 2));
#endregion
#region BITMAPINFO and pixel data
base.PtrToStreamCore(ptr, stream);
#endregion
}
/// <summary>
/// Gets the size of a image data.
/// </summary>
/// <returns>
/// Size of a image data.
/// </returns>
protected override int GetSize() {
if(!this.HandlerState.ContainsKey("DIBSIZE")) {
BITMAPINFOHEADER _header = this.Header;
int _extra = 0;
if(_header.biCompression == 0) {
int _bytesPerRow = ((_header.biWidth * _header.biBitCount) >> 3);
_extra = Math.Max(_header.biHeight * (_bytesPerRow + ((_bytesPerRow & 0x3) != 0 ? 4 - _bytesPerRow & 0x3 : 0)) - _header.biSizeImage, 0);
}
this.HandlerState.Add("DIBSIZE", _header.biSize + _header.biSizeImage + _extra + (_header.ClrUsed << 2));
}
return (int)this.HandlerState["DIBSIZE"];
}
/// <summary>
/// Gets the size of the buffer.
/// </summary>
/// <value>
/// The size of the buffer.
/// </value>
protected override int BufferSize => 256 * 1024; //256K
private BITMAPINFOHEADER Header {
get {
if(!this.HandlerState.ContainsKey("BITMAPINFOHEADER")) {
this.HandlerState.Add("BITMAPINFOHEADER", Marshal.PtrToStructure(this.ImagePointer, typeof(BITMAPINFOHEADER)));
}
return this.HandlerState["BITMAPINFOHEADER"] as BITMAPINFOHEADER;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
private class BITMAPINFOHEADER {
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
public int ClrUsed => this.IsRequiredCreateColorTable ? 1 << this.biBitCount : this.biClrUsed;
public bool IsRequiredCreateColorTable => this.biClrUsed == 0 && this.biBitCount <= 8;
}
}
}