1 /*$
2  Copyright (C) 2013-2020 Azel.
3 
4  This file is part of AzPainter.
5 
6  AzPainter is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  AzPainter is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 $*/
19 
20 /*****************************************
21  * BMP 読み込み関数
22  *****************************************/
23 
24 #include <string.h>
25 
26 #include "mDef.h"
27 #include "mLoadImage.h"
28 
29 #include "mIOFileBuf.h"
30 #include "mUtil.h"
31 
32 
33 //--------------------
34 
35 typedef struct
36 {
37 	mLoadImage *param;
38 
39 	mIOFileBuf *io;
40 	uint8_t *rawbuf,	//Y1行分の生バッファ
41 		*convbuf,		//変換後のバッファ
42 		*palbuf,		//パレットバッファ [R-G-B-A]
43 		*rlebuf,		//RLE 用バッファ
44 		*rlebuf_end,	//RLE バッファ終端位置
45 		*rlebuf_cur;	//RLE バッファ現在位置
46 
47 	int	bits,			//BMP ビット数 (1,4,8,16,24,32)
48 		palnum,			//パレット数
49 		compression,	//BMP圧縮タイプ
50 		maxR,maxG,maxB,maxA,	//16bit 各色の最大値
51 		convtype;		//イメージ変換タイプ
52 
53 	uint32_t maskR,maskG,maskB,maskA;	//各色のビットマスク (0 で常に 0。A の場合は 0 なら不透明)
54 	uint8_t shiftR,shiftG,shiftB,shiftA,
55 		morethan_ver4,	//ver4 以降か
56 		end_of_bmp,		//RLE で EOB が出現したか
57 		rle_eof;		//RLE ファイルの最後まで読み込んだか
58 }_LOADBMP;
59 
60 //--------------------
61 
62 #define BI_RGB        0
63 #define BI_RLE8       1
64 #define BI_RLE4       2
65 #define BI_BITFIELDS  3
66 
67 #define RET_OK        0
68 #define RET_ERR_NOMES -1  //メッセージはセット済み
69 
70 #define RLE_BUFSIZE   1024
71 
72 enum
73 {
74 	CONVTYPE_PALETTE,
75 	CONVTYPE_24BIT,
76 	CONVTYPE_32BIT_BGRA,
77 	CONVTYPE_BITFIELDS
78 };
79 
80 //--------------------
81 
82 
83 //=======================
84 // 読み込み
85 //=======================
86 
87 
88 /** ファイルヘッダ読み込み */
89 
_read_fileheader(_LOADBMP * p)90 static int _read_fileheader(_LOADBMP *p)
91 {
92 	uint8_t d[14];
93 	int size;
94 
95 	size = mIOFileBuf_read(p->io, d, 14);
96 
97 	//BMP ではない
98 
99 	if(size < 2 || d[0] != 'B' || d[1] != 'M')
100 	{
101 		mLoadImage_setMessage(p->param, "This is not BMP");
102 		return RET_ERR_NOMES;
103 	}
104 
105 	//データが足りない
106 
107 	if(size != 14)
108 		return MLOADIMAGE_ERR_CORRUPT;
109 
110 	return RET_OK;
111 }
112 
113 /** マスク値からシフト値と値の最大値取得 */
114 
_get_maskvalue(uint32_t mask,uint8_t * shift,int * max)115 static void _get_maskvalue(uint32_t mask,uint8_t *shift,int *max)
116 {
117 	if(mask == 0)
118 	{
119 		*shift = 0;
120 		*max = 0;
121 	}
122 	else
123 	{
124 		*shift = mGetBitOnPos(mask);
125 		*max = (1 << mGetBitOffPos(mask >> *shift)) - 1;
126 	}
127 }
128 
129 /** ビットフィールド読み込み/セット */
130 
_read_bitfield(_LOADBMP * p,int * readbytes)131 static int _read_bitfield(_LOADBMP *p,int *readbytes)
132 {
133 	uint8_t d[16];
134 	int size;
135 
136 	//RGBA マスク値
137 
138 	if(p->compression == BI_BITFIELDS)
139 	{
140 		//指定あり (V4 以降ならアルファ値のマスクもある)
141 
142 		size = (p->morethan_ver4)? 16: 12;
143 
144 		if(!mIOFileBuf_readSize(p->io, d, size))
145 			return MLOADIMAGE_ERR_CORRUPT;
146 
147 		p->maskR = mGetBuf32LE(d);
148 		p->maskG = mGetBuf32LE(d + 4);
149 		p->maskB = mGetBuf32LE(d + 8);
150 
151 		if(size == 16)
152 		{
153 			p->maskA = mGetBuf32LE(d + 12);
154 
155 			_get_maskvalue(p->maskA, &p->shiftA, &p->maxA);
156 		}
157 
158 		*readbytes = size;
159 	}
160 	else
161 	{
162 		//指定なし = デフォルト値 (アルファマスクなし)
163 
164 		if(p->bits == 16)
165 		{
166 			p->maskR = 0x7c00;
167 			p->maskG = 0x03e0;
168 			p->maskB = 0x001f;
169 		}
170 		else
171 		{
172 			p->maskR = 0xff0000;
173 			p->maskG = 0x00ff00;
174 			p->maskB = 0x0000ff;
175 		}
176 	}
177 
178 	//RGB 各パラメータ
179 
180 	_get_maskvalue(p->maskR, &p->shiftR, &p->maxR);
181 	_get_maskvalue(p->maskG, &p->shiftG, &p->maxG);
182 	_get_maskvalue(p->maskB, &p->shiftB, &p->maxB);
183 
184 	return RET_OK;
185 }
186 
187 /** 情報ヘッダ読み込み */
188 
_read_infoheader(_LOADBMP * p,mLoadImageInfo * info)189 static int _read_infoheader(_LOADBMP *p,mLoadImageInfo *info)
190 {
191 	uint8_t d[40];
192 	int width,height,n,readbytes;
193 	uint32_t headersize,clrused;
194 
195 	//読み込み
196 
197 	if(!mIOFileBuf_readSize(p->io, d, 40))
198 		return MLOADIMAGE_ERR_CORRUPT;
199 
200 	mConvertEndianBuf(d, -1, "44422444444");
201 
202 	//------ 基本情報
203 
204 	//ヘッダサイズ
205 
206 	headersize = M_BUF_UINT32(d);
207 	if(headersize < 40) return MLOADIMAGE_ERR_UNSUPPORTED;  //OS/2 は非対応
208 
209 	p->morethan_ver4 = (headersize >= 108);
210 
211 	//圧縮形式
212 
213 	n = p->compression = M_BUF_UINT32(d + 16);
214 
215 	if(n < 0 || n > BI_BITFIELDS)
216 		return MLOADIMAGE_ERR_UNSUPPORTED;
217 
218 	//幅・高さ
219 
220 	width  = M_BUF_UINT32(d + 4);
221 	height = M_BUF_UINT32(d + 8);
222 
223 	if(width <= 0 || height == 0)
224 		return MLOADIMAGE_ERR_INVALID_VALUE;
225 
226 	if(height < 0)
227 	{
228 		//トップダウン
229 		height = -height;
230 		info->bottomup = FALSE;
231 	}
232 	else
233 		info->bottomup = TRUE;
234 
235 	if((p->param->max_width > 0 && width > p->param->max_width)
236 		|| (p->param->max_height > 0 && height > p->param->max_height))
237 		return MLOADIMAGE_ERR_LARGE_SIZE;
238 
239 	info->width  = width;
240 	info->height = height;
241 
242 	//ビット数
243 
244 	n = M_BUF_UINT16(d + 14);
245 
246 	if(n != 1 && n != 4 && n != 8 && n != 16 && n != 24 && n != 32)
247 		return MLOADIMAGE_ERR_INVALID_VALUE;
248 
249 	p->bits = n;
250 
251 	//解像度
252 
253 	info->resolution_unit = MLOADIMAGE_RESOLITION_UNIT_DPM;
254 	info->resolution_horz = M_BUF_UINT32(d + 24);
255 	info->resolution_vert = M_BUF_UINT32(d + 28);
256 
257 	//パレット数
258 
259 	n = clrused = M_BUF_UINT32(d + 32);
260 
261 	if(p->bits >= 24)
262 		n = 0;
263 	else if(n == 0)
264 		n = 1 << p->bits;
265 	else if(n > (1 << p->bits))
266 		return MLOADIMAGE_ERR_INVALID_VALUE;
267 
268 	p->palnum = n;
269 
270 	//------- 他データ
271 
272 	//ビットフィールド
273 
274 	if(p->bits == 16 || p->bits == 32)
275 	{
276 		if((n = _read_bitfield(p, &readbytes)))
277 			return n;
278 	}
279 
280 	//次の位置へ (パレット or イメージ)
281 
282 	n = headersize - 40;
283 	if(p->compression == BI_BITFIELDS) n -= readbytes;
284 
285 	mIOFileBuf_readEmpty(p->io, n);
286 
287 	//16bit 以上の場合、カラーテーブルをスキップ
288 
289 	if(p->bits >= 16 && clrused)
290 	{
291 		if(!mIOFileBuf_readEmpty(p->io, clrused << 2))
292 			return MLOADIMAGE_ERR_CORRUPT;
293 	}
294 
295 	//------- 情報セット
296 
297 	info->sample_bits = 8;
298 	info->raw_sample_bits = 8;
299 	info->raw_bits = p->bits;
300 	info->raw_pitch = (((info->width * p->bits + 7) >> 3) + 3) & (~3);
301 
302 	//カラータイプ
303 
304 	if(p->bits <= 8)
305 		info->raw_coltype = MLOADIMAGE_COLTYPE_PALETTE;
306 	else if(p->maskA)
307 		info->raw_coltype = MLOADIMAGE_COLTYPE_RGBA;
308 	else
309 		info->raw_coltype = MLOADIMAGE_COLTYPE_RGB;
310 
311 	//イメージ変換タイプ
312 
313 	if(p->bits <= 8)
314 		p->convtype = CONVTYPE_PALETTE;
315 	else if(p->bits == 24)
316 		p->convtype = CONVTYPE_24BIT;
317 	else if(p->bits == 32
318 		&& p->maskR == 0xff0000 && p->maskG == 0x00ff00 && p->maskB == 0x0000ff)
319 		p->convtype = CONVTYPE_32BIT_BGRA;
320 	else
321 		p->convtype = CONVTYPE_BITFIELDS;
322 
323 	return RET_OK;
324 }
325 
326 /** パレット読み込み */
327 
_read_palette(_LOADBMP * p)328 static int _read_palette(_LOADBMP *p)
329 {
330 	int i,size;
331 	uint8_t *ppal,tmp;
332 
333 	size = p->palnum << 2;
334 
335 	//確保
336 
337 	p->palbuf = (uint8_t *)mMalloc(size, FALSE);
338 	if(!p->palbuf) return MLOADIMAGE_ERR_ALLOC;
339 
340 	//読み込み
341 
342 	if(!mIOFileBuf_readSize(p->io, p->palbuf, size))
343 		return MLOADIMAGE_ERR_CORRUPT;
344 
345 	//RGB 順入れ替え (BGRA => RGBA)
346 
347 	ppal = p->palbuf;
348 
349 	for(i = p->palnum; i > 0; i--, ppal += 4)
350 	{
351 		tmp = ppal[0];
352 		ppal[0] = ppal[2];
353 		ppal[2] = tmp;
354 		ppal[3] = 255;
355 	}
356 
357 	return RET_OK;
358 }
359 
360 
361 //===========================
362 // RLE 展開
363 //===========================
364 
365 
366 /** RLE バッファに読み込み */
367 
_read_to_rlebuf(_LOADBMP * p)368 static int _read_to_rlebuf(_LOADBMP *p)
369 {
370 	int remain,read;
371 
372 	remain = p->rlebuf_end - p->rlebuf_cur;
373 
374 	if(p->rle_eof)
375 	{
376 		//ファイルの最後まで読み込んだ
377 
378 		return (remain < 2)? MLOADIMAGE_ERR_CORRUPT: RET_OK;
379 	}
380 	else
381 	{
382 		//残りが 258byte 未満なら読み込み
383 		/* 非連続データの最大が 258byte なので、最大サイズ分を読み込んでおく */
384 
385 		if(remain < 258)
386 		{
387 			memmove(p->rlebuf, p->rlebuf_cur, remain);
388 
389 			read = mIOFileBuf_read(p->io, p->rlebuf + remain, RLE_BUFSIZE - remain);
390 
391 			if(read < RLE_BUFSIZE - remain)
392 				p->rle_eof = TRUE;
393 
394 			remain += read;
395 			if(remain < 2) return MLOADIMAGE_ERR_CORRUPT;
396 
397 			p->rlebuf_end = p->rlebuf + remain;
398 			p->rlebuf_cur = p->rlebuf;
399 		}
400 
401 		return RET_OK;
402 	}
403 }
404 
405 /** RLE 展開 (4bit) */
406 
_decompress_rle4(_LOADBMP * p)407 static int _decompress_rle4(_LOADBMP *p)
408 {
409 	uint8_t *pd,*ps,b1,b2,val;
410 	int ret,width,x = 0,len,bytes,bytes_wd;
411 
412 	pd = p->rawbuf;
413 	width = (p->param->info.width + 1) & (~1);  //奇数幅での +1px は許容
414 
415 	while(1)
416 	{
417 		//読み込み
418 
419 		ret = _read_to_rlebuf(p);
420 		if(ret) return ret;
421 
422 		//2byte データ
423 
424 		b1 = p->rlebuf_cur[0];
425 		b2 = p->rlebuf_cur[1];
426 		p->rlebuf_cur += 2;
427 
428 		//
429 
430 		if(b1 != 0)
431 		{
432 			//---- 連続データ ([1-255] + データ)
433 
434 			len = b1;
435 			if(x + len > width) return MLOADIMAGE_ERR_DECODE;
436 
437 			//出力位置が下位4bitの場合
438 
439 			if(x & 1)
440 			{
441 				*(pd++) |= b2 >> 4;
442 				b2 = (b2 >> 4) | ((b2 & 15) << 4);
443 				len--;
444 			}
445 
446 			//2px単位で出力
447 
448 			for(; len > 0; len -= 2)
449 				*(pd++) = b2;
450 
451 			//余分に出力した場合は 1px 戻る
452 
453 			if(len == -1)
454 				*(--pd) &= 0xf0;
455 
456 			x += b1;
457 		}
458 		else if(b2 == 0 || b2 == 1)
459 		{
460 			//行終わり (0 + 0) or イメージ終わり (0 + 1)
461 
462 			memset(pd, 0, p->param->info.raw_pitch - (x + 1) / 2);
463 			if(b2 == 1) p->end_of_bmp = TRUE;
464 
465 			break;
466 		}
467 		else if(b2 == 2)
468 			//位置移動 (0 + 2) は非対応
469 			return MLOADIMAGE_ERR_UNSUPPORTED;
470 		else
471 		{
472 			//----- 非連続データ (0 + [3-255] + データxlen)
473 
474 			len = b2;
475 			bytes = (len + 1) >> 1;
476 			bytes_wd = (bytes + 1) & (~1);  //データは2byte境界
477 
478 			if(x + len > width) return MLOADIMAGE_ERR_DECODE;
479 
480 			if(p->rlebuf_end - p->rlebuf_cur < bytes_wd)
481 				return MLOADIMAGE_ERR_CORRUPT;
482 
483 			ps = p->rlebuf_cur;
484 
485 			if(x & 1)
486 			{
487 				//出力先の先頭が下位4bit
488 
489 				for(; len > 0; len -= 2)
490 				{
491 					val = *(ps++);
492 
493 					*(pd++) |= val >> 4;
494 					if(len != 1) *pd = (val & 15) << 4;
495 				}
496 			}
497 			else
498 			{
499 				//先頭が上位4bit
500 
501 				memcpy(pd, ps, bytes);
502 
503 				pd += bytes;
504 
505 				if(len & 1)
506 					*(--pd) &= 0xf0;
507 			}
508 
509 			x += b2;
510 			p->rlebuf_cur += bytes_wd;
511 		}
512 	}
513 
514 	return RET_OK;
515 }
516 
517 /** RLE 展開 (8bit) */
518 
_decompress_rle8(_LOADBMP * p)519 static int _decompress_rle8(_LOADBMP *p)
520 {
521 	uint8_t *pd,b1,b2;
522 	int ret,width,x = 0,bytes_wd;
523 
524 	pd = p->rawbuf;
525 	width = p->param->info.width;
526 
527 	while(1)
528 	{
529 		//読み込み
530 
531 		ret = _read_to_rlebuf(p);
532 		if(ret) return ret;
533 
534 		//2byte データ
535 
536 		b1 = p->rlebuf_cur[0];
537 		b2 = p->rlebuf_cur[1];
538 		p->rlebuf_cur += 2;
539 
540 		//
541 
542 		if(b1 != 0)
543 		{
544 			//連続データ
545 
546 			if(x + b1 > width) return MLOADIMAGE_ERR_DECODE;
547 
548 			memset(pd, b2, b1);
549 
550 			pd += b1;
551 			x += b1;
552 		}
553 		else if(b2 == 0 || b2 == 1)
554 		{
555 			//行終わり (0 + 0) or イメージ終わり (0 + 1)
556 
557 			memset(pd, 0, p->param->info.raw_pitch - x);
558 			if(b2 == 1) p->end_of_bmp = TRUE;
559 
560 			break;
561 		}
562 		else if(b2 == 2)
563 			//位置移動 (0 + 2) は非対応
564 			return MLOADIMAGE_ERR_UNSUPPORTED;
565 		else
566 		{
567 			//----- 非連続データ (0 + [3-255] + データxlen)
568 
569 			if(x + b2 > width) return MLOADIMAGE_ERR_DECODE;
570 
571 			bytes_wd = (b2 + 1) & (~1);
572 
573 			if(p->rlebuf_end - p->rlebuf_cur < bytes_wd)
574 				return MLOADIMAGE_ERR_CORRUPT;
575 
576 			memcpy(pd, p->rlebuf_cur, b2);
577 
578 			p->rlebuf_cur += bytes_wd;
579 
580 			pd += b2;
581 			x += b2;
582 		}
583 	}
584 
585 	return RET_OK;
586 }
587 
588 
589 //=======================
590 // sub
591 //=======================
592 
593 
594 /** イメージ変換 */
595 
_convert_image(_LOADBMP * p)596 static void _convert_image(_LOADBMP *p)
597 {
598 	int i,n,bits,shift,mask,convtype;
599 	uint32_t c;
600 	uint8_t *ps,*pd,*ppal,r,g,b,a;
601 	mBool to_rgba;
602 
603 	bits = p->bits;
604 	convtype = p->convtype;
605 	to_rgba = (p->param->format == MLOADIMAGE_FORMAT_RGBA);
606 
607 	ps = p->rawbuf;
608 	pd = p->convbuf;
609 
610 	if(bits <= 8)
611 	{
612 		shift = 8 - bits;
613 		mask = (1 << bits) - 1;
614 	}
615 
616 	//変換
617 
618 	for(i = p->param->info.width; i > 0; i--)
619 	{
620 		r = g = b = 0;
621 		a = 255;
622 
623 		switch(convtype)
624 		{
625 			//24bit (B-G-R)
626 			case CONVTYPE_24BIT:
627 				r = ps[2];
628 				g = ps[1];
629 				b = ps[0];
630 
631 				ps += 3;
632 				break;
633 			//32bit (B-G-R-A)
634 			case CONVTYPE_32BIT_BGRA:
635 				r = ps[2];
636 				g = ps[1];
637 				b = ps[0];
638 				if(p->maskA) a = ps[3];
639 
640 				ps += 4;
641 				break;
642 			//16bit/32bit (bitfield)
643 			case CONVTYPE_BITFIELDS:
644 				if(bits == 32)
645 				{
646 					c = ((uint32_t)ps[3] << 24) | (ps[2] << 16) | (ps[1] << 8) | ps[0];
647 					ps += 4;
648 				}
649 				else
650 				{
651 					c = (ps[1] << 8) | ps[0];
652 					ps += 2;
653 				}
654 
655 				if(p->maskR) r = ((c & p->maskR) >> p->shiftR) * 255 / p->maxR;
656 				if(p->maskG) g = ((c & p->maskG) >> p->shiftG) * 255 / p->maxG;
657 				if(p->maskB) b = ((c & p->maskB) >> p->shiftB) * 255 / p->maxB;
658 				if(p->maskA) a = ((c & p->maskA) >> p->shiftA) * 255 / p->maxA;
659 				break;
660 			//パレットカラー
661 			default:
662 				n = (*ps >> shift) & mask;
663 				if(n >= p->palnum) n = 0;
664 
665 				ppal = p->palbuf + (n << 2);
666 
667 				r = ppal[0];
668 				g = ppal[1];
669 				b = ppal[2];
670 
671 				shift -= bits;
672 				if(shift < 0)
673 				{
674 					shift = 8 - bits;
675 					ps++;
676 				}
677 				break;
678 		}
679 
680 		//セット
681 
682 		pd[0] = r;
683 		pd[1] = g;
684 		pd[2] = b;
685 
686 		if(to_rgba)
687 		{
688 			pd[3] = a;
689 			pd += 4;
690 		}
691 		else
692 			pd += 3;
693 	}
694 }
695 
696 /** イメージまでの情報読み込み */
697 
_read_headers(_LOADBMP * p)698 static int _read_headers(_LOADBMP *p)
699 {
700 	int ret;
701 
702 	//開く
703 
704 	p->io = mLoadImage_openIOFileBuf(&p->param->src);
705 	if(!p->io) return MLOADIMAGE_ERR_OPENFILE;
706 
707 	//ファイルヘッダ
708 
709 	if((ret = _read_fileheader(p)))
710 		return ret;
711 
712 	//情報ヘッダ
713 
714 	if((ret = _read_infoheader(p, &p->param->info)))
715 		return ret;
716 
717 	//パレット
718 
719 	if(p->bits <= 8)
720 	{
721 		if((ret = _read_palette(p)))
722 			return ret;
723 
724 		p->param->info.palette_num = p->palnum;
725 		p->param->info.palette_buf = p->palbuf;
726 	}
727 
728 	return RET_OK;
729 }
730 
731 /** 作業用メモリ確保 */
732 
_alloc_buf(_LOADBMP * p,mLoadImage * param)733 static int _alloc_buf(_LOADBMP *p,mLoadImage *param)
734 {
735 	//Y1行、生データ
736 
737 	p->rawbuf = (uint8_t *)mMalloc(param->info.raw_pitch, FALSE);
738 	if(!p->rawbuf) return MLOADIMAGE_ERR_ALLOC;
739 
740 	//Y1行、変換後データ
741 
742 	if(param->format != MLOADIMAGE_FORMAT_RAW)
743 	{
744 		p->convbuf = (uint8_t *)mMalloc(mLoadImage_getPitch(param), FALSE);
745 		if(!p->convbuf) return MLOADIMAGE_ERR_ALLOC;
746 	}
747 
748 	//RLE 用
749 
750 	if(p->compression == BI_RLE4 || p->compression == BI_RLE8)
751 	{
752 		p->rlebuf = (uint8_t *)mMalloc(RLE_BUFSIZE, FALSE);
753 		if(!p->rlebuf) return MLOADIMAGE_ERR_ALLOC;
754 
755 		p->rlebuf_end = p->rlebuf_cur = p->rlebuf;
756 	}
757 
758 	return RET_OK;
759 }
760 
761 /** メイン処理 */
762 
_main_proc(_LOADBMP * p)763 static int _main_proc(_LOADBMP *p)
764 {
765 	int ret,i,pitch_dst,pitch_raw,rle;
766 	mLoadImage *param = p->param;
767 
768 	//ヘッダ部分読み込み
769 
770 	if((ret = _read_headers(p)))
771 		return ret;
772 
773 	//メモリ確保
774 
775 	if((ret = _alloc_buf(p, param)))
776 		return ret;
777 
778 	//getinfo()
779 
780 	if(param->getinfo)
781 	{
782 		if((ret = (param->getinfo)(param, &param->info)))
783 			return (ret < 0)? RET_ERR_NOMES: ret;
784 	}
785 
786 	//イメージ読み込み
787 
788 	pitch_raw = param->info.raw_pitch;
789 	pitch_dst = mLoadImage_getPitch(param);
790 
791 	rle = (p->compression == BI_RLE4 || p->compression == BI_RLE8);
792 
793 	for(i = param->info.height; i > 0; i--)
794 	{
795 		//p->rawbuf に生データ読み込み
796 
797 		if(rle)
798 		{
799 			//RLE 圧縮
800 
801 			if(p->end_of_bmp)
802 				memset(p->rawbuf, 0, pitch_raw);
803 			else
804 			{
805 				if(p->compression == BI_RLE4)
806 					ret = _decompress_rle4(p);
807 				else
808 					ret = _decompress_rle8(p);
809 
810 				if(ret) return ret;
811 			}
812 		}
813 		else
814 		{
815 			//無圧縮
816 
817 			if(!mIOFileBuf_readSize(p->io, p->rawbuf, pitch_raw))
818 				return MLOADIMAGE_ERR_CORRUPT;
819 		}
820 
821 		//getrow()
822 
823 		if(param->format == MLOADIMAGE_FORMAT_RAW)
824 			ret = (param->getrow)(param, p->rawbuf, pitch_dst);
825 		else
826 		{
827 			_convert_image(p);
828 
829 			ret = (param->getrow)(param, p->convbuf, pitch_dst);
830 		}
831 
832 		if(ret)
833 			return (ret < 0)? RET_ERR_NOMES: ret;
834 	}
835 
836 	return RET_OK;
837 }
838 
839 
840 //========================
841 // main
842 //========================
843 
844 
845 /** BMP 読み込み
846  *
847  * @ingroup loadimage */
848 
mLoadImageBMP(mLoadImage * param)849 mBool mLoadImageBMP(mLoadImage *param)
850 {
851 	_LOADBMP *p;
852 	int ret;
853 
854 	//確保
855 
856 	p = (_LOADBMP *)mMalloc(sizeof(_LOADBMP), TRUE);
857 	if(!p) return FALSE;
858 
859 	p->param = param;
860 
861 	//処理
862 
863 	ret = _main_proc(p);
864 
865 	if(ret != RET_OK)
866 	{
867 		if(ret == RET_ERR_NOMES)
868 		{
869 			if(!param->message)
870 				mLoadImage_setMessage(param, "error");
871 		}
872 		else
873 			mLoadImage_setMessage_errno(param, ret);
874 	}
875 
876 	//解放
877 
878 	mIOFileBuf_close(p->io);
879 
880 	mFree(p->rawbuf);
881 	mFree(p->convbuf);
882 	mFree(p->palbuf);
883 	mFree(p->rlebuf);
884 	mFree(p);
885 
886 	return (ret == RET_OK);
887 }
888 
889