1 /*$
2  Copyright (C) 2016-2020 Azel.
3 
4  This file is part of AzPainterB.
5 
6  AzPainterB 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  AzPainterB 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  * PSD 読み書き
22  *****************************************/
23 
24 #include <string.h>
25 
26 #include "mDef.h"
27 #include "mPopupProgress.h"
28 #include "mPSDLoad.h"
29 #include "mPSDSave.h"
30 #include "mUtilFile.h"
31 
32 #include "defMacros.h"
33 #include "defDraw.h"
34 #include "defConfig.h"
35 
36 #include "TileImage.h"
37 #include "LayerList.h"
38 #include "LayerItem.h"
39 #include "ImageBuf24.h"
40 
41 #include "draw_main.h"
42 
43 
44 //--------------------
45 
46 enum
47 {
48 	_TYPE_RGB = 1,
49 	_TYPE_GRAY,
50 	_TYPE_MONO
51 };
52 
53 #define _TOGRAY(r,g,b)  ((r * 77 + g * 150 + b * 29) >> 8)
54 
55 //--------------------
56 
57 static const uint32_t g_blendmode[] = {
58 	MPSD_BLENDMODE_NORMAL, MPSD_BLENDMODE_MULTIPLY, MPSD_BLENDMODE_LINEAR_DODGE,
59 	MPSD_BLENDMODE_SUBTRACT, MPSD_BLENDMODE_SCREEN, MPSD_BLENDMODE_OVERLAY,
60 	MPSD_BLENDMODE_HARD_LIGHT, MPSD_BLENDMODE_SOFT_LIGHT, MPSD_BLENDMODE_DODGE,
61 	MPSD_BLENDMODE_BURN, MPSD_BLENDMODE_LINEAR_BURN, MPSD_BLENDMODE_VIVID_LIGHT,
62 	MPSD_BLENDMODE_LINEAR_LIGHT, MPSD_BLENDMODE_PIN_LIGHT, MPSD_BLENDMODE_DARKEN,
63 	MPSD_BLENDMODE_LIGHTEN, MPSD_BLENDMODE_DIFFERENCE, 0
64 };
65 
66 //--------------------
67 
68 
69 //=============================
70 // 読み込み
71 //=============================
72 
73 
74 /** レイヤ読み込み - チャンネルを読み込み、バッファにセット */
75 
_load_layer_image_channel(mPSDLoad * psd,mBox * boximg,mPopupProgress * prog,uint8_t * dstbuf)76 static mBool _load_layer_image_channel(mPSDLoad *psd,mBox *boximg,mPopupProgress *prog,uint8_t *dstbuf)
77 {
78 	int i,w;
79 	uint8_t *ps;
80 
81 	w = boximg->w;
82 	ps = mPSDLoad_getLineImageBuf(psd);
83 
84 	for(i = boximg->h; i > 0; i--)
85 	{
86 		if(!mPSDLoad_readLayerImageChannelLine(psd))
87 			return FALSE;
88 
89 		memcpy(dstbuf, ps, w);
90 		dstbuf += w;
91 
92 		mPopupProgressThreadIncSubStep(prog);
93 	}
94 
95 	return TRUE;
96 }
97 
98 /** レイヤ読み込み - アルファ値読み込み
99  *
100  * @return FALSE 時は、psd->err にエラー番号を入れておく */
101 
_load_layer_image_alpha(mPSDLoad * psd,TileImage * img,mPSDLoadLayerInfo * info,mPopupProgress * prog,uint8_t * buf)102 static mBool _load_layer_image_alpha(mPSDLoad *psd,
103 	TileImage *img,mPSDLoadLayerInfo *info,mPopupProgress *prog,uint8_t *buf)
104 {
105 	uint8_t *ps,*pd;
106 	int ret,ix,iy;
107 	mBox box;
108 
109 	box = info->box_img;
110 
111 	//アルファチャンネルを buf にセット
112 
113 	ret = mPSDLoad_beginLayerImageChannel(psd, MPSD_CHANNEL_ID_ALPHA);
114 	if(!ret) return FALSE;
115 
116 	if(ret == -1)
117 	{
118 		//チャンネルがない場合はすべて不透明
119 
120 		memset(buf, 255, box.w * box.h);
121 		mPopupProgressThreadAddPos(prog, 4);
122 	}
123 	else
124 	{
125 		//読み込み
126 
127 		mPopupProgressThreadBeginSubStep(prog, 4, box.h);
128 
129 		if(!_load_layer_image_channel(psd, &box, prog, buf))
130 			return FALSE;
131 	}
132 
133 	//レイヤマスクがある場合、アルファ値に適用
134 
135 	if(!(info->layermask_flags & MPSDLOAD_LAYERMASK_F_DISABLE))
136 	{
137 		ret = mPSDLoad_beginLayerImageChannel(psd, MPSD_CHANNEL_ID_MASK);
138 		if(!ret) return FALSE;
139 
140 		if(ret != -1)
141 		{
142 			pd = buf;
143 
144 			for(iy = box.h; iy > 0; iy--)
145 			{
146 				if(!mPSDLoad_readLayerImageChannelLine_mask(psd))
147 					return FALSE;
148 
149 				ps = mPSDLoad_getLineImageBuf(psd);
150 
151 				for(ix = box.w; ix > 0; ix--, ps++, pd++)
152 				{
153 					if(*pd > *ps) *pd = *ps;
154 				}
155 			}
156 		}
157 	}
158 
159 	//アルファ値セット
160 
161 	if(TileImage_setChannelImage(img, buf, 3, box.w, box.h, FALSE))
162 		return TRUE;
163 	else
164 	{
165 		psd->err = MPSDLOAD_ERR_ALLOC;
166 		return FALSE;
167 	}
168 }
169 
170 /** レイヤ読み込み - イメージ */
171 
_load_layer_image(DrawData * p,mPSDLoad * psd,mPopupProgress * prog)172 static int _load_layer_image(DrawData *p,mPSDLoad *psd,mPopupProgress *prog)
173 {
174 	mPSDLoadLayerInfo info;
175 	LayerItem *item;
176 	TileImage *img;
177 	uint8_t *allocbuf = NULL,*buf;
178 	mSize size;
179 	int i,chnum,ret;
180 
181 	chnum = (psd->colmode == MPSD_COLMODE_GRAYSCALE)? 1: 3;
182 
183 	//1チャンネル分のバッファ確保
184 	//(blendimg のバッファで足りるならそちらを使う)
185 
186 	mPSDLoad_getLayerImageMaxSize(psd, &size);
187 
188 	if(size.w * size.h <= p->imgw * p->imgh * 3)
189 		buf = (uint8_t *)p->blendimg->buf;
190 	else
191 	{
192 		buf = allocbuf = (uint8_t *)mMalloc(size.w * size.h, FALSE);
193 		if(!allocbuf) return MPSDLOAD_ERR_ALLOC;
194 	}
195 
196 	//---- 各レイヤ読み込み
197 	/* ファイルの格納順に読み込むので、
198 	 * 一覧上において下から順にイメージのあるレイヤを読み込み。 */
199 
200 	mPopupProgressThreadSetMax(prog,
201 		LayerList_getNormalLayerNum(p->layerlist) * 16);
202 
203 	item = LayerList_getItem_bottomNormal(p->layerlist);
204 
205 	for(; item; item = LayerItem_getPrevNormal(item))
206 	{
207 		//読み込み開始
208 
209 		if(!mPSDLoad_beginLayerImage(psd, &info, TRUE))
210 		{
211 			//空イメージ
212 
213 			mPSDLoad_endLayerImage(psd);
214 			mPopupProgressThreadAddPos(prog, 16);
215 			continue;
216 		}
217 
218 		img = item->img;
219 
220 		//A チャンネルを先に読み込み
221 
222 		if(!_load_layer_image_alpha(psd, img, &info, prog, buf))
223 			goto ERR;
224 
225 		//色チャンネル読み込み
226 
227 		for(i = 0; i < chnum; i++)
228 		{
229 			//開始
230 
231 			ret = mPSDLoad_beginLayerImageChannel(psd, i);
232 			if(!ret)
233 				goto ERR;
234 			else if(ret == -1)
235 			{
236 				mPopupProgressThreadAddPos(prog, 4);
237 				continue;
238 			}
239 
240 			//buf に読み込み
241 
242 			mPopupProgressThreadBeginSubStep(prog, (chnum == 1)? 12: 4, info.box_img.h);
243 
244 			if(!_load_layer_image_channel(psd, &info.box_img, prog, buf))
245 				goto ERR;
246 
247 			//セット
248 
249 			TileImage_setChannelImage(img, buf, i,
250 				info.box_img.w, info.box_img.h, (i == 0 && chnum == 1));
251 		}
252 
253 		mPSDLoad_endLayerImage(psd);
254 	}
255 
256 	mFree(allocbuf);
257 
258 	return MPSDLOAD_ERR_OK;
259 
260 ERR:
261 	mFree(allocbuf);
262 	return psd->err;
263 }
264 
265 /** レイヤ読み込み */
266 
_load_from_layer(DrawData * p,mPSDLoad * psd,mPopupProgress * prog)267 static int _load_from_layer(DrawData *p,mPSDLoad *psd,mPopupProgress *prog)
268 {
269 	mPSDLoadLayerInfo info;
270 	TileImageInfo tinfo;
271 	LayerItem *item,*item_parent;
272 	TileImage *img;
273 	int layerno,i;
274 
275 	//------ レイヤ作成
276 
277 	item_parent = NULL;
278 
279 	//グループレイヤ構造を維持するため、一覧上において上から順に作成する
280 
281 	for(layerno = psd->layernum - 1; layerno >= 0; layerno--)
282 	{
283 		if(!mPSDLoad_getLayerInfo(psd, layerno, &info))
284 			return psd->err;
285 
286 		//フォルダ終了
287 
288 		if(info.group == MPSDLOAD_LAYERGROUP_END)
289 		{
290 			if(item_parent) item_parent = LAYERITEM(item_parent->i.parent);
291 			continue;
292 		}
293 
294 		//レイヤ作成
295 
296 		item = LayerList_addLayer(p->layerlist, NULL);
297 		if(!item) return MPSDLOAD_ERR_ALLOC;
298 
299 		//位置移動 (親の最後に)
300 
301 		LayerList_moveitem_forLoad_topdown(p->layerlist, item, item_parent);
302 
303 		//名前 (UTF-8 とみなす)
304 
305 		LayerList_setItemName_utf8(p->layerlist, item, info.name);
306 
307 		//不透明度
308 
309 		item->opacity = (int)(info.opacity / 255.0 * 128.0 + 0.5);
310 
311 		//非表示
312 
313 		if(info.flags & MPSDLOAD_LAYERINFO_F_HIDE)
314 			item->flags &= ~LAYERITEM_F_VISIBLE;
315 
316 		//フォルダ
317 
318 		if(info.group == MPSDLOAD_LAYERGROUP_EXPAND
319 			|| info.group == MPSDLOAD_LAYERGROUP_FOLDED)
320 		{
321 			item_parent = item;
322 			item->flags |= LAYERITEM_F_FOLDER_EXPAND;
323 			continue;
324 		}
325 
326 		//イメージ作成
327 
328 		if(info.box_img.w == 0 || info.box_img.h == 0)
329 		{
330 			//空イメージ
331 			tinfo.offx = tinfo.offy = 0;
332 			tinfo.tilew = tinfo.tileh = 1;
333 		}
334 		else
335 		{
336 			tinfo.offx = info.box_img.x;
337 			tinfo.offy = info.box_img.y;
338 			tinfo.tilew = (info.box_img.w + 63) / 64;
339 			tinfo.tileh = (info.box_img.h + 63) / 64;
340 		}
341 
342 		img = TileImage_newFromInfo(TILEIMAGE_COLTYPE_RGBA, &tinfo);
343 		if(!img) return MPSDLOAD_ERR_ALLOC;
344 
345 		item->img = img;
346 
347 		//合成モード
348 
349 		for(i = 0; g_blendmode[i]; i++)
350 		{
351 			if(g_blendmode[i] == info.blendmode)
352 			{
353 				item->blendmode = i;
354 				break;
355 			}
356 		}
357 	}
358 
359 	//------ イメージ読み込み
360 
361 	return _load_layer_image(p, psd, prog);
362 }
363 
364 /** 一枚絵イメージから読み込み */
365 
_load_from_image(DrawData * p,mPSDLoad * psd,mPopupProgress * prog)366 static int _load_from_image(DrawData *p,mPSDLoad *psd,mPopupProgress *prog)
367 {
368 	LayerItem *item;
369 	TileImage *img;
370 	int type,i,ix,iy,w,h,chnum;
371 	uint8_t *ps,*pd,f;
372 	PixelRGBA pix;
373 
374 	w = psd->width;
375 	h = psd->height;
376 
377 	//カラータイプ
378 
379 	if(psd->bits == 1)
380 		type = _TYPE_MONO;
381 	else if(psd->colmode == MPSD_COLMODE_GRAYSCALE)
382 		type = _TYPE_GRAY;
383 	else if(psd->colmode == MPSD_COLMODE_RGB && psd->img_channels >= 3)
384 		type = _TYPE_RGB;
385 	else
386 		return MPSDLOAD_ERR_UNSUPPORTED;
387 
388 	//レイヤ作成
389 
390 	item = LayerList_addLayer(p->layerlist, NULL);
391 	if(!item) return MPSDLOAD_ERR_ALLOC;
392 
393 	img = TileImage_new(TILEIMAGE_COLTYPE_RGBA, w, h);
394 	if(!img) return MPSDLOAD_ERR_ALLOC;
395 
396 	item->img = img;
397 
398 	LayerList_setItemName_byNum(p->layerlist, item);
399 
400 	//------- イメージ
401 
402 	if(!mPSDLoad_beginImage(psd)) goto PSDERR;
403 
404 	//mono or gray
405 
406 	if(type != _TYPE_RGB)
407 	{
408 		mPopupProgressThreadSetMax(prog, 40);
409 		mPopupProgressThreadBeginSubStep(prog, 20, h);
410 
411 		if(!mPSDLoad_beginImageChannel(psd)) goto PSDERR;
412 	}
413 
414 	//
415 
416 	switch(type)
417 	{
418 		//1bit (blendimg に 8bit イメージをセット)
419 		case _TYPE_MONO:
420 			pd = p->blendimg->buf;
421 
422 			for(iy = h; iy; iy--)
423 			{
424 				if(!mPSDLoad_readImageChannelLine(psd)) goto PSDERR;
425 
426 				ps = mPSDLoad_getLineImageBuf(psd);
427 
428 				for(ix = w, f = 0x80; ix; ix--)
429 				{
430 					*(pd++) = (*ps & f)? 0: 255;
431 
432 					f >>= 1;
433 					if(f == 0) f = 0x80, ps++;
434 				}
435 
436 				mPopupProgressThreadIncSubStep(prog);
437 			}
438 			break;
439 
440 		//グレイスケール (blendimg に 8bit イメージをセット)
441 		case _TYPE_GRAY:
442 			pd = p->blendimg->buf;
443 
444 			for(iy = h; iy; iy--)
445 			{
446 				if(!mPSDLoad_readImageChannelLine(psd)) goto PSDERR;
447 
448 				memcpy(pd, mPSDLoad_getLineImageBuf(psd), w);
449 
450 				pd += w;
451 
452 				mPopupProgressThreadIncSubStep(prog);
453 			}
454 			break;
455 
456 		//RGB or RGBA
457 		case _TYPE_RGB:
458 			chnum = psd->img_channels;
459 			if(chnum > 4) chnum = 4;
460 
461 			mPopupProgressThreadSetMax(prog, chnum * 10 + 20);
462 
463 			//RGB (p->blendimg->buf にセット)
464 
465 			for(i = 0; i < 3; i++)
466 			{
467 				if(!mPSDLoad_beginImageChannel(psd)) goto PSDERR;
468 
469 				pd = p->blendimg->buf + i;
470 
471 				mPopupProgressThreadBeginSubStep(prog, 10, h);
472 
473 				for(iy = h; iy; iy--)
474 				{
475 					if(!mPSDLoad_readImageChannelLine(psd)) goto PSDERR;
476 
477 					ps = mPSDLoad_getLineImageBuf(psd);
478 
479 					for(ix = w; ix; ix--, pd += 3)
480 						*pd = *(ps++);
481 
482 					mPopupProgressThreadIncSubStep(prog);
483 				}
484 			}
485 
486 			//
487 
488 			if(chnum == 3)
489 				//A なしなら ImageBuf24 としてセット
490 				TileImage_setImage_fromImageBuf24(img, p->blendimg, prog, TRUE);
491 			else
492 			{
493 				//blendimg->buf + A
494 
495 				if(!mPSDLoad_beginImageChannel(psd)) goto PSDERR;
496 
497 				mPopupProgressThreadBeginSubStep(prog, 10, h);
498 
499 				pd = p->blendimg->buf;
500 
501 				for(iy = 0; iy < h; iy++)
502 				{
503 					if(!mPSDLoad_readImageChannelLine(psd)) goto PSDERR;
504 
505 					ps = mPSDLoad_getLineImageBuf(psd);
506 
507 					for(ix = 0; ix < w; ix++, ps++, pd += 3)
508 					{
509 						if(*ps)
510 						{
511 							pix.r = pd[0];
512 							pix.g = pd[1];
513 							pix.b = pd[2];
514 							pix.a = *ps;
515 
516 							TileImage_setPixel_new(img, ix, iy, &pix);
517 						}
518 					}
519 
520 					mPopupProgressThreadIncSubStep(prog);
521 				}
522 			}
523 			break;
524 	}
525 
526 	//mono or gray
527 
528 	if(type != _TYPE_RGB)
529 	{
530 		mPopupProgressThreadBeginSubStep(prog, 20, h);
531 
532 		TileImage_setImage_from8bitGray(img, p->blendimg->buf, w, h, prog);
533 	}
534 
535 	return MPSDLOAD_ERR_OK;
536 
537 PSDERR:
538 	return psd->err;
539 }
540 
541 /** PSD 読み込み */
542 
drawFile_load_psd(DrawData * p,const char * filename,mPopupProgress * prog,char ** errmes)543 mBool drawFile_load_psd(DrawData *p,const char *filename,mPopupProgress *prog,char **errmes)
544 {
545 	mPSDLoad *psd;
546 	mBool ret = FALSE;
547 	int err = -1,horz,vert;
548 
549 	/* err: -1 で psd->err、-2 でサイズ制限、それ以外は PSD エラー */
550 
551 	//作成
552 
553 	psd = mPSDLoad_new();
554 	if(!psd)
555 	{
556 		err = MPSDLOAD_ERR_ALLOC;
557 		goto ERR;
558 	}
559 
560 	//開く
561 
562 	if(!mPSDLoad_openFile(psd, filename)) goto ERR;
563 
564 	//画像サイズ制限
565 
566 	if(psd->width > IMAGE_SIZE_MAX || psd->height > IMAGE_SIZE_MAX)
567 	{
568 		err = -2;
569 		goto ERR;
570 	}
571 
572 	//新規イメージ
573 
574 	if(!drawImage_new(p, psd->width, psd->height, -1, FALSE))
575 	{
576 		err = MPSDLOAD_ERR_ALLOC;
577 		goto ERR;
578 	}
579 
580 	//画像リソース
581 
582 	if(mPSDLoad_readResource_resolution_dpi(psd, &horz, &vert))
583 		p->imgdpi = horz;
584 
585 	//レイヤ or 一枚絵イメージ
586 
587 	if(mPSDLoad_isHaveLayer(psd))
588 	{
589 		//レイヤ読み込み
590 
591 		if(!mPSDLoad_beginLayer(psd)) goto ERR;
592 
593 		err = _load_from_layer(p, psd, prog);
594 
595 		mPSDLoad_endLayer(psd);
596 	}
597 	else
598 	{
599 		//レイヤなしの場合は一枚絵イメージから読み込み
600 
601 		err = _load_from_image(p, psd, prog);
602 	}
603 
604 	//成功
605 
606 	if(err == MPSDLOAD_ERR_OK)
607 	{
608 		p->curlayer = LayerList_getItem_top(p->layerlist);
609 		ret = TRUE;
610 	}
611 
612 	//---------
613 
614 ERR:
615 	if(!ret)
616 	{
617 		if(err == -2)
618 			*errmes = mStrdup("image size is large");
619 		else
620 			*errmes = mStrdup(mPSDLoad_getErrorMessage((err == -1)? psd->err: err));
621 	}
622 
623 	mPSDLoad_close(psd);
624 
625 	return ret;
626 }
627 
628 
629 //=============================
630 // 保存
631 //=============================
632 
633 
634 /** 一枚絵イメージ書き込み */
635 
_psdimage_write(DrawData * p,mPSDSave * psd,int type,mPopupProgress * prog)636 static mBool _psdimage_write(DrawData *p,mPSDSave *psd,int type,mPopupProgress *prog)
637 {
638 	uint8_t *ps,*pd,*dstbuf,val,f;
639 	int w,h,i,j,ix,iy;
640 
641 	if(!mPSDSave_beginImage(psd)) return FALSE;
642 
643 	w = p->imgw;
644 	h = p->imgh;
645 	ps = p->blendimg->buf;
646 
647 	dstbuf = mPSDSave_getLineImageBuf(psd);
648 
649 	switch(type)
650 	{
651 		//RGB
652 		case _TYPE_RGB:
653 			mPopupProgressThreadBeginSubStep_onestep(prog, 30, h * 3);
654 
655 			for(i = 0; i < 3; i++)
656 			{
657 				mPSDSave_beginImageChannel(psd);
658 
659 				ps = p->blendimg->buf + i;
660 
661 				for(iy = h; iy > 0; iy--)
662 				{
663 					pd = dstbuf;
664 
665 					for(ix = w; ix > 0; ix--, ps += 3)
666 						*(pd++) = *ps;
667 
668 					mPSDSave_writeImageChannelLine(psd);
669 
670 					mPopupProgressThreadIncSubStep(prog);
671 				}
672 
673 				mPSDSave_endImageChannel(psd);
674 			}
675 			break;
676 
677 		//グレイスケール
678 		case _TYPE_GRAY:
679 			mPopupProgressThreadBeginSubStep_onestep(prog, 20, h);
680 
681 			mPSDSave_beginImageChannel(psd);
682 
683 			for(iy = h; iy > 0; iy--)
684 			{
685 				pd = dstbuf;
686 
687 				for(ix = w; ix > 0; ix--, ps += 3)
688 					*(pd++) = _TOGRAY(ps[0], ps[1], ps[2]);
689 
690 				mPSDSave_writeImageChannelLine(psd);
691 
692 				mPopupProgressThreadIncSubStep(prog);
693 			}
694 
695 			mPSDSave_endImageChannel(psd);
696 			break;
697 
698 		//mono (白=0、それ以外は1)
699 		case _TYPE_MONO:
700 			mPopupProgressThreadBeginSubStep_onestep(prog, 20, h);
701 
702 			mPSDSave_beginImageChannel(psd);
703 
704 			for(iy = h; iy > 0; iy--)
705 			{
706 				pd = dstbuf;
707 				ix = w;
708 
709 				for(i = (w + 7) >> 3; i > 0; i--)
710 				{
711 					val = 0;
712 					f = 0x80;
713 
714 					for(j = 8; j && ix; j--, ix--, ps += 3, f >>= 1)
715 					{
716 						if(ps[0] != 255 || ps[1] != 255 || ps[2] != 255)
717 							val |= f;
718 					}
719 
720 					*(pd++) = val;
721 				}
722 
723 				mPSDSave_writeImageChannelLine(psd);
724 
725 				mPopupProgressThreadIncSubStep(prog);
726 			}
727 
728 			mPSDSave_endImageChannel(psd);
729 			break;
730 	}
731 
732 	return TRUE;
733 }
734 
735 /** レイヤ出力 */
736 
_write_layer(DrawData * p,mPSDSave * psd,int layernum,mPopupProgress * prog)737 static mBool _write_layer(DrawData *p,mPSDSave *psd,int layernum,mPopupProgress *prog)
738 {
739 	LayerItem *pi_bottom,*pi;
740 	mPSDSaveLayerInfo info;
741 	mRect rc;
742 	mBox box;
743 	int ch,ix,iy;
744 	uint8_t *pd;
745 	PixelRGBA pix;
746 
747 	mPopupProgressThreadSetMax(prog, layernum * 4);
748 
749 	//書き込む先頭レイヤ
750 
751 	pi_bottom = LayerList_getItem_bottomNormal(p->layerlist);
752 
753 	//レイヤ開始
754 
755 	if(!mPSDSave_beginLayer(psd, layernum)) return FALSE;
756 
757 	//レイヤ情報
758 
759 	for(pi = pi_bottom; pi; pi = LayerItem_getPrevNormal(pi))
760 	{
761 		mMemzero(&info, sizeof(mPSDSaveLayerInfo));
762 
763 		if(TileImage_getHaveImageRect_pixel(pi->img, &rc, NULL))
764 		{
765 			info.left = rc.x1;
766 			info.top = rc.y1;
767 			info.right = rc.x2 + 1;
768 			info.bottom = rc.y2 + 1;
769 		}
770 
771 		info.name = pi->name;
772 		info.opacity = (int)(pi->opacity / 128.0 * 255.0 + 0.5);
773 		info.hide = !(pi->flags & LAYERITEM_F_VISIBLE);
774 		info.blendmode = g_blendmode[pi->blendmode];
775 		info.channels = 4;
776 
777 		mPSDSave_writeLayerInfo(psd, &info);
778 	}
779 
780 	if(!mPSDSave_endLayerInfo(psd)) return FALSE;
781 
782 	//イメージ
783 
784 	for(pi = pi_bottom; pi; pi = LayerItem_getPrevNormal(pi))
785 	{
786 		if(!mPSDSave_beginLayerImage(psd, &box))
787 		{
788 			//空イメージ
789 
790 			mPopupProgressThreadAddPos(prog, 4);
791 		}
792 		else
793 		{
794 			//各チャンネル
795 
796 			for(ch = 0; ch < 4; ch++)
797 			{
798 				mPSDSave_beginLayerImageChannel(psd,
799 					(ch == 3)? MPSD_CHANNEL_ID_ALPHA: ch);
800 
801 				for(iy = 0; iy < box.h; iy++)
802 				{
803 					pd = mPSDSave_getLineImageBuf(psd);
804 
805 					for(ix = 0; ix < box.w; ix++)
806 					{
807 						TileImage_getPixel(pi->img, box.x + ix, box.y + iy, &pix);
808 
809 						*(pd++) = pix.ar[ch];
810 					}
811 
812 					mPSDSave_writeLayerImageChannelLine(psd);
813 				}
814 
815 				mPSDSave_endLayerImageChannel(psd);
816 
817 				mPopupProgressThreadIncPos(prog);
818 			}
819 		}
820 
821 		mPSDSave_endLayerImage(psd);
822 	}
823 
824 	mPSDSave_endLayer(psd);
825 
826 	return TRUE;
827 }
828 
829 /** PSD 保存 (レイヤ維持)
830  *
831  * フォルダは保存されない。 */
832 
drawFile_save_psd_layer(DrawData * p,const char * filename,mPopupProgress * prog)833 mBool drawFile_save_psd_layer(DrawData *p,const char *filename,mPopupProgress *prog)
834 {
835 	mPSDSave *psd;
836 	mPSDSaveInfo info;
837 	mBool ret = FALSE;
838 	int layernum;
839 
840 	//通常レイヤ数 (フォルダしかない場合はエラー)
841 
842 	layernum = LayerList_getNormalLayerNum(p->layerlist);
843 
844 	if(layernum == 0) return FALSE;
845 
846 	//情報
847 
848 	info.width = p->imgw;
849 	info.height = p->imgh;
850 	info.img_channels = 3;
851 	info.bits = 8;
852 	info.colmode = MPSD_COLMODE_RGB;
853 
854 	//開く
855 
856 	psd = mPSDSave_openFile(filename, &info,
857 		((APP_CONF->save.flags & CONFIG_SAVEOPTION_F_PSD_UNCOMPRESSED) == 0));
858 
859 	if(!psd) return FALSE;
860 
861 	//画像リソース
862 
863 	mPSDSave_beginResource(psd);
864 
865 	mPSDSave_writeResource_resolution_dpi(psd, p->imgdpi, p->imgdpi);
866 	mPSDSave_writeResource_currentLayer(psd, 0);
867 
868 	mPSDSave_endResource(psd);
869 
870 	//レイヤ
871 
872 	if(_write_layer(p, psd, layernum, prog))
873 	{
874 		//一枚絵イメージ
875 
876 		ret = _psdimage_write(p, psd, _TYPE_RGB, prog);
877 	}
878 
879 	mPSDSave_close(psd);
880 
881 	if(!ret) mDeleteFile(filename);
882 
883 	return ret;
884 }
885 
886 /** PSD 保存 (レイヤなし)
887  *
888  * @param type 1:8bitRGB 2:grayscale 3:mono */
889 
drawFile_save_psd_image(DrawData * p,int type,const char * filename,mPopupProgress * prog)890 mBool drawFile_save_psd_image(DrawData *p,int type,const char *filename,mPopupProgress *prog)
891 {
892 	mPSDSave *psd;
893 	mPSDSaveInfo info;
894 	mBool ret;
895 
896 	//情報
897 
898 	info.width = p->imgw;
899 	info.height = p->imgh;
900 	info.img_channels = (type == _TYPE_RGB)? 3: 1;
901 	info.bits = (type == _TYPE_MONO)? 1: 8;
902 
903 	switch(type)
904 	{
905 		case _TYPE_RGB: info.colmode = MPSD_COLMODE_RGB; break;
906 		case _TYPE_GRAY: info.colmode = MPSD_COLMODE_GRAYSCALE; break;
907 		default: info.colmode = MPSD_COLMODE_MONO; break;
908 	}
909 
910 	//開く
911 
912 	psd = mPSDSave_openFile(filename, &info,
913 		((APP_CONF->save.flags & CONFIG_SAVEOPTION_F_PSD_UNCOMPRESSED) == 0));
914 
915 	if(!psd) return FALSE;
916 
917 	//画像リソース
918 
919 	mPSDSave_beginResource(psd);
920 
921 	mPSDSave_writeResource_resolution_dpi(psd, p->imgdpi, p->imgdpi);
922 
923 	mPSDSave_endResource(psd);
924 
925 	//レイヤなし
926 
927 	mPSDSave_writeLayerNone(psd);
928 
929 	//一枚絵イメージ
930 
931 	ret = _psdimage_write(p, psd, type, prog);
932 
933 	mPSDSave_close(psd);
934 
935 	if(!ret) mDeleteFile(filename);
936 
937 	return ret;
938 }
939