TNB Library
TnbBitmapPortableFormat.h
[詳解]
1#pragma once
11#include "TnbBitmapImage.h"
12#include "TnbBlockLinkVector.h"
13#include "TnbFile.h"
14#include "TnbStrOperator.h"
15
16
17
18//TNB Library
19namespace TNB
20{
21
22
23
39{
40public:
41
44 {
51 };
52
59 {
60 return m_desc;
61 }
62
71 bool Set(size_t size, LPCVOID pData)
72 {
74 const char* contents = static_cast<const char*>(pData);
75 const char* lpszText = contents;
76 INDEX ind = 0;
77 CAscii pa;
78 bool isFinishied = false;
79 while ( ! isFinishied )
80 {
81 const char* p = lpszText;
82 size_t len = 0;
83 while ( true )
84 {
85 if ( *p == 0 )
86 {
87 if ( len == 0 )
88 {
89 isFinishied = true;
90 }
91 break;
92 }
93 else if ( *p == 0x0D || *p == 0x0A )
94 {
95 p++;
96 if ( *p == 0x0A )
97 {
98 p++;
99 }
100 break;
101 }
102 int s = STRLIB::GetCharSize(*p);
103 p += s;
104 len += s;
105 }
106 if ( ! isFinishied )
107 {
108 char c = contents[ind];
109 if ( c == '#' || c == 0 )
110 {
111 ; //記憶しない
112 }
113 else if ( c < 0x20 && c > 'P' )
114 {
115 break; //バイナリデータ
116 }
117 else
118 {
119 params.Add(TParam(ind, len));
120 if ( pa.IsEmpty() )
121 {
122 pa.SetFromLeft(&contents[params[0].index], params[0].size);
123 }
124 if ( pa == "P4" && params.GetSize() >= 2 )
125 {
126 break;
127 }
128 if ( (pa == "P5" || pa == "P6") && params.GetSize() >= 3 )
129 {
130 break;
131 }
132 }
133 ind += p - lpszText;
134 lpszText += p - lpszText;
135 }
136 }
137 //
138 if ( params.GetSize() < 2 )
139 {
140 return false;
141 }
142 DWORD colorDips = 0; // カラー深さ
143 SIZE sz; // 画像サイズ
144 // サイズチェック
145 CAscii a;
146 a.SetFromLeft(&contents[params[1].index], params[1].size);
147 while ( a.Replace("\t", " ") != 0 );
148 while ( a.Replace(" ", " ") != 0 );
150 if ( va.GetSize() != 2 )
151 {
152 return false;
153 }
154 sz.cx = va[0].ToInt();
155 sz.cy = va[1].ToInt();
156 if ( sz.cx == 0 || sz.cy == 0 )
157 {
158 return false;
159 }
160 //
161 if ( pa == "P2" || pa == "P3" || pa == "P5" || pa == "P6" )
162 {
163 // P2, P3, P5, P6 はカラー深さが存在
164 if ( params.GetSize() < 3 )
165 {
166 return false;
167 }
168 const char * pp = &contents[params[2].index];
169 colorDips = STRLIB::ToInt(pp);
170 }
171 if ( pa == "P1" || pa == "P2" || pa == "P3" )
172 {
173 // P1, P2, P3
174 int ex = (pa == "P1") ? 2 : 3;
176 loop ( i, params.GetSize() - ex )
177 {
178 a.SetFromLeft(&contents[params[i + ex].index], params[i + ex].size);
179 while ( a.Replace("\t", " ") != 0 );
180 while ( a.Replace(" ", " ") != 0 );
182 loop ( j, va )
183 {
184 bm.Add(va[j].ToInt());
185 }
186 }
187 if ( pa == "P1" )
188 {
189 // P1
190 if ( size_t(sz.cx * sz.cy) > bm.GetSize() )
191 {
192 return false;
193 }
194 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
195 m_bmp.ToHaveRgbData();
196 loop ( y, sz.cy )
197 {
198 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
199 int m = y * sz.cx;
200 loop ( x, sz.cx )
201 {
202 if ( bm[m + x] == 0 )
203 {
204 p->rgbRed = 255;
205 p->rgbGreen = 255;
206 p->rgbBlue = 255;
207 }
208 p++;
209 }
210 }
211 m_desc = P1;
212 return true;
213 }
214 else if ( pa == "P2" )
215 {
216 // P2
217 if ( size_t(sz.cx * sz.cy) > bm.GetSize() )
218 {
219 return false;
220 }
221 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
222 m_bmp.ToHaveRgbData();
223 loop ( y, sz.cy )
224 {
225 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
226 int m = y * sz.cx;
227 loop ( x, sz.cx )
228 {
229 BYTE c = static_cast<BYTE>(bm[m + x] * 255 / colorDips);
230 p->rgbRed = c;
231 p->rgbGreen = c;
232 p->rgbBlue = c;
233 p++;
234 }
235 }
236 m_desc = P2;
237 return true;
238 }
239 else // pa == "P3"
240 {
241 // P3
242 if ( size_t(sz.cx * sz.cy * 3) > bm.GetSize() )
243 {
244 return false;
245 }
246 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
247 m_bmp.ToHaveRgbData();
248 loop ( y, sz.cy )
249 {
250 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
251 int m = y * sz.cx * 3;
252 loop ( x, sz.cx )
253 {
254 p->rgbRed = static_cast<BYTE>(bm[m + x * 3 + 0] * 255 / colorDips);
255 p->rgbGreen = static_cast<BYTE>(bm[m + x * 3 + 1] * 255 / colorDips);
256 p->rgbBlue = static_cast<BYTE>(bm[m + x * 3 + 2] * 255 / colorDips);
257 p++;
258 }
259 }
260 m_desc = P3;
261 return true;
262 }
263 }
264 else if ( pa == "P4" || pa == "P5" || pa == "P6" )
265 {
266 int ex = (pa == "P4") ? 1 : 2;
267 const char* q0 = &contents[params[ex].index + params[ex].size];
268 size_t len = size - (params[ex].index + params[ex].size);
269 if ( *q0 == 0x0D || *q0 == 0x0A )
270 {
271 q0++;
272 len--;
273 //if ( *q0 == 0x0A )
274 //{
275 // q0++;
276 // len--;
277 //}
278 }
279 const BYTE* q = reinterpret_cast<const BYTE*>(q0);
280 if ( pa == "P4" )
281 {
282 // P4
283 if ( size_t(((sz.cx + 7 ) / 8) * sz.cy) > len )
284 {
285 return false;
286 }
287 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
288 m_bmp.ToHaveRgbData();
289 loop ( y, sz.cy )
290 {
291 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
292 int m = y * ((sz.cx + 7) / 8);
293 loop ( x, sz.cx )
294 {
295 if ( (q[m + (x / 8)] & _BIT(7 - (x & 7))) == 0 )
296 {
297 p->rgbRed = 255;
298 p->rgbGreen = 255;
299 p->rgbBlue = 255;
300 }
301 p++;
302 }
303 }
304 m_desc = P4;
305 return true;
306 }
307 else if ( pa == "P5" )
308 {
309 // P5
310 if ( size_t(sz.cx * sz.cy) > len )
311 {
312 return false;
313 }
314 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
315 m_bmp.ToHaveRgbData();
316 loop ( y, sz.cy )
317 {
318 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
319 int m = y * sz.cx;
320 loop ( x, sz.cx )
321 {
322 BYTE c = static_cast<BYTE>(q[m + x] * 255 / colorDips);
323 p->rgbRed = c;
324 p->rgbGreen = c;
325 p->rgbBlue = c;
326 p++;
327 }
328 }
329 m_desc = P5;
330 return true;
331 }
332 else // pa == "P6"
333 {
334 // P6
335 if ( size_t(sz.cx * sz.cy * 3) > len )
336 {
337 return false;
338 }
339 m_bmp.Set(sz.cx, sz.cy, RGB(0, 0, 0));
340 m_bmp.ToHaveRgbData();
341 loop ( y, sz.cy )
342 {
343 RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
344 int m = y * sz.cx * 3;
345 loop ( x, sz.cx )
346 {
347 p->rgbRed = static_cast<BYTE>(q[m + x * 3 + 0] * 255 / colorDips);
348 p->rgbGreen = static_cast<BYTE>(q[m + x * 3 + 1] * 255 / colorDips);
349 p->rgbBlue = static_cast<BYTE>(q[m + x * 3 + 2] * 255 / colorDips);
350 p++;
351 }
352 }
353 m_desc = P6;
354 return true;
355 }
356 }
357 else
358 {
359 return false;
360 }
361 return true;
362 }
363
371 bool Load(LPCTSTR lpszFileName)
372 {
373 CFileReader rr;
374 if ( rr.Open(lpszFileName) )
375 {
376 CByteVector vb = rr.ReadExactly();
377 return Set(vb.GetSize(), vb.ReferBuffer());
378 }
379 return false;
380 }
381
388 CByteVector ToVector(EDescriptor desc, DWORD prm, LPCTSTR lpszComment = NULL) const
389 {
390 CByteVector vb;
391 if ( ! m_bmp.IsEmpty() )
392 {
393 CAscii a;
394 CAscii asz;
395 SIZE sz = m_bmp.GetSize();
396 asz.Format("%d %d\n", sz.cx, sz.cy);
397 if ( lpszComment != NULL )
398 {
399 asz.Format("#%s\n%d %d\n", CAscii(lpszComment), sz.cx, sz.cy);
400 }
401 else
402 {
403 asz.Format("%d %d\n", sz.cx, sz.cy);
404 }
405 switch ( desc )
406 {
407 case P1:
408 {
410 a = "P1\n" + asz;
411 INDEX idx = 0;
412 loop ( y, sz.cy )
413 {
414 const RGBQUAD* p = bm.GetRgbDataPtr(y);
415 loop ( x, sz.cx )
416 {
417 if ( p->rgbRed < prm )
418 {
419 a += "1 ";
420 }
421 else
422 {
423 a += "0 ";
424 }
425 if ( idx++ >= 32 )
426 {
427 a.TrimRight(' ');
428 a += "\n";
429 idx = 0;
430 }
431 p++;
432 }
433 }
434 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
435 }
436 break;
437 case P2:
438 {
440 a = "P2\n" + asz + CAscii::Fmt("%d\n", prm);
441 INDEX idx = 0;
442 loop ( y, sz.cy )
443 {
444 const RGBQUAD* p = bm.GetRgbDataPtr(y);
445 loop ( x, sz.cx )
446 {
447 int q = p->rgbRed * prm / 255;
448 a += CAscii::Fmt("%d ", q);
449 if ( idx++ >= 32 )
450 {
451 a.TrimRight(' ');
452 a += "\n";
453 idx = 0;
454 }
455 p++;
456 }
457 }
458 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
459 }
460 break;
461 case P3:
462 {
463 a = "P3\n" + asz + CAscii::Fmt("%d\n", prm);
464 INDEX idx = 0;
465 loop ( y, sz.cy )
466 {
467 const RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
468 loop ( x, sz.cx )
469 {
470 int r = p->rgbRed * prm / 255;
471 int g = p->rgbGreen * prm / 255;
472 int b = p->rgbBlue * prm / 255;
473 a += CAscii::Fmt("%d %d %d ", r, g, b);
474 if ( idx++ >= 32 )
475 {
476 a.TrimRight(' ');
477 a += "\n";
478 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
479 a.Empty();
480 idx = 0;
481 }
482 p++;
483 }
484 }
485 if ( a.GetLength() > 0 )
486 {
487 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
488 }
489 }
490 break;
491 case P4:
492 {
494 a = "P4\n" + asz;
495 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
496 CByteVector v;
497 int yyy = (sz.cx + 7) / 8;
498 v.SetSize(sz.cy * yyy);
499 loop ( y, sz.cy )
500 {
501 const RGBQUAD* p = bm.GetRgbDataPtr(y);
502 loop ( x, sz.cx )
503 {
504 BYTE& b = v.Ref((y * yyy) + (x / 8));
505 if ( p->rgbRed < prm )
506 {
507 b |= _BIT(7 - (x & 7));
508 }
509 else
510 {
511 b &= ~(_BIT(7 - (x & 7)));
512 }
513 p++;
514 }
515 }
516 vb += v;
517 }
518 break;
519 case P5:
520 {
522 a = "P5\n" + asz + CAscii::Fmt("%d\n", prm);
523 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
524 loop ( y, sz.cy )
525 {
526 const RGBQUAD* p = bm.GetRgbDataPtr(y);
527 loop ( x, sz.cx )
528 {
529 int q = p->rgbRed * prm / 255;
530 vb.Add(static_cast<BYTE>(q));
531 p++;
532 }
533 }
534 }
535 break;
536 case P6:
537 {
538 a = "P6\n" + asz + CAscii::Fmt("%d\n", prm);
539 vb.AddElements(a.GetLength(), reinterpret_cast<const BYTE*>(a.ReferBuffer()));
540 loop ( y, sz.cy )
541 {
542 const RGBQUAD* p = m_bmp.GetRgbDataPtr(y);
543 loop ( x, sz.cx )
544 {
545 int r = p->rgbRed * prm / 255;
546 int g = p->rgbGreen * prm / 255;
547 int b = p->rgbBlue * prm / 255;
548 vb.Add(static_cast<BYTE>(r));
549 vb.Add(static_cast<BYTE>(g));
550 vb.Add(static_cast<BYTE>(b));
551 p++;
552 }
553 }
554 }
555 break;
556 }
557 }
558 return vb;
559 }
560
571 bool Save(LPCTSTR lpszFileName, EDescriptor desc, DWORD prm, LPCTSTR lpszComment = NULL) const
572 {
573 CByteVector vb = ToVector(desc, prm, lpszComment);
574 if ( vb.GetSize() > 0 )
575 {
576 return CFileWriter::NewFile(lpszFileName, vb.GetSize(), vb.ReferBuffer());
577 }
578 return false;
579 }
580
586 {
587 return m_bmp;
588 }
589
590private:
592 struct TParam
593 {
594 INDEX index;
595 size_t size;
596 // コンストラクタ.
597 TParam(INDEX i = 0, size_t s = 0) : index(i), size(s)
598 {
599 }
600 };
601
602 CBitmapImage m_bmp;
603 EDescriptor m_desc;
604};
605
606
607
608}; // TNB
ビットマップイメージ管理関係のヘッダ
配列型情報管理関係のヘッダ
#define _BIT(X)
BIT演算
Definition: TnbDef.h:307
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ファイル関係のヘッダ
文字列操作関係のヘッダ
ビットマップイメージ管理クラス
bool IsEmpty(void) const
[確認] Empty状態確認.
RGBQUAD * GetRgbDataPtr(INT_PTR y=-1)
[取得] RGBデータアドレス取得.
CBitmapImage CreateGrayscaleBitmap(void) const
[作成] グレイスケール画像作成.
const SIZE & GetSize(void) const
[取得] イメージサイズ取得.
bool Set(int cx, int cy, COLORREF color=CLR_INVALID)
[設定] イメージ設定.
bool ToHaveRgbData(void)
[設定] RGBデータ準備.
ビットマップポータブルフォーマットクラス.
EDescriptor GetLastDescriptor(void) const
[取得] 最終設定種類取得.
CByteVector ToVector(EDescriptor desc, DWORD prm, LPCTSTR lpszComment=NULL) const
[変換] バイナリ変換.
bool Save(LPCTSTR lpszFileName, EDescriptor desc, DWORD prm, LPCTSTR lpszComment=NULL) const
[保存] ファイル書き込み.
CBitmapImage & Bitmap(void)
[参照] 画像参照.
bool Set(size_t size, LPCVOID pData)
[設定] 設定.
bool Load(LPCTSTR lpszFileName)
[設定] ファイル読込み.
@ P6
Portable PixMap Binary (.PPM)
@ P1
Portable BitMap ASCII (.PBM)
@ P4
Portable BitMap Binary (.PBM)
@ P3
Portable PixMap ASCII (.PPM)
@ P2
Portable GrayMap ASCII (.PGM)
@ P5
Portable GrayMap Binary (.PGM)
virtual size_t GetSize(void) const
[取得] 要素数取得.
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
ファイル読み込みクラス
Definition: TnbFile.h:338
bool Open(LPCTSTR lpszName, bool boIsShare=true, bool boDummy=false)
[操作] オープン
Definition: TnbFile.h:364
static bool NewFile(LPCTSTR lpszFileName, size_t size, LPCVOID P, CFileWriter &fw=CFileWriter())
[保存] ファイル作成.
Definition: TnbFile.h:653
static CVectorT< CStrT< TYP > > SeparatePeriod(const TYP *lpsz, const TYP *lpszMark, bool isCheckDc=true)
[取得] トークン区切取得
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
const TYP * ReferBuffer(void) const
[取得] バッファ参照.
Definition: TnbStr.h:380
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
static CStrT Fmt(const char *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
CStrT & TrimRight(TYP t=' ')
[処理] 末尾から文字をトリム.
Definition: TnbStr.h:990
CStrT & SetFromLeft(const TYP *lpText, size_t iLen)
[代入] 文字数制限代入.
Definition: TnbStr.h:278
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
int Replace(TYP tOld, TYP tNew)
[処理] 文字置換.
Definition: TnbStr.h:1038
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:359
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
virtual bool SetSize(size_t size)
[操作] サイズ指定
Definition: TnbVector.h:618
virtual TYP & Ref(INDEX index)
[取得] 要素の参照取得.
Definition: TnbVector.h:246
virtual size_t AddElements(size_t size, const TYP *P=NULL)
[追加] 複数要素追加.
Definition: TnbVector.h:456
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
int GetCharSize(char c)
[取得] 文字のサイズ(ASCII/SJIS用)
Definition: TnbStrLib.h:341
TNB::CStrT< char > CAscii
ASCII文字列クラス
Definition: TnbStr.h:1758
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
void ReadExactly(size_t size, LPVOID _P) const
[取得] 読み込み.
Definition: TnbReader.h:114