1/* Save a bit of typing.
2 */
3_colour_conv from to x = map_unary (colour_transform from to) x;
4
5/* convert Mono to various formats
6 */
7Mono_to = class {
8	/* convert mono colourspace to mono colourspace
9	 */
10	Mono x = _colour_conv Image_type.B_W Image_type.B_W x;
11
12	/* convert mono colourspace to XYZ colourspace
13	 */
14	XYZ x = _colour_conv Image_type.B_W Image_type.XYZ x;
15
16	/* convert mono colourspace to Yxy colourspace
17	 */
18	Yxy x = _colour_conv Image_type.B_W Image_type.YXY x;
19
20	/* convert mono colourspace to Lab colourspace
21	 */
22	Lab x = _colour_conv Image_type.B_W Image_type.LAB x;
23
24	/* convert mono colourspace to LCh colourspace
25	 */
26	LCh x = _colour_conv Image_type.B_W Image_type.LCH x;
27
28	/* convert mono colourspace to UCS colourspace
29	 */
30	UCS x = _colour_conv Image_type.B_W Image_type.UCS x;
31
32	/* convert mono colourspace to RGB colourspace
33	 */
34	RGB x = _colour_conv Image_type.B_W Image_type.RGB x;
35
36	/* convert mono colourspace to sRGB colourspace
37	 */
38	sRGB x = _colour_conv Image_type.B_W Image_type.sRGB x;
39
40	/* convert mono colourspace to LabQ colourspace
41	 */
42	LabQ x = _colour_conv Image_type.B_W Image_type.LABQ x;
43
44	/* convert mono colourspace to LabS colourspace
45	 */
46	LabS x = _colour_conv Image_type.B_W Image_type.LABS x;
47}
48
49/* convert XYZ to various formats
50 */
51XYZ_to = class {
52	/* convert XYZ colourspace to mono colourspace
53	 */
54	Mono x = _colour_conv Image_type.XYZ Image_type.B_W x;
55
56	/* convert XYZ colourspace to XYZ colourspace
57	 */
58	XYZ x = _colour_conv Image_type.XYZ Image_type.XYZ x;
59
60	/* convert XYZ colourspace to Yxy colourspace
61	 */
62	Yxy x = _colour_conv Image_type.XYZ Image_type.YXY x;
63
64	/* convert XYZ colourspace to Lab colourspace
65	 */
66	Lab x = _colour_conv Image_type.XYZ Image_type.LAB x;
67
68	/* convert XYZ colourspace to LCh colourspace
69	 */
70	LCh x = _colour_conv Image_type.XYZ Image_type.LCH x;
71
72	/* convert XYZ colourspace to UCS colourspace
73	 */
74	UCS x = _colour_conv Image_type.XYZ Image_type.UCS x;
75
76	/* convert XYZ colourspace to RGB colourspace
77	 */
78	RGB x = _colour_conv Image_type.XYZ Image_type.RGB x;
79
80	/* convert XYZ colourspace to sRGB colourspace
81	 */
82	sRGB x = _colour_conv Image_type.XYZ Image_type.sRGB x;
83
84	/* convert XYZ colourspace to LabQ colourspace
85	 */
86	LabQ x = _colour_conv Image_type.XYZ Image_type.LABQ x;
87
88	/* convert XYZ colourspace to LabS colourspace
89	 */
90	LabS x = _colour_conv Image_type.XYZ Image_type.LABS x;
91}
92
93/* convert Yxy to various formats
94 */
95Yxy_to = class {
96	/* convert Yxy colourspace to mono colourspace
97	 */
98	Mono x = _colour_conv Image_type.YXY Image_type.B_W x;
99
100	/* convert Yxy colourspace to XYZ colourspace
101	 */
102	XYZ x = _colour_conv Image_type.YXY Image_type.XYZ x;
103
104	/* convert Yxy colourspace to Yxy colourspace
105	 */
106	Yxy x = _colour_conv Image_type.YXY Image_type.YXY x;
107
108	/* convert Yxy colourspace to Lab colourspace
109	 */
110	Lab x = _colour_conv Image_type.YXY Image_type.LAB x;
111
112	/* convert Yxy colourspace to LCh colourspace
113	 */
114	LCh x = _colour_conv Image_type.YXY Image_type.LCH x;
115
116	/* convert Yxy colourspace to UCS colourspace
117	 */
118	UCS x = _colour_conv Image_type.YXY Image_type.UCS x;
119
120	/* convert Yxy colourspace to RGB colourspace
121	 */
122	RGB x = _colour_conv Image_type.YXY Image_type.RGB x;
123
124	/* convert Yxy colourspace to sRGB colourspace
125	 */
126	sRGB x = _colour_conv Image_type.YXY Image_type.sRGB x;
127
128	/* convert Yxy colourspace to LabQ colourspace
129	 */
130	LabQ x = _colour_conv Image_type.YXY Image_type.LABQ x;
131
132	/* convert Yxy colourspace to LabS colourspace
133	 */
134	LabS x = _colour_conv Image_type.YXY Image_type.LABS x;
135}
136
137/* convert Lab to various formats
138 */
139Lab_to = class {
140	/* convert Lab colourspace to mono colourspace
141	 */
142	Mono x = _colour_conv Image_type.LAB Image_type.B_W x;
143
144	/* convert Lab colourspace to XYZ colourspace
145	 */
146	XYZ x = _colour_conv Image_type.LAB Image_type.XYZ x;
147
148	/* convert Lab colourspace to Yxy colourspace
149	 */
150	Yxy x = _colour_conv Image_type.LAB Image_type.YXY x;
151
152	/* convert Lab colourspace to Lab colourspace
153	 */
154	Lab x = _colour_conv Image_type.LAB Image_type.LAB x;
155
156	/* convert Lab colourspace to LCh colourspace
157	 */
158	LCh x = _colour_conv Image_type.LAB Image_type.LCH x;
159
160	/* convert Lab colourspace to UCS colourspace
161	 */
162	UCS x = _colour_conv Image_type.LAB Image_type.UCS x;
163
164	/* convert Lab colourspace to RGB colourspace
165	 */
166	RGB x = _colour_conv Image_type.LAB Image_type.RGB x;
167
168	/* convert Lab colourspace to sRGB colourspace
169	 */
170	sRGB x = _colour_conv Image_type.LAB Image_type.sRGB x;
171
172	/* convert Lab colourspace to LabQ colourspace
173	 */
174	LabQ x = _colour_conv Image_type.LAB Image_type.LABQ x;
175
176	/* convert Lab colourspace to LabS colourspace
177	 */
178	LabS x = _colour_conv Image_type.LAB Image_type.LABS x;
179}
180
181/* convert LCh to various formats
182 */
183LCh_to = class {
184	/* convert LCh colourspace to mono colourspace
185	 */
186	Mono x = _colour_conv Image_type.LCH Image_type.B_W x;
187
188	/* convert LCh colourspace to XYZ colourspace
189	 */
190	XYZ x = _colour_conv Image_type.LCH Image_type.XYZ x;
191
192	/* convert LCh colourspace to Yxy colourspace
193	 */
194	Yxy x = _colour_conv Image_type.LCH Image_type.YXY x;
195
196	/* convert LCh colourspace to Lab colourspace
197	 */
198	Lab x = _colour_conv Image_type.LCH Image_type.LAB x;
199
200	/* convert LCh colourspace to LCh colourspace
201	 */
202	LCh x = _colour_conv Image_type.LCH Image_type.LCH x;
203
204	/* convert LCh colourspace to UCS colourspace
205	 */
206	UCS x = _colour_conv Image_type.LCH Image_type.UCS x;
207
208	/* convert LCh colourspace to RGB colourspace
209	 */
210	RGB x = _colour_conv Image_type.LCH Image_type.RGB x;
211
212	/* convert LCh colourspace to sRGB colourspace
213	 */
214	sRGB x = _colour_conv Image_type.LCH Image_type.sRGB x;
215
216	/* convert LCh colourspace to LabQ colourspace
217	 */
218	LabQ x = _colour_conv Image_type.LCH Image_type.LABQ x;
219
220	/* convert LCh colourspace to LabS colourspace
221	 */
222	LabS x = _colour_conv Image_type.LCH Image_type.LABS x;
223}
224
225/* convert UCS to various formats
226 */
227UCS_to = class {
228	/* convert UCS colourspace to mono colourspace
229	 */
230	Mono x = _colour_conv Image_type.UCS Image_type.B_W x;
231
232	/* convert UCS colourspace to XYZ colourspace
233	 */
234	XYZ x = _colour_conv Image_type.UCS Image_type.XYZ x;
235
236	/* convert UCS colourspace to Yxy colourspace
237	 */
238	Yxy x = _colour_conv Image_type.UCS Image_type.YXY x;
239
240	/* convert UCS colourspace to Lab colourspace
241	 */
242	Lab x = _colour_conv Image_type.UCS Image_type.LAB x;
243
244	/* convert UCS colourspace to LCh colourspace
245	 */
246	LCh x = _colour_conv Image_type.UCS Image_type.LCH x;
247
248	/* convert UCS colourspace to UCS colourspace
249	 */
250	UCS x = _colour_conv Image_type.UCS Image_type.UCS x;
251
252	/* convert UCS colourspace to RGB colourspace
253	 */
254	RGB x = _colour_conv Image_type.UCS Image_type.RGB x;
255
256	/* convert UCS colourspace to sRGB colourspace
257	 */
258	sRGB x = _colour_conv Image_type.UCS Image_type.sRGB x;
259
260	/* convert UCS colourspace to LabQ colourspace
261	 */
262	LabQ x = _colour_conv Image_type.UCS Image_type.LABQ x;
263
264	/* convert UCS colourspace to LabS colourspace
265	 */
266	LabS x = _colour_conv Image_type.UCS Image_type.LABS x;
267}
268
269/* convert RGB to various formats
270 */
271RGB_to = class {
272	/* convert RGB colourspace to mono colourspace
273	 */
274	Mono x = _colour_conv Image_type.RGB Image_type.B_W x;
275
276	/* convert RGB colourspace to XYZ colourspace
277	 */
278	XYZ x = _colour_conv Image_type.RGB Image_type.XYZ x;
279
280	/* convert RGB colourspace to Yxy colourspace
281	 */
282	Yxy x = _colour_conv Image_type.RGB Image_type.YXY x;
283
284	/* convert RGB colourspace to Lab colourspace
285	 */
286	Lab x = _colour_conv Image_type.RGB Image_type.LAB x;
287
288	/* convert RGB colourspace to LCh colourspace
289	 */
290	LCh x = _colour_conv Image_type.RGB Image_type.LCH x;
291
292	/* convert RGB colourspace to UCS colourspace
293	 */
294	UCS x = _colour_conv Image_type.RGB Image_type.UCS x;
295
296	/* convert RGB colourspace to RGB colourspace
297	 */
298	RGB x = _colour_conv Image_type.RGB Image_type.RGB x;
299
300	/* convert RGB colourspace to sRGB colourspace
301	 */
302	sRGB x = _colour_conv Image_type.RGB Image_type.sRGB x;
303
304	/* convert RGB colourspace to LabQ colourspace
305	 */
306	LabQ x = _colour_conv Image_type.RGB Image_type.LABQ x;
307
308	/* convert RGB colourspace to LabS colourspace
309	 */
310	LabS x = _colour_conv Image_type.RGB Image_type.LABS x;
311}
312
313/* convert sRGB to various formats
314 */
315sRGB_to = class {
316	/* convert sRGB colourspace to mono colourspace
317	 */
318	Mono x = _colour_conv Image_type.sRGB Image_type.B_W x;
319
320	/* convert sRGB colourspace to XYZ colourspace
321	 */
322	XYZ x = _colour_conv Image_type.sRGB Image_type.XYZ x;
323
324	/* convert sRGB colourspace to Yxy colourspace
325	 */
326	Yxy x = _colour_conv Image_type.sRGB Image_type.YXY x;
327
328	/* convert sRGB colourspace to Lab colourspace
329	 */
330	Lab x = _colour_conv Image_type.sRGB Image_type.LAB x;
331
332	/* convert sRGB colourspace to LCh colourspace
333	 */
334	LCh x = _colour_conv Image_type.sRGB Image_type.LCH x;
335
336	/* convert sRGB colourspace to UCS colourspace
337	 */
338	UCS x = _colour_conv Image_type.sRGB Image_type.UCS x;
339
340	/* convert sRGB colourspace to RGB colourspace
341	 */
342	RGB x = _colour_conv Image_type.sRGB Image_type.RGB x;
343
344	/* convert sRGB colourspace to sRGB colourspace
345	 */
346	sRGB x = _colour_conv Image_type.sRGB Image_type.sRGB x;
347
348	/* convert sRGB colourspace to LabQ colourspace
349	 */
350	LabQ x = _colour_conv Image_type.sRGB Image_type.LABQ x;
351
352	/* convert sRGB colourspace to LabS colourspace
353	 */
354	LabS x = _colour_conv Image_type.sRGB Image_type.LABS x;
355}
356
357/* convert LabQ to various formats
358 */
359LabQ_to = class {
360	/* convert LabQ colourspace to mono colourspace
361	 */
362	Mono x = _colour_conv Image_type.LABQ Image_type.B_W x;
363
364	/* convert LabQ colourspace to XYZ colourspace
365	 */
366	XYZ x = _colour_conv Image_type.LABQ Image_type.XYZ x;
367
368	/* convert LabQ colourspace to Yxy colourspace
369	 */
370	Yxy x = _colour_conv Image_type.LABQ Image_type.YXY x;
371
372	/* convert LabQ colourspace to Lab colourspace
373	 */
374	Lab x = _colour_conv Image_type.LABQ Image_type.LAB x;
375
376	/* convert LabQ colourspace to LCh colourspace
377	 */
378	LCh x = _colour_conv Image_type.LABQ Image_type.LCH x;
379
380	/* convert LabQ colourspace to UCS colourspace
381	 */
382	UCS x = _colour_conv Image_type.LABQ Image_type.UCS x;
383
384	/* convert LabQ colourspace to RGB colourspace
385	 */
386	RGB x = _colour_conv Image_type.LABQ Image_type.RGB x;
387
388	/* convert LabQ colourspace to sRGB colourspace
389	 */
390	sRGB x = _colour_conv Image_type.LABQ Image_type.sRGB x;
391
392	/* convert LabQ colourspace to LabQ colourspace
393	 */
394	LabQ x = _colour_conv Image_type.LABQ Image_type.LABQ x;
395
396	/* convert LabQ colourspace to LabS colourspace
397	 */
398	LabS x = _colour_conv Image_type.LABQ Image_type.LABS x;
399}
400
401/* convert LabS to various formats
402 */
403LabS_to = class {
404	/* convert LabS colourspace to mono colourspace
405	 */
406	Mono x = _colour_conv Image_type.LABS Image_type.B_W x;
407
408	/* convert LabS colourspace to XYZ colourspace
409	 */
410	XYZ x = _colour_conv Image_type.LABS Image_type.XYZ x;
411
412	/* convert LabS colourspace to Yxy colourspace
413	 */
414	Yxy x = _colour_conv Image_type.LABS Image_type.YXY x;
415
416	/* convert LabS colourspace to Lab colourspace
417	 */
418	Lab x = _colour_conv Image_type.LABS Image_type.LAB x;
419
420	/* convert LabS colourspace to LCh colourspace
421	 */
422	LCh x = _colour_conv Image_type.LABS Image_type.LCH x;
423
424	/* convert LabS colourspace to UCS colourspace
425	 */
426	UCS x = _colour_conv Image_type.LABS Image_type.UCS x;
427
428	/* convert LabS colourspace to RGB colourspace
429	 */
430	RGB x = _colour_conv Image_type.LABS Image_type.RGB x;
431
432	/* convert LabS colourspace to sRGB colourspace
433	 */
434	sRGB x = _colour_conv Image_type.LABS Image_type.sRGB x;
435
436	/* convert LabS colourspace to LabQ colourspace
437	 */
438	LabQ x = _colour_conv Image_type.LABS Image_type.LABQ x;
439
440	/* convert LabS colourspace to LabS colourspace
441	 */
442	LabS x = _colour_conv Image_type.LABS Image_type.LABS x;
443}
444
445#separator
446
447/* recombine image bands with an editable matrix
448 */
449Colour_recombination in
450	= map_unary widget in
451{
452	widget image = class
453		Image value {
454		_check_args = [
455			[image, "image", check_Image]
456		] ++ super._check_args;
457		_vislevel = 3;
458
459		matrix = Matrix_rec (identity_matrix image.bands);
460
461		value = recomb matrix image.value;
462	}
463}
464
465/* colour temperature conversions
466 */
467Colour_temperature = class {
468	/* convert XYZ from D65 to D50 ... use the Bradford approximation
469	 */
470	D65XYZ_to_D50XYZ in = map_unary (colour_unary im_D652D50) in;
471
472	/* convert XYZ from D50 to D65 ... use the Bradford approximation
473	 */
474	D50XYZ_to_D65XYZ in = map_unary (colour_unary im_D502D65) in;
475}
476
477/* various colour difference metrics
478 */
479dE_ = class {
480	/* Apply a converter to an object ... convert image or colour (since
481	 * we can guess the colour space we're converting from), don't convert
482	 * matrix or vector (since we can't tell ... assume it's in the right
483	 * space already).
484	 */
485	_apply_cvt cvt x
486		= cvt x,
487			is_instanceof "Image" x || is_instanceof "Colour" x ||
488			is_image x
489		= x;
490
491	_diff cvt in1 in2 = abs_vec (_apply_cvt cvt in1 - _apply_cvt cvt in2);
492
493	/* Converter to LAB.
494	 */
495	_lab_cvt = colour_transform_to Image_type.LAB;
496
497	/* Converter to UCS ... plain UCS is Ch form, so we go LAB again after
498	 * to make sure we get a rectangular coord system.
499	 */
500	_ucs_cvt = colour_transform Image_type.LCH Image_type.LAB @
501		colour_transform_to Image_type.UCS;
502
503	/* calculate delta-E CIE76 for two objects
504	 */
505	CIE76 in1 in2 = map_binary (_diff _lab_cvt) in1 in2;
506
507	/* calculate delta-E00 (CIEDE2000) for two objects
508	 */
509	CIE00 in1 in2 = map_binary
510		(colour_binary "im_dE00_fromLab" im_dE00_fromLab) in1 in2;
511
512	/* calculate delta-E CMC(1:1) for two objects
513	 */
514	UCS in1 in2 = map_binary (_diff _ucs_cvt) in1 in2;
515}
516
517#separator
518
519/* apply a coloured tint to a monochrome image
520 */
521Tint_mono_image in
522	= map_unary apply_tint in
523{
524	apply_tint in = class
525		Image value {
526		_check_args = [
527			[in, "in", check_Image]
528		] ++ super._check_args;
529		_vislevel = 3;
530
531		tint = Colour "Lab" [50, 0, 0];
532
533		value = image_set_type Image_type.LAB
534			(fancytint inp l_tint a_tint b_tint)
535		{
536			// input image ... to L only
537			inp_lab = colour_transform_to Image_type.LAB in.value;
538			inp = inp_lab?0;
539
540			// make sure tint is LAB (might be edited)
541			lab_tint = colour_transform_to Image_type.LAB tint;
542
543			// selected lab
544			l_tint = lab_tint.value?0;
545			a_tint = lab_tint.value?1;
546			b_tint = lab_tint.value?2;
547
548			// fancy tint function ... don't tint black and white
549			fancytint im l a b
550				= im ++ ima ++ imb
551			{
552				mod
553					= (100 - im) / (100 - l), im > l
554					= im / l;
555
556				backgr = image_new in.width in.height 1
557					Image_format.FLOAT
558					Image_coding.NOCODING
559					Image_type.B_W 0 0 0;
560
561				ima = mod * (backgr + a);
562				imb = mod * (backgr + b);
563			}
564		}
565	}
566}
567
568/* displace neutral axis in LAB colourspace
569 */
570Adjust_cast image
571	= map_unary widget image
572{
573	widget image = class
574		Image value {
575		_check_args = [
576			[image, "Image", check_Image]
577		] ++ super._check_args;
578		_vislevel = 3;
579
580		green_red = Slider (-20) 20 0;
581		blue_yellow = Slider (-20) 20 0;
582
583		value
584			= (colour_transform_to (get_type image) image'').value
585		{
586			image' = colour_transform_to Image_type.LAB image;
587			image'' = image' +
588				Vector [0, green_red.value, blue_yellow.value];
589		}
590	}
591}
592
593/* displace h, scale LC in LCh colourspace
594 */
595Adjust_hue_saturation_brightness image
596	= map_unary widget image
597{
598	widget image = class
599		Image value {
600		_check_args = [
601			[image, "Image", check_Image]
602		] ++ super._check_args;
603		_vislevel = 3;
604
605		hue = Slider 0 360 0;
606		saturation = Slider 0.01 5 1;
607		brightness = Slider 0.01 5 1;
608
609		value
610			= (colour_transform_to (get_type image) image'').value
611		{
612			image' = colour_transform_to Image_type.LCH image;
613			image'' =
614				image' * Vector [bv, sv, 1] + Vector [0, 0, hv];
615			bv = brightness.value;
616			sv = saturation.value;
617			hv = hue.value;
618		}
619	}
620}
621
622/* find pixels with a similar colour
623 */
624Similar_colour image
625	= map_unary match image
626{
627	match image = class
628		Image value {
629		_check_args = [
630			[image, "Image", check_Image]
631		] ++ super._check_args;
632		_vislevel = 3;
633
634		target_patch = Region image
635			(20 - image.xoffset)
636			(20 - image.yoffset)
637			10 10;
638		target_colour = Colour_from_image target_patch;
639		dE_threshold = Slider 0 100 10;
640
641		value = (dE_.CIE76 image target_colour < dE_threshold).value;
642	}
643}
644
645/* plot an ab scatter histogram
646 */
647Plot_ab_scatter image
648	= map_unary widget image
649{
650	widget image = class
651		Image value {
652		_check_args = [
653			[image, "Image", check_Image]
654		] ++ super._check_args;
655		_vislevel = 3;
656
657		bins = 8;
658
659		value
660			= bg * (((90 / mx) * hist) ++ blk)
661		{
662			lab = colour_transform_to Image_type.LAB image.value;
663			ab = (unsigned char) ((lab?1 ++ lab?2) + 128);
664			hist = hist_find_nD bins ab;
665			mx = max hist;
666			bg = lab_slice bins 1;
667			blk = 1 + im_black bins bins 2;
668		}
669	}
670}
671
672
673
674
675