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  * mPSDSave
22  *****************************************/
23 
24 #include <stdio.h>
25 #include <string.h>
26 
27 #include "mDef.h"
28 #include "mUtilStdio.h"
29 #include "mUtil.h"
30 #include "mUtilCharCode.h"
31 
32 #include "mPSDSave.h"
33 
34 
35 //-------------------
36 
37 typedef struct
38 {
39 	long fpos_chinfo;
40 	int left,top,width,height;
41 	uint8_t channels;
42 }_layerinfo;
43 
44 
45 struct _mPSDSave
46 {
47 	FILE *fp;
48 	mPSDSaveInfo *info;
49 
50 	uint8_t *buf1,		//作業用バッファ1
51 		*buf2,			//作業用バッファ2
52 		*rowbuf,		//チャンネルのY1行バッファ
53 		*outbuf,		//PackBits 書き込み用バッファ
54 						//(無圧縮時は Unicode 名用バッファ)
55 		compression;	//0:無圧縮 1:PackBits
56 
57 	_layerinfo *curlinfo;
58 
59 	fpos_t fpos1,
60 		fpos2;
61 	uint32_t size1,
62 		size2;
63 	int layernum,
64 		pitch,
65 		cury,
66 		curlayer,
67 		curchannel,
68 		outsize,	//outbuf の現在の書き込みサイズ
69 		layer_maxw,	//レイヤイメージの最大サイズ
70 		layer_maxh,
71 		channel_id;
72 };
73 
74 //-------------------
75 
76 #define _OUTBUFSIZE  (8 * 1024)
77 #define _MAX_UNICODE_NAME_LEN 256  //レイヤ名 Unicode の最大文字数
78 
79 //-------------------
80 
81 
82 
83 //========================
84 // PackBits 圧縮
85 //========================
86 
87 
88 /** outbuf のデータをファイルに書き込み */
89 
_write_outbuf(mPSDSave * p)90 static void _write_outbuf(mPSDSave *p)
91 {
92 	if(p->outsize)
93 	{
94 		fwrite(p->outbuf, 1, p->outsize, p->fp);
95 		p->outsize = 0;
96 	}
97 }
98 
99 /** データ書き込み
100  *
101  * @param type 0:非連続 1:連続
102  * @return 書き込んだサイズ */
103 
_packbits_write(mPSDSave * p,uint8_t type,uint8_t * buf,int cnt)104 static int _packbits_write(mPSDSave *p,uint8_t type,uint8_t *buf,int cnt)
105 {
106 	int size,len;
107 	uint8_t *pd;
108 
109 	//長さ
110 
111 	len = cnt - 1;
112 	if(type) len = -len;
113 
114 	//データサイズ
115 
116 	size = 1 + ((type)? 1: cnt);
117 
118 	//バッファを超える場合はファイルに出力
119 
120 	if(p->outsize + size >= _OUTBUFSIZE)
121 		_write_outbuf(p);
122 
123 	//バッファに追加
124 
125 	pd = p->outbuf + p->outsize;
126 
127 	*pd = (uint8_t)len;
128 
129 	if(type)
130 		pd[1] = *buf;
131 	else
132 		memcpy(pd + 1, buf, cnt);
133 
134 	p->outsize += size;
135 
136 	return size;
137 }
138 
139 /** PackBits 圧縮
140  *
141  * outbuf に圧縮データを書き込み、バッファがいっぱいになったらファイルへ書き込む。
142  *
143  * @return 圧縮サイズ */
144 
_encode_packbits(mPSDSave * p,uint8_t * buf,int size)145 static int _encode_packbits(mPSDSave *p,uint8_t *buf,int size)
146 {
147 	uint8_t *ps,*psend,*ps2,val;
148 	int write = 0;
149 
150 	ps = buf;
151 	psend = ps + size;
152 
153 	while(ps < psend)
154 	{
155 		if(ps == psend - 1 || *ps != ps[1])
156 		{
157 			//非連続データ (次の連続データが見つかるまで)
158 
159 			for(ps2 = ps; ps - ps2 < 128; ps++)
160 			{
161 				if(ps == psend - 1)
162 				{
163 					ps++;
164 					break;
165 				}
166 				else if(*ps == ps[1])
167 					break;
168 			}
169 
170 			write += _packbits_write(p, 0, ps2, ps - ps2);
171 		}
172 		else
173 		{
174 			//連続データ
175 
176 			val = *ps;
177 			ps2 = ps;
178 
179 			for(ps += 2; ps < psend && ps - ps2 < 128 && *ps == val; ps++);
180 
181 			write += _packbits_write(p, 1, ps2, ps - ps2);
182 		}
183 	}
184 
185 	return write;
186 }
187 
188 
189 //=========================
190 // sub
191 //=========================
192 
193 
194 /** Unicode レイヤ名を outbuf にセット
195  *
196  * NULL 文字は含まない。
197  * データは 4byte 境界。
198  *
199  * @return 文字数 */
200 
_set_layername_unicode(mPSDSave * p,const char * name)201 static int _set_layername_unicode(mPSDSave *p,const char *name)
202 {
203 	uint8_t *pd;
204 	uint32_t c,c2;
205 	int ret,len;
206 
207 	pd = p->outbuf;
208 	len = 0;
209 
210 	while(*name && len < _MAX_UNICODE_NAME_LEN)
211 	{
212 		ret = mUTF8ToUCS4Char(name, -1, &c, &name);
213 
214 		if(ret < 0)
215 			return 0;
216 		else if(ret == 0)
217 		{
218 			if(c <= 0xffff)
219 			{
220 				pd[0] = c >> 8;
221 				pd[1] = (uint8_t)c;
222 				pd += 2;
223 				len++;
224 			}
225 			else
226 			{
227 				c -= 0x10000;
228 				c2 = c >> 16;
229 
230 				pd[0] = 0xd8 | (c2 >> 2);
231 				pd[1] = ((c2 & 3) << 6) | ((c >> 10) & 63);
232 				pd[2] = 0xdc | ((c >> 8) & 3);
233 				pd[3] = (uint8_t)c;
234 
235 				pd += 4;
236 				len += 2;
237 			}
238 		}
239 	}
240 
241 	//余白追加 (4byte境界)
242 
243 	if(len & 1)
244 		pd[0] = pd[1] = 0;
245 
246 	return len;
247 }
248 
249 
250 //=========================
251 // main
252 //=========================
253 
254 
255 /*******************//**
256 
257 @defgroup psdsave mPSDSave
258 @brief PSD 書き込み
259 
260 @ingroup group_image
261 
262 @{
263 @file mPSDSave.h
264 
265 @struct mPSDSaveInfo
266 @enum MPSD_COLMODE
267 @enum MPSD_BLENDMODE
268 
269 ************************/
270 
271 
272 /** 閉じる */
273 
mPSDSave_close(mPSDSave * p)274 void mPSDSave_close(mPSDSave *p)
275 {
276 	if(p)
277 	{
278 		if(p->fp) fclose(p->fp);
279 
280 		mFree(p->buf1);
281 		mFree(p->buf2);
282 		mFree(p->rowbuf);
283 		mFree(p->outbuf);
284 
285 		mFree(p);
286 	}
287 }
288 
289 /** ファイルから開く
290  *
291  * @param packbits PackBits 圧縮を行うか (FALSE で無圧縮) */
292 
mPSDSave_openFile(const char * filename,mPSDSaveInfo * info,mBool packbits)293 mPSDSave *mPSDSave_openFile(const char *filename,mPSDSaveInfo *info,mBool packbits)
294 {
295 	mPSDSave *p;
296 	uint8_t dat[26];
297 
298 	//確保
299 
300 	p = (mPSDSave *)mMalloc(sizeof(mPSDSave), TRUE);
301 	if(!p) return NULL;
302 
303 	p->info = info;
304 	p->compression = (packbits != 0);
305 
306 	//PackBits 書き込み用バッファ
307 	//(無圧縮時は Unicode 名用バッファ)
308 
309 	p->outbuf = (uint8_t *)mMalloc(
310 		(packbits)? _OUTBUFSIZE: ((_MAX_UNICODE_NAME_LEN * 2 + 3) & ~3), FALSE);
311 
312 	if(!p->outbuf)
313 	{
314 		mPSDSave_close(p);
315 		return NULL;
316 	}
317 
318 	//ファイル開く
319 
320 	p->fp = mFILEopenUTF8(filename, "wb");
321 	if(!p->fp)
322 	{
323 		mPSDSave_close(p);
324 		return NULL;
325 	}
326 
327 	//ファイルヘッダ書き込み
328 
329 	mSetBufBE_args(dat, "s24224422",
330 		"8BPS",
331 		1,		//version
332 		0, 0,	//reversed
333 		p->info->img_channels, p->info->height, p->info->width,
334 		p->info->bits, p->info->colmode);
335 
336 	fwrite(dat, 1, 26, p->fp);
337 
338 	//カラーモードデータサイズ (0)
339 
340 	mFILEwriteZero(p->fp, 4);
341 
342 	return p;
343 }
344 
345 /** イメージ書き込み先バッファ取得 */
346 
mPSDSave_getLineImageBuf(mPSDSave * p)347 uint8_t *mPSDSave_getLineImageBuf(mPSDSave *p)
348 {
349 	return p->rowbuf;
350 }
351 
352 
353 //=========================
354 // 画像リソースデータ
355 //=========================
356 /*
357  * fpos1 : 全体サイズ書き込み位置
358  * size1 : 全体サイズ
359  *
360  * 各データは 2byte 境界。
361  * 奇数の場合は、データサイズはそのままで、余白データを 1byte 追加。
362  */
363 
364 
365 /** 画像リソースデータ開始 */
366 
mPSDSave_beginResource(mPSDSave * p)367 void mPSDSave_beginResource(mPSDSave *p)
368 {
369 	//全体サイズ (仮)
370 
371 	fgetpos(p->fp, &p->fpos1);
372 	mFILEwriteZero(p->fp, 4);
373 
374 	p->size1 = 0;
375 }
376 
377 /** 画像リソースデータ終了 */
378 
mPSDSave_endResource(mPSDSave * p)379 void mPSDSave_endResource(mPSDSave *p)
380 {
381 	//データが空の場合、すでに仮サイズで 0 を書き込んでいるので、何もしない
382 
383 	if(p->size1)
384 	{
385 		fsetpos(p->fp, &p->fpos1);
386 		mFILEwrite32BE(p->fp, p->size1);
387 		fseek(p->fp, 0, SEEK_END);
388 	}
389 }
390 
391 /** 画像リソース:解像度を DPI 単位で書き込み */
392 
mPSDSave_writeResource_resolution_dpi(mPSDSave * p,int dpi_horz,int dpi_vert)393 void mPSDSave_writeResource_resolution_dpi(mPSDSave *p,int dpi_horz,int dpi_vert)
394 {
395 	uint8_t dat[28] = {
396 		0x38,0x42,0x49,0x4d,    //'8BIM'
397 		0x03,0xed,              //ID (0x03ed)
398 		0x00,0x00,              //name
399 		0x00,0x00,0x00,0x10,    //size
400 		0x00,0x00,0x00,0x00, 0x00,0x01, 0x00,0x02, //H
401 		0x00,0x00,0x00,0x00, 0x00,0x01, 0x00,0x02  //V
402 
403 		/* [4byte:16+16bit固定小数点] [2byte:1=pixel per inch] [2byte:2=cm] */
404 	};
405 
406 	//固定小数点数の整数部分をセット
407 
408 	mSetBuf16BE(dat + 12, dpi_horz);
409 	mSetBuf16BE(dat + 20, dpi_vert);
410 
411 	fwrite(dat, 1, 28, p->fp);
412 
413 	p->size1 += 28;
414 }
415 
416 /** 画像リソース:カレントレイヤ番号を書き込み
417  *
418  * @param no 一番下のレイヤを 0 とする */
419 
mPSDSave_writeResource_currentLayer(mPSDSave * p,int no)420 void mPSDSave_writeResource_currentLayer(mPSDSave *p,int no)
421 {
422 	uint8_t dat[14] = {
423 		0x38,0x42,0x49,0x4d,	//'8BIM'
424 		0x04,0x00,				//ID (0x0400)
425 		0x00,0x00,				//name
426 		0x00,0x00,0x00,0x02,	//size
427 		0x00,0x00
428 	};
429 
430 	mSetBuf16BE(dat + 12, no);
431 	fwrite(dat, 1, 14, p->fp);
432 
433 	p->size1 += 14;
434 }
435 
436 
437 //=============================
438 // 一枚絵イメージ
439 //=============================
440 /*
441  * fpos1 : Y圧縮サイズリスト書き込み位置
442  * buf1  : Y圧縮サイズリストバッファ
443  */
444 
445 
446 /** 一枚絵イメージ 書き込み開始
447  *
448  * レイヤデータ書き込み後。*/
449 
mPSDSave_beginImage(mPSDSave * p)450 mBool mPSDSave_beginImage(mPSDSave *p)
451 {
452 	int i,lsize;
453 
454 	//チャンネルのY1行サイズ
455 
456 	if(p->info->bits == 1)
457 		p->pitch = (p->info->width + 7) >> 3;
458 	else
459 		p->pitch = p->info->width;
460 
461 	//Y1行バッファ
462 
463 	p->rowbuf = (uint8_t *)mMalloc(p->pitch, FALSE);
464 	if(!p->rowbuf) return FALSE;
465 
466 	//PackBits Y圧縮サイズリストバッファ
467 
468 	if(p->compression)
469 	{
470 		lsize = p->info->height * 2;
471 
472 		p->buf1 = (uint8_t *)mMalloc(lsize, TRUE);
473 		if(!p->buf1) return FALSE;
474 	}
475 
476 	//圧縮タイプ
477 
478 	mFILEwrite16BE(p->fp, p->compression);
479 
480 	//Y圧縮サイズリストを仮出力
481 
482 	if(p->compression)
483 	{
484 		fgetpos(p->fp, &p->fpos1);
485 
486 		for(i = p->info->img_channels; i > 0; i--)
487 			fwrite(p->buf1, 1, lsize, p->fp);
488 	}
489 
490 	return TRUE;
491 }
492 
493 /** 一枚絵イメージ、各チャンネルの書き込み開始 */
494 
mPSDSave_beginImageChannel(mPSDSave * p)495 void mPSDSave_beginImageChannel(mPSDSave *p)
496 {
497 	p->cury = 0;
498 	p->outsize = 0;
499 }
500 
501 /** 一枚絵イメージ、各チャンネルのY1行イメージ書き込み
502  *
503  * mPSDSave_getLineImageBuf() で取得したバッファに書き込んでおく。 */
504 
mPSDSave_writeImageChannelLine(mPSDSave * p)505 void mPSDSave_writeImageChannelLine(mPSDSave *p)
506 {
507 	int size;
508 
509 	if(p->cury < p->info->height)
510 	{
511 		if(p->compression == 0)
512 		{
513 			//無圧縮
514 
515 			fwrite(p->rowbuf, 1, p->pitch, p->fp);
516 		}
517 		else
518 		{
519 			//PackBits
520 
521 			size = _encode_packbits(p, p->rowbuf, p->pitch);
522 
523 			mSetBuf16BE(p->buf1 + (p->cury << 1), size);
524 		}
525 
526 		p->cury++;
527 	}
528 }
529 
530 /** 一枚絵イメージ、各チャンネルの書き込み終了 */
531 
mPSDSave_endImageChannel(mPSDSave * p)532 void mPSDSave_endImageChannel(mPSDSave *p)
533 {
534 	//バッファの残りデータを出力
535 
536 	_write_outbuf(p);
537 
538 	//Y圧縮サイズリスト
539 
540 	if(p->compression)
541 	{
542 		fsetpos(p->fp, &p->fpos1);
543 		fwrite(p->buf1, 1, p->info->height * 2, p->fp);
544 
545 		//次の書き込み位置
546 
547 		fgetpos(p->fp, &p->fpos1);
548 		fseek(p->fp, 0, SEEK_END);
549 	}
550 }
551 
552 
553 //=============================
554 // レイヤ
555 //=============================
556 /*
557  * fpos1 : 全体サイズ書き込み位置
558  * fpos2 : 各チャンネルのY圧縮サイズリスト書き込み位置
559  * buf1  : 全レイヤの情報データ記録用
560  * buf2  : Y圧縮サイズリストバッファ
561  * size1 : 各チャンネルの圧縮サイズ
562  * size2 : レイヤデータ全体のサイズ
563  */
564 
565 
566 /** レイヤなしの場合、一枚絵イメージの前に書き込み */
567 
mPSDSave_writeLayerNone(mPSDSave * p)568 void mPSDSave_writeLayerNone(mPSDSave *p)
569 {
570 	mFILEwrite32BE(p->fp, 0);
571 }
572 
573 /** レイヤ書き込み開始
574  *
575  * @param num レイヤ数 */
576 
mPSDSave_beginLayer(mPSDSave * p,int num)577 mBool mPSDSave_beginLayer(mPSDSave *p,int num)
578 {
579 	p->layernum = num;
580 	p->curlayer = 0;
581 	p->layer_maxw = p->layer_maxh = 0;
582 	p->size2 = 2;  //2 = レイヤ数
583 
584 	//レイヤ情報バッファ確保
585 
586 	p->buf1 = (uint8_t *)mMalloc(sizeof(_layerinfo) * num, FALSE);
587 	if(!p->buf1) return FALSE;
588 
589 	p->curlinfo = (_layerinfo *)p->buf1;
590 
591 	//書き込み
592 
593 	fgetpos(p->fp, &p->fpos1);
594 
595 	mFILEwriteZero(p->fp, 8);	//全体サイズ(4) + 内部全体サイズ(4)
596 	mFILEwrite16BE(p->fp, num);	//レイヤ数
597 
598 	return TRUE;
599 }
600 
601 /** レイヤ情報書き込み
602  *
603  * mPSDSave_beginLayer() 後、一番下のレイヤを先頭として、全レイヤ分を書き込む。 */
604 
mPSDSave_writeLayerInfo(mPSDSave * p,mPSDSaveLayerInfo * info)605 void mPSDSave_writeLayerInfo(mPSDSave *p,mPSDSaveLayerInfo *info)
606 {
607 	FILE *fp = p->fp;
608 	_layerinfo *winfo;
609 	int i,name_len,name_len4,name_uni_len,name_uni_size4,exsize;
610 
611 	if(p->curlayer >= p->layernum) return;
612 
613 	//必要な情報を保存
614 
615 	winfo = p->curlinfo;
616 
617 	winfo->left = info->left;
618 	winfo->top = info->top;
619 	winfo->width = info->right - info->left;
620 	winfo->height = info->bottom - info->top;
621 
622 	//イメージの最大サイズを記録しておく
623 
624 	if(p->layer_maxw < winfo->width) p->layer_maxw = winfo->width;
625 	if(p->layer_maxh < winfo->height) p->layer_maxh = winfo->height;
626 
627 	//------ 基本データ書き込み
628 
629 	//範囲
630 
631 	mFILEwrite32BE(fp, info->top);
632 	mFILEwrite32BE(fp, info->left);
633 	mFILEwrite32BE(fp, info->bottom);
634 	mFILEwrite32BE(fp, info->right);
635 
636 	//チャンネル数
637 
638 	mFILEwrite16BE(fp, info->channels);
639 
640 	//チャンネルデータ
641 
642 	winfo->fpos_chinfo = ftell(fp);
643 
644 	for(i = 0; i < info->channels; i++)
645 	{
646 		//ID (仮)
647 
648 		mFILEwrite16BE(fp, 0);
649 
650 		//データサイズ (仮)
651 		/* 範囲なしの場合、圧縮フラグ[2byte]のみなので、2 をセットしておく */
652 
653 		mFILEwrite32BE(fp, 2);
654 	}
655 
656 	//8BIM
657 
658 	fputs("8BIM", fp);
659 
660 	//合成モード
661 
662 	mFILEwrite32BE(fp, info->blendmode);
663 
664 	//不透明度
665 
666 	mFILEwriteByte(fp, info->opacity);
667 
668 	//clip
669 
670 	mFILEwriteByte(fp, 0);
671 
672 	//フラグ [0bit:透明色保護 1bit:非表示]
673 
674 	mFILEwriteByte(fp, (info->hide)? 2: 0);
675 
676 	//0
677 
678 	mFILEwriteByte(fp, 0);
679 
680 	//-------- 拡張データ
681 
682 	/* 4byte: 以下の拡張データサイズ
683 	 * 4byte: レイヤマスクデータサイズ
684 	 * 4byte: 合成データサイズ
685 	 * パスカル文字列: レイヤ名 [!]4byte境界(長さのバイトも含む)
686 	 * 8BIM + key のデータが並ぶ
687 	 */
688 
689 	name_len = name_uni_len = 0;
690 	exsize = 0;
691 
692 	//レイヤ名長さ
693 
694 	if(info->name)
695 	{
696 		name_len = strlen(info->name);
697 		if(name_len > 255) name_len = 255;
698 	}
699 
700 	name_len4 = (name_len + 1 + 3) & ~3;
701 
702 	//Unicode レイヤ名 (outbuf にセット)
703 
704 	if(name_len)
705 	{
706 		name_uni_len = _set_layername_unicode(p, info->name);
707 
708 		name_uni_size4 = (name_uni_len * 2 + 3) & ~3;
709 		exsize += 8 + 4 + 4 + name_uni_size4;
710 	}
711 
712 	//****
713 
714 	//拡張データサイズ
715 
716 	mFILEwrite32BE(fp, 8 + name_len4 + exsize);
717 
718 	//レイヤマスクデータサイズ + 合成データサイズ
719 
720 	mFILEwriteZero(fp, 8);
721 
722 	//レイヤ名
723 
724 	mFILEwriteByte(fp, name_len);
725 	fwrite(info->name, 1, name_len, fp);
726 	mFILEwriteZero(fp, name_len4 - name_len - 1);	//余白
727 
728 	//レイヤ名 (Unicode)
729 
730 	if(name_uni_len)
731 	{
732 		fputs("8BIMluni", fp);
733 		mFILEwrite32BE(fp, 4 + name_uni_size4);
734 		mFILEwrite32BE(fp, name_uni_len);
735 		fwrite(p->outbuf, 1, name_uni_size4, fp);
736 	}
737 
738 	//次へ
739 
740 	p->curlayer++;
741 	p->curlinfo++;
742 	p->size2 += 66 + name_len4 + exsize;
743 }
744 
745 /** レイヤ情報書き込み終了
746  *
747  * イメージ書き込みの準備を行う。 */
748 
mPSDSave_endLayerInfo(mPSDSave * p)749 mBool mPSDSave_endLayerInfo(mPSDSave *p)
750 {
751 	p->curlayer = 0;
752 	p->curlinfo = (_layerinfo *)p->buf1;
753 
754 	//バッファ確保
755 
756 	p->rowbuf = (uint8_t *)mMalloc(p->layer_maxw, FALSE);
757 	if(!p->rowbuf) return FALSE;
758 
759 	if(p->compression)
760 	{
761 		p->buf2 = (uint8_t *)mMalloc(p->layer_maxh * 2, FALSE);
762 		if(!p->buf2) return FALSE;
763 	}
764 
765 	return TRUE;
766 }
767 
768 /** 各レイヤのイメージ書き込み開始
769  *
770  * 空イメージの場合は、イメージデータが書き込まれるで、チャンネルイメージを描画する必要はない。
771  *
772  * @param box イメージ範囲が入る (NULL で取得しない)
773  * @return イメージ範囲があるか (FALSE で空イメージ) */
774 
mPSDSave_beginLayerImage(mPSDSave * p,mBox * box)775 mBool mPSDSave_beginLayerImage(mPSDSave *p,mBox *box)
776 {
777 	_layerinfo *winfo;
778 
779 	if(p->curlayer >= p->layernum) return FALSE;
780 
781 	p->curchannel = 0;
782 
783 	winfo = p->curlinfo;
784 
785 	//イメージ範囲
786 
787 	if(box)
788 	{
789 		box->x = winfo->left;
790 		box->y = winfo->top;
791 		box->w = winfo->width;
792 		box->h = winfo->height;
793 	}
794 
795 	//空かどうか
796 
797 	if(winfo->width && winfo->height)
798 		return TRUE;
799 	else
800 	{
801 		//空ならイメージデータ書き込み
802 		/* 圧縮フラグ(2byte) = 0:無圧縮 x 4 ch */
803 
804 		mFILEwriteZero(p->fp, 2 * 4);
805 
806 		p->size2 += 8;
807 
808 		return FALSE;
809 	}
810 }
811 
812 /** レイヤの各チャンネル書き込み開始 */
813 
mPSDSave_beginLayerImageChannel(mPSDSave * p,int channel_id)814 void mPSDSave_beginLayerImageChannel(mPSDSave *p,int channel_id)
815 {
816 	p->channel_id = channel_id;
817 	p->cury = 0;
818 	p->outsize = 0;
819 	p->size1 = 2;
820 
821 	//圧縮フラグ
822 
823 	mFILEwrite16BE(p->fp, p->compression);
824 
825 	//Y圧縮サイズリスト (仮)
826 
827 	if(p->compression)
828 	{
829 		fgetpos(p->fp, &p->fpos2);
830 
831 		fwrite(p->buf2, 1, p->curlinfo->height * 2, p->fp);
832 
833 		p->size1 += p->curlinfo->height * 2;
834 	}
835 }
836 
837 /** レイヤイメージの最大幅取得 */
838 
mPSDSave_getLayerImageMaxWidth(mPSDSave * p)839 int mPSDSave_getLayerImageMaxWidth(mPSDSave *p)
840 {
841 	return p->layer_maxw;
842 }
843 
844 /** レイヤのチャンネルイメージ Y1行を出力 */
845 
mPSDSave_writeLayerImageChannelLine(mPSDSave * p)846 void mPSDSave_writeLayerImageChannelLine(mPSDSave *p)
847 {
848 	int size;
849 
850 	if(p->cury < p->curlinfo->height)
851 	{
852 		if(p->compression == 0)
853 		{
854 			//無圧縮
855 
856 			fwrite(p->rowbuf, 1, p->curlinfo->width, p->fp);
857 
858 			size = p->curlinfo->width;
859 		}
860 		else
861 		{
862 			//PackBits
863 
864 			size = _encode_packbits(p, p->rowbuf, p->curlinfo->width);
865 
866 			mSetBuf16BE(p->buf2 + (p->cury << 1), size);
867 		}
868 
869 		p->cury++;
870 		p->size1 += size;
871 	}
872 }
873 
874 /** レイヤのチャンネルイメージ書き込み終了 */
875 
mPSDSave_endLayerImageChannel(mPSDSave * p)876 void mPSDSave_endLayerImageChannel(mPSDSave *p)
877 {
878 	//PackBits 残りを出力
879 
880 	_write_outbuf(p);
881 
882 	//チャンネル情報を書き込み
883 
884 	fseek(p->fp, p->curlinfo->fpos_chinfo + p->curchannel * 6, SEEK_SET);
885 
886 	mFILEwrite16BE(p->fp, p->channel_id);
887 	mFILEwrite32BE(p->fp, p->size1);
888 
889 	//Y圧縮サイズリスト書き込み
890 
891 	if(p->compression)
892 	{
893 		fsetpos(p->fp, &p->fpos2);
894 		fwrite(p->buf2, 1, p->curlinfo->height * 2, p->fp);
895 	}
896 
897 	fseek(p->fp, 0, SEEK_END);
898 
899 	//
900 
901 	p->curchannel++;
902 	p->size2 += p->size1;
903 }
904 
905 /** 各レイヤイメージ書き込み終了 */
906 
mPSDSave_endLayerImage(mPSDSave * p)907 void mPSDSave_endLayerImage(mPSDSave *p)
908 {
909 	p->curlayer++;
910 	p->curlinfo++;
911 }
912 
913 /** レイヤの書き込み終了 */
914 
mPSDSave_endLayer(mPSDSave * p)915 void mPSDSave_endLayer(mPSDSave *p)
916 {
917 	//2byte 境界
918 
919 	if(p->size2 & 1)
920 	{
921 		mFILEwriteByte(p->fp, 0);
922 		p->size2++;
923 	}
924 
925 	//全体サイズ書き込み
926 
927 	fsetpos(p->fp, &p->fpos1);
928 
929 	mFILEwrite32BE(p->fp, p->size2 + 4);
930 	mFILEwrite32BE(p->fp, p->size2);
931 
932 	fseek(p->fp, 0, SEEK_END);
933 
934 	//バッファ解放
935 
936 	mFree(p->buf1);
937 	mFree(p->buf2);
938 	mFree(p->rowbuf);
939 
940 	p->buf1 = p->buf2 = p->rowbuf = NULL;
941 }
942 
943 /* @} */
944