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  * フィルタ処理
22  *
23  * カラー/アルファ値
24  **************************************/
25 
26 #include <math.h>
27 
28 #include "mDef.h"
29 #include "mPopupProgress.h"
30 #include "mColorConv.h"
31 #include "mRandXorShift.h"
32 
33 #include "defTileImage.h"
34 #include "TileImage.h"
35 #include "LayerList.h"
36 #include "LayerItem.h"
37 #include "ImageBuf8.h"
38 
39 #include "defDraw.h"
40 #include "draw_op_sub.h"
41 
42 #include "FilterDrawInfo.h"
43 #include "filter_sub.h"
44 
45 
46 //--------------------
47 
48 typedef void (*ColorCommonFunc)(FilterDrawInfo *,int,int,PixelRGBA *);
49 
50 //--------------------
51 
52 
53 //========================
54 // カラー処理共通
55 //========================
56 
57 
58 /** キャンバスプレビュー用処理 */
59 /*
60  * - ダイアログ中のキャンバスプレビュー時は、
61  *   imgdst は imgsrc から複製されている。
62  * - RGB のみの操作なので、A=0 の点は変更なしとなる。
63  *   そのため、確保されているタイルだけ処理すれば良い。
64  */
65 
_color_common_forPreview(FilterDrawInfo * info,ColorCommonFunc func)66 static mBool _color_common_forPreview(FilterDrawInfo *info,ColorCommonFunc func)
67 {
68 	TileImageTileRectInfo tinfo;
69 	uint8_t **ppsrc,**ppdst;
70 	PixelRGBA *ps,*pd,pix;
71 	int px,py,tx,ty,ix,iy,xx,yy;
72 
73 	//処理範囲
74 
75 	ppsrc = TileImage_getTileRectInfo(info->imgsrc, &tinfo, &info->box);
76 	if(!ppsrc) return TRUE;
77 
78 	ppdst = TILEIMAGE_GETTILE_BUFPT(info->imgdst, tinfo.rctile.x1, tinfo.rctile.y1);
79 
80 	//
81 
82 	py = tinfo.pxtop.y;
83 
84 	for(ty = tinfo.rctile.y1; ty <= tinfo.rctile.y2; ty++, py += 64)
85 	{
86 		px = tinfo.pxtop.x;
87 
88 		for(tx = tinfo.rctile.x1; tx <= tinfo.rctile.x2; tx++, px += 64, ppsrc++, ppdst++)
89 		{
90 			if(!(*ppsrc)) continue;
91 
92 			//タイル単位で処理
93 
94 			ps = (PixelRGBA *)*ppsrc;
95 			pd = (PixelRGBA *)*ppdst;
96 
97 			for(iy = 0, yy = py; iy < 64; iy++, yy++)
98 			{
99 				for(ix = 0, xx = px; ix < 64; ix++, xx++, ps++, pd++)
100 				{
101 					if(ps->a && tinfo.rcclip.x1 <= xx && xx < tinfo.rcclip.x2
102 						&& tinfo.rcclip.y1 <= yy && yy < tinfo.rcclip.y2)
103 					{
104 						pix = *ps;
105 
106 						(func)(info, xx, yy, &pix);
107 
108 						*pd = pix;
109 					}
110 				}
111 			}
112 		}
113 
114 		ppsrc += tinfo.pitch;
115 		ppdst += tinfo.pitch;
116 	}
117 
118 	return TRUE;
119 }
120 
121 /** 実際の処理 */
122 
_color_common_forReal(FilterDrawInfo * info,ColorCommonFunc func)123 static mBool _color_common_forReal(FilterDrawInfo *info,ColorCommonFunc func)
124 {
125 	int ix,iy;
126 	PixelRGBA pix;
127 	TileImage *img = info->imgdst;
128 
129 	for(iy = info->rc.y1; iy <= info->rc.y2; iy++)
130 	{
131 		for(ix = info->rc.x1; ix <= info->rc.x2; ix++)
132 		{
133 			TileImage_getPixel(img, ix, iy, &pix);
134 
135 			if(pix.a)
136 			{
137 				(func)(info, ix, iy, &pix);
138 
139 				TileImage_setPixel_draw_direct(img, ix, iy, &pix);
140 			}
141 		}
142 
143 		mPopupProgressThreadIncSubStep(info->prog);
144 	}
145 
146 	return TRUE;
147 }
148 
149 /** 色操作の共通処理 */
150 
_color_common(FilterDrawInfo * info,ColorCommonFunc func)151 static mBool _color_common(FilterDrawInfo *info,ColorCommonFunc func)
152 {
153 	if(info->in_dialog)
154 		return _color_common_forPreview(info, func);
155 	else
156 		return _color_common_forReal(info, func);
157 }
158 
159 /** ピクセル処理 (共通) : テーブルから取得 */
160 
_colfunc_from_table(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)161 static void _colfunc_from_table(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
162 {
163 	uint8_t *tbl = (uint8_t *)info->ptmp[0];
164 	int i;
165 
166 	for(i = 0; i < 3; i++)
167 		pix->ar[i] = tbl[pix->ar[i]];
168 }
169 
170 
171 //========================
172 //
173 //========================
174 
175 
176 /** 明度・コントラスト調整
177  *
178  * 明度 : -255 .. 255
179  * コントラスト : -100 .. 100 */
180 
_colfunc_brightcont(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)181 static void _colfunc_brightcont(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
182 {
183 	uint8_t *tbl = (uint8_t *)info->ptmp[0];
184 	int i,val[3];
185 
186 	//コントラスト
187 
188 	for(i = 0; i < 3; i++)
189 		val[i] = tbl[pix->ar[i]];
190 
191 	//明度
192 
193 	if(info->val_bar[0])
194 	{
195 		FilterSub_RGBtoYCrCb(val);
196 
197 		val[0] += info->val_bar[0];  //Y に加算
198 
199 		FilterSub_YCrCbtoRGB(val);
200 	}
201 
202 	for(i = 0; i < 3; i++)
203 		pix->ar[i] = val[i];
204 }
205 
FilterDraw_color_brightcont(FilterDrawInfo * info)206 mBool FilterDraw_color_brightcont(FilterDrawInfo *info)
207 {
208 	uint8_t *buf;
209 	int i,n;
210 	double d;
211 
212 	//コントラスト テーブル作成
213 
214 	buf = (uint8_t *)mMalloc(256, FALSE);
215 	if(!buf) return FALSE;
216 
217 	d = info->val_bar[1] / 100.0;
218 
219 	for(i = 0; i < 256; i++)
220 	{
221 		n = round(i + d * (i - 128));
222 
223 		if(n < 0) n = 0;
224 		else if(n > 255) n = 255;
225 
226 		buf[i] = n;
227 	}
228 
229 	//
230 
231 	info->ptmp[0] = buf;
232 
233 	_color_common(info, _colfunc_brightcont);
234 
235 	mFree(buf);
236 
237 	return TRUE;
238 }
239 
240 
241 /** ガンマ補正 */
242 
FilterDraw_color_gamma(FilterDrawInfo * info)243 mBool FilterDraw_color_gamma(FilterDrawInfo *info)
244 {
245 	uint8_t *buf;
246 	int i,n;
247 	double d;
248 
249 	//テーブル作成
250 
251 	buf = (uint8_t *)mMalloc(256, FALSE);
252 	if(!buf) return FALSE;
253 
254 	d = 1.0 / (info->val_bar[0] * 0.01);
255 
256 	for(i = 0; i < 256; i++)
257 	{
258 		n = round(pow(i / 255.0, d) * 255);
259 
260 		if(n < 0) n = 0;
261 		else if(n > 255) n = 255;
262 
263 		buf[i] = n;
264 	}
265 
266 	//
267 
268 	info->ptmp[0] = buf;
269 
270 	_color_common(info, _colfunc_from_table);
271 
272 	mFree(buf);
273 
274 	return TRUE;
275 }
276 
277 
278 /** レベル補正 */
279 
FilterDraw_color_level(FilterDrawInfo * info)280 mBool FilterDraw_color_level(FilterDrawInfo *info)
281 {
282 	uint8_t *buf;
283 	int i,n,in_min,in_mid,in_max,out_min,out_max,out_mid;
284 	double d1,d2,d;
285 
286 	in_min = info->val_bar[0];
287 	in_mid = info->val_bar[1];
288 	in_max = info->val_bar[2];
289 	out_min = info->val_bar[3];
290 	out_max = info->val_bar[4];
291 
292 	out_mid = (out_max - out_min) >> 1;
293 
294 	d1 = (double)out_mid / (in_mid - in_min);
295 	d2 = (double)(out_max - out_min - out_mid) / (in_max - in_mid);
296 
297 	//テーブル作成
298 
299 	buf = (uint8_t *)mMalloc(256, FALSE);
300 	if(!buf) return FALSE;
301 
302 	for(i = 0; i < 256; i++)
303 	{
304 		//入力制限
305 
306 		n = i;
307 
308 		if(n < in_min) n = in_min;
309 		else if(n > in_max) n = in_max;
310 
311 		//補正
312 
313 		if(n < in_mid)
314 			d = (n - in_min) * d1;
315 		else
316 			d = (n - in_mid) * d2 + out_mid;
317 
318 		buf[i] = (int)(d + out_min + 0.5);
319 	}
320 
321 	//
322 
323 	info->ptmp[0] = buf;
324 
325 	_color_common(info, _colfunc_from_table);
326 
327 	mFree(buf);
328 
329 	return TRUE;
330 }
331 
332 
333 /** RGB 補正 */
334 
_colfunc_rgb(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)335 static void _colfunc_rgb(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
336 {
337 	int i,n;
338 
339 	for(i = 0; i < 3; i++)
340 	{
341 		n = pix->ar[i] + info->val_bar[i];
342 
343 		if(n < 0) n = 0;
344 		else if(n > 255) n = 255;
345 
346 		pix->ar[i] = n;
347 	}
348 }
349 
FilterDraw_color_rgb(FilterDrawInfo * info)350 mBool FilterDraw_color_rgb(FilterDrawInfo *info)
351 {
352 	return _color_common(info, _colfunc_rgb);
353 }
354 
355 
356 /** HSV 調整 */
357 
_colfunc_hsv(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)358 static void _colfunc_hsv(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
359 {
360 	double hsv[3];
361 	int c[3],i;
362 
363 	mRGBtoHSV(pix->r, pix->g, pix->b, hsv);
364 
365 	for(i = 0; i < 3; i++)
366 		hsv[i] += info->dtmp[i];
367 
368 	if(hsv[0] < 0) hsv[0] += 1;
369 	else if(hsv[0] >= 1.0) hsv[0] -= 1;
370 
371 	for(i = 1; i < 3; i++)
372 	{
373 		if(hsv[i] < 0) hsv[i] = 0;
374 		else if(hsv[i] > 1.0) hsv[i] = 1;
375 	}
376 
377 	mHSVtoRGB(hsv[0], hsv[1], hsv[2], c);
378 
379 	for(i = 0; i < 3; i++)
380 		pix->ar[i] = c[i];
381 }
382 
FilterDraw_color_hsv(FilterDrawInfo * info)383 mBool FilterDraw_color_hsv(FilterDrawInfo *info)
384 {
385 	info->dtmp[0] = info->val_bar[0] / 360.0;
386 	info->dtmp[1] = info->val_bar[1] / 100.0;
387 	info->dtmp[2] = info->val_bar[2] / 100.0;
388 
389 	return _color_common(info, _colfunc_hsv);
390 }
391 
392 /** HLS 調整 */
393 
_colfunc_hls(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)394 static void _colfunc_hls(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
395 {
396 	double d[3];
397 	int c[3],i;
398 
399 	mRGBtoHLS(pix->r, pix->g, pix->b, d);
400 
401 	for(i = 0; i < 3; i++)
402 		d[i] += info->dtmp[i];
403 
404 	if(d[0] < 0) d[0] += 1;
405 	else if(d[0] >= 1.0) d[0] -= 1;
406 
407 	for(i = 1; i < 3; i++)
408 	{
409 		if(d[i] < 0) d[i] = 0;
410 		else if(d[i] > 1.0) d[i] = 1;
411 	}
412 
413 	mHLStoRGB((int)(d[0] * 360 + 0.5), d[1], d[2], c);
414 
415 	for(i = 0; i < 3; i++)
416 		pix->ar[i] = c[i];
417 }
418 
FilterDraw_color_hls(FilterDrawInfo * info)419 mBool FilterDraw_color_hls(FilterDrawInfo *info)
420 {
421 	info->dtmp[0] = info->val_bar[0] / 360.0;
422 	info->dtmp[1] = info->val_bar[1] / 100.0;
423 	info->dtmp[2] = info->val_bar[2] / 100.0;
424 
425 	return _color_common(info, _colfunc_hls);
426 }
427 
428 /** ネガポジ反転 */
429 
_colfunc_nega(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)430 static void _colfunc_nega(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
431 {
432 	int i;
433 
434 	for(i = 0; i < 3; i++)
435 		pix->ar[i] = 255 - pix->ar[i];
436 }
437 
FilterDraw_color_nega(FilterDrawInfo * info)438 mBool FilterDraw_color_nega(FilterDrawInfo *info)
439 {
440 	return _color_common(info, _colfunc_nega);
441 }
442 
443 
444 /** グレイスケール */
445 
_colfunc_grayscale(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)446 static void _colfunc_grayscale(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
447 {
448 	pix->r = pix->g = pix->b = RGB_TO_GRAY(pix->r, pix->g, pix->b);
449 }
450 
FilterDraw_color_grayscale(FilterDrawInfo * info)451 mBool FilterDraw_color_grayscale(FilterDrawInfo *info)
452 {
453 	return _color_common(info, _colfunc_grayscale);
454 }
455 
456 
457 /** セピアカラー */
458 
_colfunc_sepia(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)459 static void _colfunc_sepia(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
460 {
461 	int v;
462 
463 	v = RGB_TO_GRAY(pix->r, pix->g, pix->b);
464 
465 	pix->r = (v + 30 > 255)? 255: v + 30;
466 	pix->g = v;
467 	pix->b = (v - 15 < 0)? 0: v - 15;
468 }
469 
FilterDraw_color_sepia(FilterDrawInfo * info)470 mBool FilterDraw_color_sepia(FilterDrawInfo *info)
471 {
472 	return _color_common(info, _colfunc_sepia);
473 }
474 
475 
476 /** グラデーションマップ */
477 
_colfunc_gradmap(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)478 static void _colfunc_gradmap(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
479 {
480 	int v;
481 
482 	v = RGB_TO_GRAY(pix->r, pix->g, pix->b);
483 
484 	TileImage_getGradationColor(pix, v / 255.0, (TileImageDrawGradInfo *)info->ptmp[0]);
485 }
486 
FilterDraw_color_gradmap(FilterDrawInfo * info)487 mBool FilterDraw_color_gradmap(FilterDrawInfo *info)
488 {
489 	TileImageDrawGradInfo ginfo;
490 
491 	drawOpSub_setDrawGradationInfo(&ginfo);
492 
493 	info->ptmp[0] = &ginfo;
494 
495 	return _color_common(info, _colfunc_gradmap);
496 }
497 
498 
499 /** 2値化 */
500 
_colfunc_threshold(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)501 static void _colfunc_threshold(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
502 {
503 	int v;
504 
505 	v = RGB_TO_GRAY(pix->r, pix->g, pix->b);
506 
507 	v = (v < info->val_bar[0])? 0: 255;
508 
509 	pix->r = pix->g = pix->b = v;
510 }
511 
FilterDraw_color_threshold(FilterDrawInfo * info)512 mBool FilterDraw_color_threshold(FilterDrawInfo *info)
513 {
514 	return _color_common(info, _colfunc_threshold);
515 }
516 
517 
518 /** 2値化 (ディザ) */
519 /*
520 	0:bayer2x2, 1:bayer4x4, 2:渦巻き4x4, 3:網点4x4, 4:ランダム
521 */
522 
_colfunc_threshold_dither(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)523 static void _colfunc_threshold_dither(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
524 {
525 	uint8_t val_bayer2x2[2][2] = {{0,2},{3,1}},
526 	val_4x4[3][4][4] = {
527 		{{0 ,8,2,10}, {12,4,14, 6}, {3,11, 1,9}, {15, 7,13, 5}},
528 		{{13,7,6,12}, { 8,1, 0, 5}, {9, 2, 3,4}, {14,10,11,15}},
529 		{{10,4,6, 8}, {12,0, 2,14}, {7, 9,11,5}, { 3,15,13, 1}}
530 	};
531 	int v,cmp;
532 
533 	//比較値
534 
535 	switch(info->val_combo[0])
536 	{
537 		case 0:
538 			cmp = val_bayer2x2[y & 1][x & 1] * 255 >> 2;
539 			break;
540 		case 1:
541 		case 2:
542 		case 3:
543 			cmp = val_4x4[info->val_combo[0] - 1][y & 3][x & 3] * 255 >> 4;
544 			break;
545 		case 4:
546 			cmp = mRandXorShift_getIntRange(0, 254);
547 			break;
548 	}
549 
550 	//
551 
552 	v = RGB_TO_GRAY(pix->r, pix->g, pix->b);
553 	v = (v <= cmp)? 0: 255;
554 
555 	pix->r = pix->g = pix->b = v;
556 }
557 
FilterDraw_color_threshold_dither(FilterDrawInfo * info)558 mBool FilterDraw_color_threshold_dither(FilterDrawInfo *info)
559 {
560 	return _color_common(info, _colfunc_threshold_dither);
561 }
562 
563 
564 /** ポスタリゼーション */
565 
FilterDraw_color_posterize(FilterDrawInfo * info)566 mBool FilterDraw_color_posterize(FilterDrawInfo *info)
567 {
568 	uint8_t *buf;
569 	int i,level,n;
570 
571 	//テーブル作成
572 
573 	buf = (uint8_t *)mMalloc(256, FALSE);
574 	if(!buf) return FALSE;
575 
576 	level = info->val_bar[0];
577 
578 	for(i = 0; i < 255; i++)
579 	{
580 		n = i * level / 255;
581 
582 		buf[i] = (n == level - 1)? 255: n * 255 / (level - 1);
583 	}
584 
585 	buf[255] = 255;
586 
587 	//
588 
589 	info->ptmp[0] = buf;
590 
591 	_color_common(info, _colfunc_from_table);
592 
593 	mFree(buf);
594 
595 	return TRUE;
596 }
597 
598 
599 //=============================
600 // 色置換
601 //=============================
602 
603 
604 /** 描画色置換 */
605 
_colfunc_replace_drawcol(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)606 static void _colfunc_replace_drawcol(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
607 {
608 	if(pix->r == info->pixdraw.r
609 		&& pix->g == info->pixdraw.g
610 		&& pix->b == info->pixdraw.b)
611 	{
612 		pix->r = info->val_bar[0];
613 		pix->g = info->val_bar[1];
614 		pix->b = info->val_bar[2];
615 	}
616 }
617 
FilterDraw_color_replace_drawcol(FilterDrawInfo * info)618 mBool FilterDraw_color_replace_drawcol(FilterDrawInfo *info)
619 {
620 	return _color_common(info, _colfunc_replace_drawcol);
621 }
622 
623 
624 /** 色置換 (共通) */
625 
_commfunc_replace(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)626 static mBool _commfunc_replace(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
627 {
628 	mBool drawcol = FALSE;
629 
630 	//描画色かどうか
631 
632 	if(pix->a && info->ntmp[0] < 3)
633 	{
634 		drawcol = (pix->r == info->pixdraw.r
635 			&& pix->g == info->pixdraw.g
636 			&& pix->b == info->pixdraw.b);
637 	}
638 
639 	//
640 
641 	switch(info->ntmp[0])
642 	{
643 		//描画色を透明に
644 		case 0:
645 			if(drawcol)
646 			{
647 				pix->c = 0;
648 				return TRUE;
649 			}
650 			break;
651 		//描画色以外を透明に
652 		case 1:
653 			if(pix->a && !drawcol)
654 			{
655 				pix->c = 0;
656 				return TRUE;
657 			}
658 			break;
659 		//描画色を背景色に
660 		case 2:
661 			if(drawcol)
662 			{
663 				pix->r = info->pixbkgnd.r;
664 				pix->g = info->pixbkgnd.g;
665 				pix->b = info->pixbkgnd.b;
666 				return TRUE;
667 			}
668 			break;
669 		//透明色を描画色に
670 		case 3:
671 			if(pix->a == 0)
672 			{
673 				*pix = info->pixdraw;
674 				return TRUE;
675 			}
676 			break;
677 	}
678 
679 	return FALSE;
680 }
681 
FilterDraw_color_replace(FilterDrawInfo * info)682 mBool FilterDraw_color_replace(FilterDrawInfo *info)
683 {
684 	return FilterSub_drawCommon(info, _commfunc_replace);
685 }
686 
687 
688 //=============================
689 // アルファ操作
690 //=============================
691 
692 
693 /** アルファ操作 (チェックレイヤ) */
694 
_commfunc_alpha_checked(FilterDrawInfo * info,int x,int y,PixelRGBA * pixdst)695 static mBool _commfunc_alpha_checked(FilterDrawInfo *info,int x,int y,PixelRGBA *pixdst)
696 {
697 	LayerItem *pi = (LayerItem *)info->ptmp[0];
698 	PixelRGBA pix;
699 	int type,a;
700 
701 	type = info->ntmp[0];
702 	a = pixdst->a;
703 
704 	switch(type)
705 	{
706 		//透明な部分を透明に
707 		//不透明な部分を透明に
708 		case 0:
709 		case 1:
710 			//各レイヤで不透明な点があるか
711 
712 			for(; pi; pi = pi->link)
713 			{
714 				TileImage_getPixel(pi->img, x, y, &pix);
715 
716 				if(pix.a) break;
717 			}
718 
719 			if((type == 0 && !pi) || (type == 1 && pi))
720 				a = 0;
721 			break;
722 		//値をコピー (対象上で透明な部分は除く)
723 		case 2:
724 			if(pixdst->a)
725 			{
726 				//各レイヤのアルファ値を合成
727 
728 				for(a = 0; pi; pi = pi->link)
729 				{
730 					TileImage_getPixel(pi->img, x, y, &pix);
731 
732 					a = (((a + pix.a) << 4) - ((a * pix.a << 4) / 255) + 8) >> 4; //4bit 固定少数点で
733 				}
734 			}
735 			break;
736 		//値を足す
737 		case 3:
738 			if(pixdst->a != 255)
739 			{
740 				for(; pi; pi = pi->link)
741 				{
742 					TileImage_getPixel(pi->img, x, y, &pix);
743 
744 					a += pix.a;
745 
746 					if(a >= 255)
747 					{
748 						a = 255;
749 						break;
750 					}
751 				}
752 			}
753 			break;
754 		//値を引く
755 		case 4:
756 			if(pixdst->a != 0)
757 			{
758 				for(; pi; pi = pi->link)
759 				{
760 					TileImage_getPixel(pi->img, x, y, &pix);
761 
762 					a -= pix.a;
763 
764 					if(a <= 0)
765 					{
766 						a = 0;
767 						break;
768 					}
769 				}
770 			}
771 			break;
772 		//値を乗算
773 		case 5:
774 			if(pixdst->a != 0)
775 			{
776 				for(; pi && a; pi = pi->link)
777 				{
778 					TileImage_getPixel(pi->img, x, y, &pix);
779 
780 					a = (a * pix.a + 127) / 255;
781 				}
782 			}
783 			break;
784 		//明るい色ほど透明に
785 		//暗い色ほど透明に
786 		case 6:
787 		case 7:
788 			TileImage_getPixel(pi->img, x, y, &pix);
789 
790 			if(pix.a)
791 			{
792 				a = RGB_TO_GRAY(pix.r, pix.g, pix.b);
793 				if(type == 6) a = 255 - a;
794 			}
795 			break;
796 	}
797 
798 	//アルファ値セット
799 
800 	if(a == pixdst->a)
801 		return FALSE;
802 	else
803 	{
804 		if(a == 0)
805 			pixdst->c = 0;
806 		else
807 			pixdst->a = a;
808 
809 		return TRUE;
810 	}
811 }
812 
FilterDraw_alpha_checked(FilterDrawInfo * info)813 mBool FilterDraw_alpha_checked(FilterDrawInfo *info)
814 {
815 	//チェックレイヤのリンクをセット
816 
817 	info->ptmp[0] = LayerList_setLink_checked(APP_DRAW->layerlist);
818 
819 	return FilterSub_drawCommon(info, _commfunc_alpha_checked);
820 }
821 
822 
823 /** アルファ操作 (カレント) */
824 
_commfunc_alpha_current(FilterDrawInfo * info,int x,int y,PixelRGBA * pix)825 static mBool _commfunc_alpha_current(FilterDrawInfo *info,int x,int y,PixelRGBA *pix)
826 {
827 	int a;
828 
829 	a = pix->a;
830 
831 	switch(info->ntmp[0])
832 	{
833 		//明るい色ほど透明に
834 		case 0:
835 			if(a)
836 				a = 255 - RGB_TO_GRAY(pix->r, pix->g, pix->b);
837 			break;
838 		//暗い色ほど透明に
839 		case 1:
840 			if(a)
841 				a = RGB_TO_GRAY(pix->r, pix->g, pix->b);
842 			break;
843 		//テクスチャ適用
844 		case 2:
845 			if(a)
846 				a = (a * ImageBuf8_getPixel_forTexture(APP_DRAW->tex.curimg, x, y) + 127) / 255;
847 			break;
848 		//アルファ値からグレイスケール作成
849 		case 3:
850 			pix->r = pix->g = pix->b = a;
851 			pix->a = 255;
852 			return TRUE;
853 		//透明以外をすべて完全不透明に
854 		case 4:
855 			if(a) a = 255;
856 			break;
857 	}
858 
859 	//アルファ値セット
860 
861 	if(a == pix->a)
862 		return FALSE;
863 	else
864 	{
865 		if(a == 0)
866 			pix->c = 0;
867 		else
868 			pix->a = a;
869 
870 		return TRUE;
871 	}
872 }
873 
FilterDraw_alpha_current(FilterDrawInfo * info)874 mBool FilterDraw_alpha_current(FilterDrawInfo *info)
875 {
876 	return FilterSub_drawCommon(info, _commfunc_alpha_current);
877 }
878 
879 
880