-
Notifications
You must be signed in to change notification settings - Fork 8
/
BMP.bt
138 lines (121 loc) · 3.52 KB
/
BMP.bt
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
129
130
131
132
133
134
135
136
137
138
//------------------------------------------------
//--- 010 Editor v2.0 Binary Template
//
// File: BMP.bt
// Author: SweetScape Software
// Version: 2.3
// Purpose: Parse BMP image files.
// Category: Image
// File Mask: *.bmp
// ID Bytes: 42 4D //BM
// History:
// 2.3 2016-02-26 SweetScape: Allow negative heights.
// 2.2 2015-10-13 SweetScape: Updated header for repository submission.
// 2.1 SweetScape: Bug fix for ReadRGBQUAD function.
// 2.0 SweetScape: Added read functions.
// 1.0 SweetScape: Initial release.
//
// More information available at
// https://en.wikipedia.org/wiki/BMP_file_format
//------------------------------------------------
// Define structures used in BMP files
typedef struct { // bmfh
CHAR bfType[2];
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct { // bmih
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct { // rgbq
UBYTE rgbBlue;
UBYTE rgbGreen;
UBYTE rgbRed;
UBYTE rgbReserved;
} RGBQUAD <read=ReadRGBQUAD>;
typedef struct { // rgbt
UBYTE rgbBlue;
UBYTE rgbGreen;
UBYTE rgbRed;
} RGBTRIPLE <read=ReadRGBTRIPLE>;
//---------------------------------------------
// Custom read functions for color types - this allows the
// color to be displayed without having to open up the structure.
string ReadRGBQUAD( RGBQUAD &a )
{
string s;
SPrintf( s, "#%02X%02X%02X%02X", a.rgbReserved, a.rgbRed, a.rgbGreen, a.rgbBlue );
return s;
}
string ReadRGBTRIPLE( RGBTRIPLE &a )
{
string s;
SPrintf( s, "#%02X%02X%02X", a.rgbRed, a.rgbGreen, a.rgbBlue );
return s;
}
//---------------------------------------------
// Define the headers
LittleEndian();
SetBackColor( cLtGray );
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
// Check for header
if( bmfh.bfType != "BM" )
{
Warning( "File is not a bitmap. Template stopped." );
return -1;
}
// Define the color table
if( (bmih.biBitCount != 24) && (bmih.biBitCount != 32) )
{
SetBackColor( cLtAqua );
if( bmih.biClrUsed > 0 )
RGBQUAD aColors[ bmih.biClrUsed ];
else
RGBQUAD aColors[ 1 << bmih.biBitCount ];
}
// Define the bytes of the data
SetBackColor( cNone );
if( bmih.biCompression > 0 )
{
// Bytes are compressed
if( bmih.biSizeImage > 0 )
UBYTE rleData[ bmih.biSizeImage ];
else
UBYTE rleData[ bmfh.bfSize - FTell() ];
}
else
{
// Calculate bytes per line and padding required
local int bytesPerLine = (int)Ceil( bmih.biWidth * bmih.biBitCount / 8.0 );
local int padding = 4 - (bytesPerLine % 4);
if( padding == 4 )
padding = 0;
// Define each line of the image
struct BITMAPLINE {
// Define color data
if( bmih.biBitCount < 8 )
UBYTE imageData[ bytesPerLine ];
else if( bmih.biBitCount == 8 )
UBYTE colorIndex[ bmih.biWidth ];
else if( bmih.biBitCount == 24 )
RGBTRIPLE colors[ bmih.biWidth ];
else if( bmih.biBitCount == 32 )
RGBQUAD colors[ bmih.biWidth ];
// Pad if necessary
if( padding != 0 )
UBYTE padBytes[ padding ];
} lines[ (bmih.biHeight < 0) ? -bmih.biHeight : bmih.biHeight] <optimize=true>;
}