-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitmap.h
More file actions
169 lines (142 loc) · 6.12 KB
/
Copy pathbitmap.h
File metadata and controls
169 lines (142 loc) · 6.12 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef __BITMAP_H__
#define __BITMAP_H__
//---------------------------------------------------------------------------------------
// File : bitmap.cpp
// Desc : Bitmap Module.
// Copyright(c) Project Asura. All right reserved.
//---------------------------------------------------------------------------------------
#include <cstdio>
#include <cmath>
//namespace /* anonymous */ {
////////////////////////////////////////////////////////////////////////////////////////
// BMP_COMPRESSION_TYOE enum
////////////////////////////////////////////////////////////////////////////////////////
enum BMP_COMPRESSION_TYPE
{
BMP_COMPRESSION_RGB = 0, // 無圧縮.
BMP_COMPRESSION_RLE8 = 1, // RLE圧縮 8 bits/pixel.
BMP_COMPRESSION_RLE4 = 2, // RLE圧縮 4 bits/pixel.
BMP_COMPRESSION_BITFIELDS = 3, // ビットフィールド.
};
#pragma pack( push, 1 )
////////////////////////////////////////////////////////////////////////////////////////
// BMP_FILE_HEADER structure
////////////////////////////////////////////////////////////////////////////////////////
struct BMP_FILE_HEADER
{
unsigned short type; // ファイルタイプ 'BM'
unsigned int size; // ファイルサイズ.
unsigned short reserved1; // 予約領域 (0固定).
unsigned short reserved2; // 予約領域 (0固定).
unsigned int offBits; // ファイル先頭から画像データまでのオフセット.
};
////////////////////////////////////////////////////////////////////////////////////////
// BMO_INFO_HEADER structure
////////////////////////////////////////////////////////////////////////////////////////
struct BMP_INFO_HEADER
{
unsigned int size; // ヘッダサイズ (40固定).
int width; // 画像の横幅.
int height; // 画像の縦幅.
unsigned short planes; // プレーン数 (1固定).
unsigned short bitCount; // 1ピクセルあたりのビット数.
unsigned int compression; // 圧縮形式.
unsigned int size_image; // 画像データ部のサイズ.
int x_pels_per_meter; // 横方向の解像度.
int y_pels_per_meter; // 縦方向の解像度.
unsigned int clr_used; // 格納されているパレット数.
unsigned int clr_important; // 重要なパレットのインデックス.
};
#pragma pack( pop )
void write_file_header( BMP_FILE_HEADER& header, FILE* pFile )
{
fwrite( &header.type, sizeof(unsigned short), 1, pFile );
fwrite( &header.size, sizeof(unsigned int), 1, pFile );
fwrite( &header.reserved1, sizeof(unsigned short), 1, pFile );
fwrite( &header.reserved2, sizeof(unsigned short), 1, pFile );
fwrite( &header.offBits, sizeof(unsigned int), 1, pFile );
}
void write_info_header( BMP_INFO_HEADER& header, FILE* pFile )
{
fwrite( &header.size, sizeof(unsigned int), 1, pFile );
fwrite( &header.width, sizeof(int), 1, pFile );
fwrite( &header.height, sizeof(int), 1, pFile );
fwrite( &header.planes, sizeof(unsigned short), 1, pFile );
fwrite( &header.bitCount, sizeof(unsigned short), 1, pFile );
fwrite( &header.compression, sizeof(unsigned int), 1, pFile );
fwrite( &header.size_image, sizeof(unsigned int), 1, pFile );
fwrite( &header.x_pels_per_meter, sizeof(int), 1, pFile );
fwrite( &header.y_pels_per_meter, sizeof(int), 1, pFile );
fwrite( &header.clr_used, sizeof(unsigned int), 1, pFile );
fwrite( &header.clr_important, sizeof(unsigned int), 1, pFile );
}
void write_bmp
(
FILE* pFile,
const int width,
const int height,
const double* pPixel,
const double gamma
)
{
BMP_FILE_HEADER fileHeader;
BMP_INFO_HEADER infoHeader;
fileHeader.type = 0x4D42;
fileHeader.size = sizeof(BMP_FILE_HEADER) + sizeof(BMP_INFO_HEADER) + ( width * height * 3 );
fileHeader.reserved1 = 0;
fileHeader.reserved2 = 0;
fileHeader.offBits = sizeof(BMP_FILE_HEADER) + sizeof(BMP_INFO_HEADER);
infoHeader.size = 40;
infoHeader.width = width;
infoHeader.height = height;
infoHeader.planes = 1;
infoHeader.bitCount = 24;
infoHeader.compression = 0;
infoHeader.size_image = 0;
infoHeader.x_pels_per_meter = 0;
infoHeader.y_pels_per_meter = 0;
infoHeader.clr_used = 0;
infoHeader.clr_important = 0;
write_file_header( fileHeader, pFile );
write_info_header( infoHeader, pFile );
for ( int i=height-1; i>=0; --i )
{
for( int j=width-1; j>=0; --j )
{
int index = ( i * width * 3 ) + ( j * 3 );
double r = pow( 1 - exp(-pPixel[index + 0]), 1.0 / gamma );
double g = pow( 1 - exp(-pPixel[index + 1]), 1.0 / gamma );
double b = pow( 1 - exp(-pPixel[index + 2]), 1.0 / gamma );
if ( r > 1.0 ) { r = 1.0; }
if ( g > 1.0 ) { g = 1.0; }
if ( b > 1.0 ) { b = 1.0; }
if ( r < 0.0 ) { r = 0.0; }
if ( g < 0.0 ) { g = 0.0; }
if ( b < 0.0 ) { b = 0.0; }
unsigned char R = static_cast<unsigned char>( r * 255.0 + 0.5 );
unsigned char G = static_cast<unsigned char>( g * 255.0 + 0.5 );
unsigned char B = static_cast<unsigned char>( b * 255.0 + 0.5 );
fwrite( &B, sizeof(unsigned char), 1, pFile );
fwrite( &G, sizeof(unsigned char), 1, pFile );
fwrite( &R, sizeof(unsigned char), 1, pFile );
}
}
}
//} // namespace /* anonymous */
bool save_to_bmp
(
const char* filename,
const int width,
const int height,
const double* colors,
const double gamma
)
{
FILE* fp;
fp = fopen( filename, "wb" );
write_bmp( fp, width, height, colors, gamma );
fclose( fp );
return true;
}
// 24bit bitmap only.
#endif