Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CPixelbit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Sun Aug 15 01:53:13 2010 UTC (13 years, 9 months ago) by okadu
File MIME type: text/x-c++src
File size: 10220 byte(s)


1 #include "CPixelbit.h"
2
3 // 関数宣言
4 void Dialog(char *, ...);
5
6 // 内部グローバル
7 HMODULE CPixelbit::ms_hMSIMG32;
8 BOOL (WINAPI *CPixelbit::ms_TransBlt)(HDC, int, int, int, int, HDC, int, int, int, int, UINT);
9
10 /*
11 * [static]
12 * 外部ライブラリの初期化
13 */
14 BOOL CPixelbit::InitExtFunc(){
15 ms_hMSIMG32 = LoadLibrary("msimg32.dll");
16 ms_TransBlt = (BOOL (WINAPI *)(HDC, int, int, int, int,
17 HDC, int, int, int, int, UINT)) GetProcAddress(ms_hMSIMG32, "TransparentBlt");
18 if(!ms_TransBlt) return FALSE;
19 return TRUE;
20 }
21
22 /*
23 * [static]
24 * 外部ライブラリの解放
25 */
26 void CPixelbit::FreeExtFunc(){
27 FreeLibrary(ms_hMSIMG32);
28 }
29
30 /*
31 * コンストラクタ
32 */
33 CPixelbit::CPixelbit(){
34 m_PixelAdr = NULL;
35 m_ColorKey = 0xffffffff;
36 m_Width = 0;
37 m_Height = 0;
38 Clear(1, 1);
39 }
40
41 /*
42 * コンストラクタ (サイズ指定)
43 */
44 CPixelbit::CPixelbit(
45 int w, int h // サイズ
46 ){
47 m_PixelAdr = NULL;
48 m_ColorKey = 0xffffffff;
49 m_Width = 0;
50 m_Height = 0;
51 Clear(w, h);
52 }
53
54 /*
55 * デストラクタ
56 */
57 CPixelbit::~CPixelbit(){
58 if(m_PixelAdr){
59 SelectObject(m_BmpHdc, m_BmpHndOld);
60 DeleteObject(m_BmpHnd);
61 DeleteDC(m_BmpHdc);
62 m_PixelAdr = NULL;
63 }
64 }
65
66 /*
67 * サイズを指定して初期化
68 *
69 * 戻り値: 成功したら TRUE を返す
70 */
71 BOOL CPixelbit::Clear(
72 int w, int h, // サイズ
73 int sbit // ビット深度
74 ){
75 if(sbit!=24) sbit = 32;
76 m_BitsPerPixel = sbit;
77 m_BytesPerPixel = m_BitsPerPixel/8;
78 m_BytesPerLine = (w*m_BytesPerPixel+3)&~3;
79 m_DwordsPerLine = m_BytesPerLine/4;
80 PDWORD adr = NULL;
81 BITMAPINFO bmpinfo;
82 HBITMAP bmphnd;
83 HDC hdc, hdcnew;
84 if(w<=0 || h==0) return FALSE;
85 ZeroMemory(&bmpinfo, sizeof(bmpinfo));
86 bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
87 bmpinfo.bmiHeader.biWidth = w;
88 bmpinfo.bmiHeader.biHeight = -h;
89 bmpinfo.bmiHeader.biPlanes = 1;
90 bmpinfo.bmiHeader.biBitCount = sbit;
91 bmpinfo.bmiHeader.biCompression = BI_RGB;
92 bmphnd = CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, (void **)(&adr), NULL, 0);
93 if(!bmphnd) return FALSE;
94 hdc = GetDC(0);
95 hdcnew = CreateCompatibleDC(hdc);
96 ReleaseDC(0, hdc);
97 if(!hdcnew){
98 DeleteObject(bmphnd);
99 return FALSE;
100 }
101 if(m_PixelAdr){
102 SelectObject(m_BmpHdc, m_BmpHndOld);
103 DeleteObject(m_BmpHnd);
104 DeleteDC(m_BmpHdc);
105 m_PixelAdr = NULL;
106 }
107 m_BmpInfo = bmpinfo;
108 m_PixelAdr = adr;
109 m_BmpHnd = bmphnd;
110 m_BmpHdc = hdcnew;
111 m_BmpHndOld = (HBITMAP)SelectObject(m_BmpHdc, m_BmpHnd);
112 m_Width = w;
113 m_Height = h < 0 ? -h : h;
114 #ifdef ENABLE_RECT_BOUNDARY
115 ResetBoundary();
116 #endif
117 ZeroMemory(m_PixelAdr, m_BytesPerLine*m_Height);
118 return TRUE;
119 }
120
121 /*
122 * ファイルから読込
123 *
124 * 戻り値: 成功したらビット深度を返す
125 */
126 int CPixelbit::Load(
127 char *fname // ファイル名
128 ){
129 PBYTE buf;
130 HANDLE fh;
131 DWORD load;
132 int size;
133 if(!fname) return 0;
134 fh = CreateFile(fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
135 if(fh==INVALID_HANDLE_VALUE) return 0;
136 buf = new BYTE[size = GetFileSize(fh, NULL)];
137 ReadFile(fh, buf, size, &load, NULL);
138 CloseHandle(fh);
139 if(Assign(buf+sizeof(BITMAPFILEHEADER))){
140 int sbit = ((LPBITMAPINFOHEADER)(buf+sizeof(BITMAPFILEHEADER)))->biBitCount;
141 delete [] buf;
142 return sbit;
143 }else{
144 delete [] buf;
145 return 0;
146 }
147 }
148
149 /*
150 * ファイルに保存
151 *
152 * 戻り値: 成功したら TRUE を返す
153 */
154 BOOL CPixelbit::Save(
155 char *fname, // ファイル名
156 int sbit // ビット深度
157 ){
158 DWORD wrote, size;
159 if(m_Width*m_Height<1) return FALSE;
160 if(sbit!=24) sbit = 32;
161 int len = (m_Width*sbit/8+3)&~3;
162 size = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+len*m_Height;
163 PBYTE buf = new BYTE[size];
164 ZeroMemory(buf, size);
165 buf[0] = 'B';
166 buf[1] = 'M';
167 CopyMemory(buf+2, &size, 4);
168 *(PDWORD)(buf+10) = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
169 PrepareDIB(buf+14, len, sbit);
170 HANDLE fh = CreateFile(fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
171 WriteFile(fh, buf, size, &wrote, NULL);
172 CloseHandle(fh);
173 delete [] buf;
174 return wrote==size;
175 }
176
177 /*
178 * クリップボードから貼り付け
179 *
180 * 戻り値: 成功したらビット深度を返す
181 */
182 int CPixelbit::PasteFromClipboard(
183 HWND hWnd // 窓ハンドル
184 ){
185 if(!OpenClipboard(hWnd)) return 0;
186 PBYTE buf;
187 HANDLE clip = GetClipboardData(CF_DIB);
188 if(!clip || !(buf = (PBYTE)GlobalLock(clip)) || !Assign(buf)){
189 CloseClipboard();
190 return 0;
191 }
192 int sbit = ((LPBITMAPINFOHEADER)buf)->biBitCount;
193 GlobalUnlock(clip);
194 CloseClipboard();
195 return sbit;
196 }
197
198 /*
199 * クリップボードにコピー
200 *
201 * 戻り値: 成功したら TRUE を返す
202 */
203 BOOL CPixelbit::CopyToClipboard(
204 HWND hWnd, // 窓ハンドル
205 int sbit // ビット深度
206 ){
207 if(m_Width*m_Height<1) return FALSE;
208 if(!OpenClipboard(hWnd)) return FALSE;
209 sbit = sbit==32 ? 32 : 24;
210 int len = (m_Width*sbit/8+3)&~3;
211 int size = sizeof(BITMAPINFOHEADER)+len*m_Height;
212 PBYTE buf;
213 HGLOBAL data = GlobalAlloc(GHND|GMEM_SHARE, size);
214 if(!data || !(buf = (PBYTE)GlobalLock(data))){
215 CloseClipboard();
216 return FALSE;
217 }
218 PrepareDIB(buf, len, sbit);
219 GlobalUnlock(data);
220 EmptyClipboard();
221 SetClipboardData(CF_DIB, data);
222 CloseClipboard();
223 return TRUE;
224 }
225
226 /*
227 * メモリ領域上のビットマップを割り当てる
228 *
229 * 戻り値: 成功したら TRUE を返す
230 */
231 BOOL CPixelbit::Assign(
232 PBYTE ptr // BITMAPINFOHEADER の先頭
233 ){
234 int w, h;
235 LPBITMAPINFOHEADER head;
236 if(!ptr) return FALSE;
237 head = (LPBITMAPINFOHEADER)ptr;
238 w = head->biWidth;
239 h = head->biHeight;
240 if(w*h<1) return FALSE;
241 if(!Clear(w, h)) return FALSE;
242 PBYTE adr = ptr+sizeof(BITMAPINFOHEADER);
243 if(head->biCompression==BI_BITFIELDS) adr += 12;
244 switch(head->biBitCount){
245 case 1: Set4PAL1(m_Width, m_Height, adr); break;
246 case 4: Set4PAL4(m_Width, m_Height, adr); break;
247 case 8: Set4PAL8(m_Width, m_Height, adr); break;
248 case 24: Set4BGR24(m_Width, m_Height, adr); break;
249 case 32: Set4BGR32(m_Width, m_Height, adr); break;
250 }
251 return TRUE;
252 }
253
254 /*
255 * メモリからパレット画像 (4bit/pixel) を読み込む
256 */
257 void CPixelbit::Set4PAL1(
258 int w, int h, // 画像サイズ
259 PBYTE ptr // パレット開始アドレス
260 ){
261 int i, j, len = w%32 ? (w/32+1)*4 : w/8, bit;
262 PDWORD pal = (PDWORD)ptr;
263 ptr += 2*sizeof(DWORD);
264 for(i = 0; i<h; i++){
265 PBYTE src = ptr+(h-i-1)*len;
266 PDWORD dest = m_PixelAdr+w*i;
267 for(j = 0, bit = 7; j<w; j++, bit = (bit-1)&7){
268 *dest++ = pal[(*src>>bit)&0x01];
269 if(!bit) src++;
270 }
271 }
272 }
273
274 /*
275 * メモリからパレット画像 (4bit/pixel) を読み込む
276 */
277 void CPixelbit::Set4PAL4(
278 int w, int h, // 画像サイズ
279 PBYTE ptr // パレット開始アドレス
280 ){
281 int i, j, len = w%8 ? (w/8+1)*4 : w/2, bit;
282 PDWORD pal = (PDWORD)ptr;
283 ptr += 16*sizeof(DWORD);
284 for(i = 0; i<h; i++){
285 PBYTE src = ptr+(h-i-1)*len;
286 PDWORD dest = m_PixelAdr+w*i;
287 for(j = 0, bit = 4; j<w; j++, bit = (bit-4)&7){
288 *dest++ = pal[(*src>>bit)&0x0f];
289 if(!bit) src++;
290 }
291 }
292 }
293
294 /*
295 * メモリからパレット画像 (8bit/pixel) を読み込む
296 */
297 void CPixelbit::Set4PAL8(
298 int w, int h, // 画像サイズ
299 PBYTE ptr // パレット開始アドレス
300 ){
301 int i, j, len = w%4 ? (w/4+1)*4 : w;
302 PDWORD pal = (PDWORD)ptr;
303 ptr += 256*sizeof(DWORD);
304 for(i = 0; i<h; i++){
305 PBYTE src = ptr+(h-i-1)*len;
306 PDWORD dest = m_PixelAdr+w*i;
307 for(j = 0; j<w; j++) *dest++ = pal[*src++];
308 }
309 }
310
311 /*
312 * メモリ上の BGR (24bit/pixel) 列から画像を読み込む
313 */
314 void CPixelbit::Set4BGR24(
315 int w, int h, // 画像サイズ
316 PBYTE ptr // ビットマップ開始アドレス
317 ){
318 int i, j, len = w%4 ? (w*3/4+1)*4 : w*3;
319 for(i = 0; i<h; i++){
320 PBYTE src = ptr+(h-i-1)*len;
321 PBYTE dest = (PBYTE)(m_PixelAdr+w*i);
322 for(j = 0; j<w; j++){
323 *dest++ = *src++;
324 *dest++ = *src++;
325 *dest++ = *src++;
326 *dest++ = 0;
327 }
328 }
329 }
330
331 /*
332 * メモリ上の BGR (32bit/pixel) 列から画像を読み込む
333 */
334 void CPixelbit::Set4BGR32(
335 int w, int h, // 画像サイズ
336 PBYTE ptr // ビットマップ開始アドレス
337 ){
338 int i, j, len = w*4;
339 for(i = 0; i<h; i++){
340 PDWORD src = (PDWORD)(ptr+(h-i-1)*len);
341 PDWORD dest = m_PixelAdr+w*i;
342 for(j = 0; j<w; j++) *dest++ = *src++;
343 }
344 }
345
346 /*
347 * DIB データ作成 (保存・クリップボードコピー用)
348 */
349 void CPixelbit::PrepareDIB(
350 PBYTE buf, // BITMAPINFOHEADER の先頭
351 int len, // ライン長
352 int sbit // ビット深度
353 ){
354 int i, j;
355 LPBITMAPINFOHEADER head = (LPBITMAPINFOHEADER)buf;
356 PBYTE pixel = (PBYTE)head+sizeof(BITMAPINFOHEADER);
357 head->biSize = sizeof(BITMAPINFOHEADER);
358 head->biWidth = m_Width;
359 head->biHeight = m_Height;
360 head->biPlanes = 1;
361 head->biBitCount = sbit;
362 if(m_BitsPerPixel==(unsigned int)sbit){
363 memcpy(pixel, m_PixelAdr, len*m_Height);
364 }else if(m_BitsPerPixel==32 && sbit==24){
365 for(i = 0; i<m_Height; i++){
366 PDWORD src = m_PixelAdr+m_Width*(m_Height-i-1);
367 PBYTE dest = pixel+i*len;
368 for(j = 0; j <m_Width; j++, src++){
369 *dest++ = (BYTE)*src;
370 *dest++ = (BYTE)(*src>>8);
371 *dest++ = (BYTE)(*src>>16);
372 }
373 }
374 }
375 }
376
377 ////////////////////////////////////////////////////////////////////////////////
378 ////////////////////////////////////////////////////////////////////////////////
379
380 /*
381 * POINT 構造体に値を代入して生成
382 *
383 * 戻り値: POINT のインスタンス
384 */
385 POINT MakeRect(
386 int x, int y // 座標
387 ){
388 POINT pos;
389 pos.x = x;
390 pos.y = y;
391 return pos;
392 }
393
394 /*
395 * RECT 構造体に値を代入して生成
396 *
397 * 戻り値: RECT のインスタンス
398 */
399 RECT MakeRect(
400 int x, int y, // 座標
401 int w, int h // サイズ
402 ){
403 RECT rect;
404 rect.left = x;
405 rect.top = y;
406 rect.right = x+w;
407 rect.bottom = y+h;
408 return rect;
409 }
410
411 /*
412 * RGB 値から HSV 値を計算
413 */
414 void RGBtoHSV(
415 BYTE r, BYTE g, BYTE b, // RGB 値
416 int *hh, // h 値 (色相) 代入先
417 int *ss, // s 値 (彩度) 代入先
418 int *vv // v 値 (明度) 代入先
419 ){
420 int rr, gg, bb, x, h, v, t;
421 v = r>g ? (r>b ? r : b) : (g>b ? g : b); // _max(r, g, b);
422 x = r<g ? (r<b ? r : b) : (g<b ? g : b); // _min(r, g, b);
423 t = v-x;
424 if(vv) *vv = v;
425 if(ss) *ss = v ? t*255/v : 0;
426 if(!hh) return;
427 if(t){
428 rr = (v-r)*255/t;
429 gg = (v-g)*255/t;
430 bb = (v-b)*255/t;
431 }else{
432 rr = gg = bb = 0;
433 }
434 if(g==v){
435 h = r==x ? 1280+bb : 256-rr;
436 }else if(r==v){
437 h = b==x ? 256+gg : 768-bb;
438 }else{
439 h = g==x ? 768+rr : 1280-gg;
440 }
441 *hh = 359-(((h*60)>>8)+240)%360;
442 //*hh = h%1536; // h = (h*60)/256; h %= 360;
443 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26