1package gift
2
3import (
4	"image"
5	"testing"
6)
7
8func TestMedian(t *testing.T) {
9	testData := []struct {
10		desc           string
11		ksize          int
12		disk           bool
13		srcb, dstb     image.Rectangle
14		srcPix, dstPix []uint8
15	}{
16		{
17			"median (0, false)",
18			0, false,
19			image.Rect(-1, -1, 4, 2),
20			image.Rect(0, 0, 5, 3),
21			[]uint8{
22				0x11, 0x99, 0x55, 0x22, 0x66,
23				0xFF, 0x44, 0xFF, 0xCC, 0x00,
24				0x33, 0x77, 0xBB, 0x88, 0xEE,
25			},
26			[]uint8{
27				0x11, 0x99, 0x55, 0x22, 0x66,
28				0xFF, 0x44, 0xFF, 0xCC, 0x00,
29				0x33, 0x77, 0xBB, 0x88, 0xEE,
30			},
31		},
32		{
33			"median (1, false)",
34			1, false,
35			image.Rect(-1, -1, 4, 2),
36			image.Rect(0, 0, 5, 3),
37			[]uint8{
38				0x11, 0x99, 0x55, 0x22, 0x66,
39				0xFF, 0x44, 0xFF, 0xCC, 0x00,
40				0x33, 0x77, 0xBB, 0x88, 0xEE,
41			},
42			[]uint8{
43				0x11, 0x99, 0x55, 0x22, 0x66,
44				0xFF, 0x44, 0xFF, 0xCC, 0x00,
45				0x33, 0x77, 0xBB, 0x88, 0xEE,
46			},
47		},
48		{
49			"median (2, false)",
50			2, false,
51			image.Rect(-1, -1, 4, 2),
52			image.Rect(0, 0, 5, 3),
53			[]uint8{
54				0x11, 0x99, 0x55, 0x22, 0x66,
55				0xFF, 0x44, 0xFF, 0xCC, 0x00,
56				0x33, 0x77, 0xBB, 0x88, 0xEE,
57			},
58			[]uint8{
59				0x11, 0x99, 0x55, 0x22, 0x66,
60				0xFF, 0x44, 0xFF, 0xCC, 0x00,
61				0x33, 0x77, 0xBB, 0x88, 0xEE,
62			},
63		},
64		{
65			"median (3, false)",
66			3, false,
67			image.Rect(-1, -1, 4, 2),
68			image.Rect(0, 0, 5, 3),
69			[]uint8{
70				0x11, 0x99, 0x55, 0x22, 0x66,
71				0xFF, 0x44, 0xFF, 0xCC, 0x00,
72				0x33, 0x77, 0xBB, 0x88, 0xEE,
73			},
74			[]uint8{
75				0x44, 0x55, 0x55, 0x55, 0x66,
76				0x44, 0x77, 0x88, 0x88, 0x66,
77				0x44, 0x77, 0x88, 0xBB, 0xCC,
78			},
79		},
80		{
81			"median (3, true)",
82			3, true,
83			image.Rect(-1, -1, 4, 2),
84			image.Rect(0, 0, 5, 3),
85			[]uint8{
86				0x11, 0x99, 0x55, 0x22, 0x66,
87				0xFF, 0x44, 0xFF, 0xCC, 0x00,
88				0x33, 0x77, 0xBB, 0x88, 0xEE,
89			},
90			[]uint8{
91				0x11, 0x55, 0x55, 0x55, 0x66,
92				0x44, 0x99, 0xBB, 0x88, 0x66,
93				0x33, 0x77, 0xBB, 0xBB, 0xEE,
94			},
95		},
96		{
97			"median (4, true)",
98			4, true,
99			image.Rect(-1, -1, 4, 2),
100			image.Rect(0, 0, 5, 3),
101			[]uint8{
102				0x11, 0x99, 0x55, 0x22, 0x66,
103				0xFF, 0x44, 0xFF, 0xCC, 0x00,
104				0x33, 0x77, 0xBB, 0x88, 0xEE,
105			},
106			[]uint8{
107				0x11, 0x55, 0x55, 0x55, 0x66,
108				0x44, 0x99, 0xBB, 0x88, 0x66,
109				0x33, 0x77, 0xBB, 0xBB, 0xEE,
110			},
111		},
112	}
113
114	for _, d := range testData {
115		src := image.NewGray(d.srcb)
116		src.Pix = d.srcPix
117
118		f := Median(d.ksize, d.disk)
119		dst := image.NewGray(f.Bounds(src.Bounds()))
120		f.Draw(dst, src, nil)
121
122		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
123			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
124		}
125	}
126
127	testDataNRGBA := []struct {
128		desc           string
129		ksize          int
130		disk           bool
131		srcb, dstb     image.Rectangle
132		srcPix, dstPix []uint8
133	}{
134		{
135			"median nrgba (3, true)",
136			3, true,
137			image.Rect(-1, -1, 4, 2),
138			image.Rect(0, 0, 5, 3),
139			[]uint8{
140				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66,
141				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00,
142				0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE,
143			},
144			[]uint8{
145				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x66,
146				0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x66,
147				0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xEE,
148			},
149		},
150	}
151
152	for _, d := range testDataNRGBA {
153		src := image.NewNRGBA(d.srcb)
154		src.Pix = d.srcPix
155
156		f := Median(d.ksize, d.disk)
157		dst := image.NewNRGBA(f.Bounds(src.Bounds()))
158		f.Draw(dst, src, nil)
159
160		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
161			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
162		}
163	}
164
165	// check no panics
166	Median(5, false).Draw(image.NewGray(image.Rect(0, 0, 1, 1)), image.NewGray(image.Rect(0, 0, 1, 1)), nil)
167	Median(5, false).Draw(image.NewGray(image.Rect(0, 0, 0, 0)), image.NewGray(image.Rect(0, 0, 0, 0)), nil)
168}
169
170func TestMinimum(t *testing.T) {
171	testData := []struct {
172		desc           string
173		ksize          int
174		disk           bool
175		srcb, dstb     image.Rectangle
176		srcPix, dstPix []uint8
177	}{
178		{
179			"minimum (0, false)",
180			0, false,
181			image.Rect(-1, -1, 4, 2),
182			image.Rect(0, 0, 5, 3),
183			[]uint8{
184				0x11, 0x99, 0x55, 0x22, 0x66,
185				0xFF, 0x44, 0xFF, 0xCC, 0x00,
186				0x33, 0x77, 0xBB, 0x88, 0xEE,
187			},
188			[]uint8{
189				0x11, 0x99, 0x55, 0x22, 0x66,
190				0xFF, 0x44, 0xFF, 0xCC, 0x00,
191				0x33, 0x77, 0xBB, 0x88, 0xEE,
192			},
193		},
194		{
195			"minimum (1, false)",
196			1, false,
197			image.Rect(-1, -1, 4, 2),
198			image.Rect(0, 0, 5, 3),
199			[]uint8{
200				0x11, 0x99, 0x55, 0x22, 0x66,
201				0xFF, 0x44, 0xFF, 0xCC, 0x00,
202				0x33, 0x77, 0xBB, 0x88, 0xEE,
203			},
204			[]uint8{
205				0x11, 0x99, 0x55, 0x22, 0x66,
206				0xFF, 0x44, 0xFF, 0xCC, 0x00,
207				0x33, 0x77, 0xBB, 0x88, 0xEE,
208			},
209		},
210		{
211			"minimum (2, false)",
212			2, false,
213			image.Rect(-1, -1, 4, 2),
214			image.Rect(0, 0, 5, 3),
215			[]uint8{
216				0x11, 0x99, 0x55, 0x22, 0x66,
217				0xFF, 0x44, 0xFF, 0xCC, 0x00,
218				0x33, 0x77, 0xBB, 0x88, 0xEE,
219			},
220			[]uint8{
221				0x11, 0x99, 0x55, 0x22, 0x66,
222				0xFF, 0x44, 0xFF, 0xCC, 0x00,
223				0x33, 0x77, 0xBB, 0x88, 0xEE,
224			},
225		},
226		{
227			"minimum (3, false)",
228			3, false,
229			image.Rect(-1, -1, 4, 2),
230			image.Rect(0, 0, 5, 3),
231			[]uint8{
232				0x11, 0x99, 0x55, 0x22, 0x66,
233				0xFF, 0x44, 0xFF, 0xCC, 0x00,
234				0x33, 0x77, 0xBB, 0x88, 0xEE,
235			},
236			[]uint8{
237				0x11, 0x11, 0x22, 0x00, 0x00,
238				0x11, 0x11, 0x22, 0x00, 0x00,
239				0x33, 0x33, 0x44, 0x00, 0x00,
240			},
241		},
242		{
243			"minimum (3, true)",
244			3, true,
245			image.Rect(-1, -1, 4, 2),
246			image.Rect(0, 0, 5, 3),
247			[]uint8{
248				0x11, 0x99, 0x55, 0x22, 0x66,
249				0xFF, 0x44, 0xFF, 0xCC, 0x00,
250				0x33, 0x77, 0xBB, 0x88, 0xEE,
251			},
252			[]uint8{
253				0x11, 0x11, 0x22, 0x22, 0x00,
254				0x11, 0x44, 0x44, 0x00, 0x00,
255				0x33, 0x33, 0x77, 0x88, 0x00,
256			},
257		},
258		{
259			"minimum (4, true)",
260			4, true,
261			image.Rect(-1, -1, 4, 2),
262			image.Rect(0, 0, 5, 3),
263			[]uint8{
264				0x11, 0x99, 0x55, 0x22, 0x66,
265				0xFF, 0x44, 0xFF, 0xCC, 0x00,
266				0x33, 0x77, 0xBB, 0x88, 0xEE,
267			},
268			[]uint8{
269				0x11, 0x11, 0x22, 0x22, 0x00,
270				0x11, 0x44, 0x44, 0x00, 0x00,
271				0x33, 0x33, 0x77, 0x88, 0x00,
272			},
273		},
274	}
275
276	for _, d := range testData {
277		src := image.NewGray(d.srcb)
278		src.Pix = d.srcPix
279
280		f := Minimum(d.ksize, d.disk)
281		dst := image.NewGray(f.Bounds(src.Bounds()))
282		f.Draw(dst, src, nil)
283
284		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
285			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
286		}
287	}
288
289	testDataNRGBA := []struct {
290		desc           string
291		ksize          int
292		disk           bool
293		srcb, dstb     image.Rectangle
294		srcPix, dstPix []uint8
295	}{
296		{
297			"minimum nrgba (3, true)",
298			3, true,
299			image.Rect(-1, -1, 4, 2),
300			image.Rect(0, 0, 5, 3),
301			[]uint8{
302				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66,
303				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00,
304				0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE,
305			},
306			[]uint8{
307				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
308				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309				0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00,
310			},
311		},
312	}
313
314	for _, d := range testDataNRGBA {
315		src := image.NewNRGBA(d.srcb)
316		src.Pix = d.srcPix
317
318		f := Minimum(d.ksize, d.disk)
319		dst := image.NewNRGBA(f.Bounds(src.Bounds()))
320		f.Draw(dst, src, nil)
321
322		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
323			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
324		}
325	}
326}
327
328func TestMaximum(t *testing.T) {
329	testData := []struct {
330		desc           string
331		ksize          int
332		disk           bool
333		srcb, dstb     image.Rectangle
334		srcPix, dstPix []uint8
335	}{
336		{
337			"maximum (0, false)",
338			0, false,
339			image.Rect(-1, -1, 4, 2),
340			image.Rect(0, 0, 5, 3),
341			[]uint8{
342				0x11, 0x99, 0x55, 0x22, 0x66,
343				0xFF, 0x44, 0xFF, 0xCC, 0x00,
344				0x33, 0x77, 0xBB, 0x88, 0xEE,
345			},
346			[]uint8{
347				0x11, 0x99, 0x55, 0x22, 0x66,
348				0xFF, 0x44, 0xFF, 0xCC, 0x00,
349				0x33, 0x77, 0xBB, 0x88, 0xEE,
350			},
351		},
352		{
353			"maximum (1, false)",
354			1, false,
355			image.Rect(-1, -1, 4, 2),
356			image.Rect(0, 0, 5, 3),
357			[]uint8{
358				0x11, 0x99, 0x55, 0x22, 0x66,
359				0xFF, 0x44, 0xFF, 0xCC, 0x00,
360				0x33, 0x77, 0xBB, 0x88, 0xEE,
361			},
362			[]uint8{
363				0x11, 0x99, 0x55, 0x22, 0x66,
364				0xFF, 0x44, 0xFF, 0xCC, 0x00,
365				0x33, 0x77, 0xBB, 0x88, 0xEE,
366			},
367		},
368		{
369			"maximum (2, false)",
370			2, false,
371			image.Rect(-1, -1, 4, 2),
372			image.Rect(0, 0, 5, 3),
373			[]uint8{
374				0x11, 0x99, 0x55, 0x22, 0x66,
375				0xFF, 0x44, 0xFF, 0xCC, 0x00,
376				0x33, 0x77, 0xBB, 0x88, 0xEE,
377			},
378			[]uint8{
379				0x11, 0x99, 0x55, 0x22, 0x66,
380				0xFF, 0x44, 0xFF, 0xCC, 0x00,
381				0x33, 0x77, 0xBB, 0x88, 0xEE,
382			},
383		},
384		{
385			"maximum (3, false)",
386			3, false,
387			image.Rect(-1, -1, 4, 2),
388			image.Rect(0, 0, 5, 3),
389			[]uint8{
390				0x11, 0x99, 0x55, 0x22, 0x66,
391				0xFF, 0x44, 0xFF, 0xCC, 0x00,
392				0x33, 0x77, 0xBB, 0x88, 0xEE,
393			},
394			[]uint8{
395				0xFF, 0xFF, 0xFF, 0xFF, 0xCC,
396				0xFF, 0xFF, 0xFF, 0xFF, 0xEE,
397				0xFF, 0xFF, 0xFF, 0xFF, 0xEE,
398			},
399		},
400		{
401			"maximum (3, true)",
402			3, true,
403			image.Rect(-1, -1, 4, 2),
404			image.Rect(0, 0, 5, 3),
405			[]uint8{
406				0x11, 0x99, 0x55, 0x22, 0x66,
407				0xFF, 0x44, 0xFF, 0xCC, 0x00,
408				0x33, 0x77, 0xBB, 0x88, 0xEE,
409			},
410			[]uint8{
411				0xFF, 0x99, 0xFF, 0xCC, 0x66,
412				0xFF, 0xFF, 0xFF, 0xFF, 0xEE,
413				0xFF, 0xBB, 0xFF, 0xEE, 0xEE,
414			},
415		},
416		{
417			"maximum (4, true)",
418			4, true,
419			image.Rect(-1, -1, 4, 2),
420			image.Rect(0, 0, 5, 3),
421			[]uint8{
422				0x11, 0x99, 0x55, 0x22, 0x66,
423				0xFF, 0x44, 0xFF, 0xCC, 0x00,
424				0x33, 0x77, 0xBB, 0x88, 0xEE,
425			},
426			[]uint8{
427				0xFF, 0x99, 0xFF, 0xCC, 0x66,
428				0xFF, 0xFF, 0xFF, 0xFF, 0xEE,
429				0xFF, 0xBB, 0xFF, 0xEE, 0xEE,
430			},
431		},
432	}
433
434	for _, d := range testData {
435		src := image.NewGray(d.srcb)
436		src.Pix = d.srcPix
437
438		f := Maximum(d.ksize, d.disk)
439		dst := image.NewGray(f.Bounds(src.Bounds()))
440		f.Draw(dst, src, nil)
441
442		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
443			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
444		}
445	}
446
447	testDataNRGBA := []struct {
448		desc           string
449		ksize          int
450		disk           bool
451		srcb, dstb     image.Rectangle
452		srcPix, dstPix []uint8
453	}{
454		{
455			"maximum nrgba (3, true)",
456			3, true,
457			image.Rect(-1, -1, 4, 2),
458			image.Rect(0, 0, 5, 3),
459			[]uint8{
460				0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x66,
461				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x00,
462				0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0xEE,
463			},
464			[]uint8{
465				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00, 0x00, 0x66,
466				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xEE,
467				0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0xEE,
468			},
469		},
470	}
471
472	for _, d := range testDataNRGBA {
473		src := image.NewNRGBA(d.srcb)
474		src.Pix = d.srcPix
475
476		f := Maximum(d.ksize, d.disk)
477		dst := image.NewNRGBA(f.Bounds(src.Bounds()))
478		f.Draw(dst, src, nil)
479
480		if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) {
481			t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix)
482		}
483	}
484}
485