github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/image/image_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package image
     6  
     7  import (
     8  	"image/color"
     9  	"testing"
    10  )
    11  
    12  type image interface {
    13  	Image
    14  	Opaque() bool
    15  	Set(int, int, color.Color)
    16  	SubImage(Rectangle) Image
    17  }
    18  
    19  func cmp(cm color.Model, c0, c1 color.Color) bool {
    20  	r0, g0, b0, a0 := cm.Convert(c0).RGBA()
    21  	r1, g1, b1, a1 := cm.Convert(c1).RGBA()
    22  	return r0 == r1 && g0 == g1 && b0 == b1 && a0 == a1
    23  }
    24  
    25  var testImages = []struct {
    26  	name  string
    27  	image func() image
    28  }{
    29  	{"rgba", func() image { return NewRGBA(Rect(0, 0, 10, 10)) }},
    30  	{"rgba64", func() image { return NewRGBA64(Rect(0, 0, 10, 10)) }},
    31  	{"nrgba", func() image { return NewNRGBA(Rect(0, 0, 10, 10)) }},
    32  	{"nrgba64", func() image { return NewNRGBA64(Rect(0, 0, 10, 10)) }},
    33  	{"alpha", func() image { return NewAlpha(Rect(0, 0, 10, 10)) }},
    34  	{"alpha16", func() image { return NewAlpha16(Rect(0, 0, 10, 10)) }},
    35  	{"gray", func() image { return NewGray(Rect(0, 0, 10, 10)) }},
    36  	{"gray16", func() image { return NewGray16(Rect(0, 0, 10, 10)) }},
    37  	{"paletted", func() image {
    38  		return NewPaletted(Rect(0, 0, 10, 10), color.Palette{
    39  			Transparent,
    40  			Opaque,
    41  		})
    42  	}},
    43  }
    44  
    45  func TestImage(t *testing.T) {
    46  	for _, tc := range testImages {
    47  		m := tc.image()
    48  		if !Rect(0, 0, 10, 10).Eq(m.Bounds()) {
    49  			t.Errorf("%T: want bounds %v, got %v", m, Rect(0, 0, 10, 10), m.Bounds())
    50  			continue
    51  		}
    52  		if !cmp(m.ColorModel(), Transparent, m.At(6, 3)) {
    53  			t.Errorf("%T: at (6, 3), want a zero color, got %v", m, m.At(6, 3))
    54  			continue
    55  		}
    56  		m.Set(6, 3, Opaque)
    57  		if !cmp(m.ColorModel(), Opaque, m.At(6, 3)) {
    58  			t.Errorf("%T: at (6, 3), want a non-zero color, got %v", m, m.At(6, 3))
    59  			continue
    60  		}
    61  		if !m.SubImage(Rect(6, 3, 7, 4)).(image).Opaque() {
    62  			t.Errorf("%T: at (6, 3) was not opaque", m)
    63  			continue
    64  		}
    65  		m = m.SubImage(Rect(3, 2, 9, 8)).(image)
    66  		if !Rect(3, 2, 9, 8).Eq(m.Bounds()) {
    67  			t.Errorf("%T: sub-image want bounds %v, got %v", m, Rect(3, 2, 9, 8), m.Bounds())
    68  			continue
    69  		}
    70  		if !cmp(m.ColorModel(), Opaque, m.At(6, 3)) {
    71  			t.Errorf("%T: sub-image at (6, 3), want a non-zero color, got %v", m, m.At(6, 3))
    72  			continue
    73  		}
    74  		if !cmp(m.ColorModel(), Transparent, m.At(3, 3)) {
    75  			t.Errorf("%T: sub-image at (3, 3), want a zero color, got %v", m, m.At(3, 3))
    76  			continue
    77  		}
    78  		m.Set(3, 3, Opaque)
    79  		if !cmp(m.ColorModel(), Opaque, m.At(3, 3)) {
    80  			t.Errorf("%T: sub-image at (3, 3), want a non-zero color, got %v", m, m.At(3, 3))
    81  			continue
    82  		}
    83  		// Test that taking an empty sub-image starting at a corner does not panic.
    84  		m.SubImage(Rect(0, 0, 0, 0))
    85  		m.SubImage(Rect(10, 0, 10, 0))
    86  		m.SubImage(Rect(0, 10, 0, 10))
    87  		m.SubImage(Rect(10, 10, 10, 10))
    88  	}
    89  }
    90  
    91  func TestNewXxxBadRectangle(t *testing.T) {
    92  	// call calls f(r) and reports whether it ran without panicking.
    93  	call := func(f func(Rectangle), r Rectangle) (ok bool) {
    94  		defer func() {
    95  			if recover() != nil {
    96  				ok = false
    97  			}
    98  		}()
    99  		f(r)
   100  		return true
   101  	}
   102  
   103  	testCases := []struct {
   104  		name string
   105  		f    func(Rectangle)
   106  	}{
   107  		{"RGBA", func(r Rectangle) { NewRGBA(r) }},
   108  		{"RGBA64", func(r Rectangle) { NewRGBA64(r) }},
   109  		{"NRGBA", func(r Rectangle) { NewNRGBA(r) }},
   110  		{"NRGBA64", func(r Rectangle) { NewNRGBA64(r) }},
   111  		{"Alpha", func(r Rectangle) { NewAlpha(r) }},
   112  		{"Alpha16", func(r Rectangle) { NewAlpha16(r) }},
   113  		{"Gray", func(r Rectangle) { NewGray(r) }},
   114  		{"Gray16", func(r Rectangle) { NewGray16(r) }},
   115  		{"CMYK", func(r Rectangle) { NewCMYK(r) }},
   116  		{"Paletted", func(r Rectangle) { NewPaletted(r, color.Palette{color.Black, color.White}) }},
   117  		{"YCbCr", func(r Rectangle) { NewYCbCr(r, YCbCrSubsampleRatio422) }},
   118  		{"NYCbCrA", func(r Rectangle) { NewNYCbCrA(r, YCbCrSubsampleRatio444) }},
   119  	}
   120  
   121  	for _, tc := range testCases {
   122  		// Calling NewXxx(r) should fail (panic, since NewXxx doesn't return an
   123  		// error) unless r's width and height are both non-negative.
   124  		for _, negDx := range []bool{false, true} {
   125  			for _, negDy := range []bool{false, true} {
   126  				r := Rectangle{
   127  					Min: Point{15, 28},
   128  					Max: Point{16, 29},
   129  				}
   130  				if negDx {
   131  					r.Max.X = 14
   132  				}
   133  				if negDy {
   134  					r.Max.Y = 27
   135  				}
   136  
   137  				got := call(tc.f, r)
   138  				want := !negDx && !negDy
   139  				if got != want {
   140  					t.Errorf("New%s: negDx=%t, negDy=%t: got %t, want %t",
   141  						tc.name, negDx, negDy, got, want)
   142  				}
   143  			}
   144  		}
   145  
   146  		// Passing a Rectangle whose width and height is MaxInt should also fail
   147  		// (panic), due to overflow.
   148  		{
   149  			zeroAsUint := uint(0)
   150  			maxUint := zeroAsUint - 1
   151  			maxInt := int(maxUint / 2)
   152  			got := call(tc.f, Rectangle{
   153  				Min: Point{0, 0},
   154  				Max: Point{maxInt, maxInt},
   155  			})
   156  			if got {
   157  				t.Errorf("New%s: overflow: got ok, want !ok", tc.name)
   158  			}
   159  		}
   160  	}
   161  }
   162  
   163  func Test16BitsPerColorChannel(t *testing.T) {
   164  	testColorModel := []color.Model{
   165  		color.RGBA64Model,
   166  		color.NRGBA64Model,
   167  		color.Alpha16Model,
   168  		color.Gray16Model,
   169  	}
   170  	for _, cm := range testColorModel {
   171  		c := cm.Convert(color.RGBA64{0x1234, 0x1234, 0x1234, 0x1234}) // Premultiplied alpha.
   172  		r, _, _, _ := c.RGBA()
   173  		if r != 0x1234 {
   174  			t.Errorf("%T: want red value 0x%04x got 0x%04x", c, 0x1234, r)
   175  			continue
   176  		}
   177  	}
   178  	testImage := []image{
   179  		NewRGBA64(Rect(0, 0, 10, 10)),
   180  		NewNRGBA64(Rect(0, 0, 10, 10)),
   181  		NewAlpha16(Rect(0, 0, 10, 10)),
   182  		NewGray16(Rect(0, 0, 10, 10)),
   183  	}
   184  	for _, m := range testImage {
   185  		m.Set(1, 2, color.NRGBA64{0xffff, 0xffff, 0xffff, 0x1357}) // Non-premultiplied alpha.
   186  		r, _, _, _ := m.At(1, 2).RGBA()
   187  		if r != 0x1357 {
   188  			t.Errorf("%T: want red value 0x%04x got 0x%04x", m, 0x1357, r)
   189  			continue
   190  		}
   191  	}
   192  }
   193  
   194  func BenchmarkAt(b *testing.B) {
   195  	for _, tc := range testImages {
   196  		b.Run(tc.name, func(b *testing.B) {
   197  			m := tc.image()
   198  			b.ReportAllocs()
   199  			b.ResetTimer()
   200  			for i := 0; i < b.N; i++ {
   201  				m.At(4, 5)
   202  			}
   203  		})
   204  	}
   205  }
   206  
   207  func BenchmarkSet(b *testing.B) {
   208  	c := color.Gray{0xff}
   209  	for _, tc := range testImages {
   210  		b.Run(tc.name, func(b *testing.B) {
   211  			m := tc.image()
   212  			b.ReportAllocs()
   213  			b.ResetTimer()
   214  			for i := 0; i < b.N; i++ {
   215  				m.Set(4, 5, c)
   216  			}
   217  		})
   218  	}
   219  }
   220  
   221  func BenchmarkRGBAAt(b *testing.B) {
   222  	m := NewRGBA(Rect(0, 0, 10, 10))
   223  	b.ResetTimer()
   224  
   225  	for i := 0; i < b.N; i++ {
   226  		m.RGBAAt(4, 5)
   227  	}
   228  }
   229  
   230  func BenchmarkRGBASetRGBA(b *testing.B) {
   231  	m := NewRGBA(Rect(0, 0, 10, 10))
   232  	c := color.RGBA{0xff, 0xff, 0xff, 0x13}
   233  	b.ResetTimer()
   234  
   235  	for i := 0; i < b.N; i++ {
   236  		m.SetRGBA(4, 5, c)
   237  	}
   238  }
   239  
   240  func BenchmarkRGBA64At(b *testing.B) {
   241  	m := NewRGBA64(Rect(0, 0, 10, 10))
   242  	b.ResetTimer()
   243  
   244  	for i := 0; i < b.N; i++ {
   245  		m.RGBA64At(4, 5)
   246  	}
   247  }
   248  
   249  func BenchmarkRGBA64SetRGBA64(b *testing.B) {
   250  	m := NewRGBA64(Rect(0, 0, 10, 10))
   251  	c := color.RGBA64{0xffff, 0xffff, 0xffff, 0x1357}
   252  	b.ResetTimer()
   253  
   254  	for i := 0; i < b.N; i++ {
   255  		m.SetRGBA64(4, 5, c)
   256  	}
   257  }
   258  
   259  func BenchmarkNRGBAAt(b *testing.B) {
   260  	m := NewNRGBA(Rect(0, 0, 10, 10))
   261  	b.ResetTimer()
   262  
   263  	for i := 0; i < b.N; i++ {
   264  		m.NRGBAAt(4, 5)
   265  	}
   266  }
   267  
   268  func BenchmarkNRGBASetNRGBA(b *testing.B) {
   269  	m := NewNRGBA(Rect(0, 0, 10, 10))
   270  	c := color.NRGBA{0xff, 0xff, 0xff, 0x13}
   271  	b.ResetTimer()
   272  
   273  	for i := 0; i < b.N; i++ {
   274  		m.SetNRGBA(4, 5, c)
   275  	}
   276  }
   277  
   278  func BenchmarkNRGBA64At(b *testing.B) {
   279  	m := NewNRGBA64(Rect(0, 0, 10, 10))
   280  	b.ResetTimer()
   281  
   282  	for i := 0; i < b.N; i++ {
   283  		m.NRGBA64At(4, 5)
   284  	}
   285  }
   286  
   287  func BenchmarkNRGBA64SetNRGBA64(b *testing.B) {
   288  	m := NewNRGBA64(Rect(0, 0, 10, 10))
   289  	c := color.NRGBA64{0xffff, 0xffff, 0xffff, 0x1357}
   290  	b.ResetTimer()
   291  
   292  	for i := 0; i < b.N; i++ {
   293  		m.SetNRGBA64(4, 5, c)
   294  	}
   295  }
   296  
   297  func BenchmarkAlphaAt(b *testing.B) {
   298  	m := NewAlpha(Rect(0, 0, 10, 10))
   299  	b.ResetTimer()
   300  
   301  	for i := 0; i < b.N; i++ {
   302  		m.AlphaAt(4, 5)
   303  	}
   304  }
   305  
   306  func BenchmarkAlphaSetAlpha(b *testing.B) {
   307  	m := NewAlpha(Rect(0, 0, 10, 10))
   308  	c := color.Alpha{0x13}
   309  	b.ResetTimer()
   310  
   311  	for i := 0; i < b.N; i++ {
   312  		m.SetAlpha(4, 5, c)
   313  	}
   314  }
   315  
   316  func BenchmarkAlpha16At(b *testing.B) {
   317  	m := NewAlpha16(Rect(0, 0, 10, 10))
   318  	b.ResetTimer()
   319  
   320  	for i := 0; i < b.N; i++ {
   321  		m.Alpha16At(4, 5)
   322  	}
   323  }
   324  
   325  func BenchmarkAlphaSetAlpha16(b *testing.B) {
   326  	m := NewAlpha16(Rect(0, 0, 10, 10))
   327  	c := color.Alpha16{0x13}
   328  	b.ResetTimer()
   329  
   330  	for i := 0; i < b.N; i++ {
   331  		m.SetAlpha16(4, 5, c)
   332  	}
   333  }
   334  
   335  func BenchmarkGrayAt(b *testing.B) {
   336  	m := NewGray(Rect(0, 0, 10, 10))
   337  	b.ResetTimer()
   338  
   339  	for i := 0; i < b.N; i++ {
   340  		m.GrayAt(4, 5)
   341  	}
   342  }
   343  
   344  func BenchmarkGraySetGray(b *testing.B) {
   345  	m := NewGray(Rect(0, 0, 10, 10))
   346  	c := color.Gray{0x13}
   347  	b.ResetTimer()
   348  
   349  	for i := 0; i < b.N; i++ {
   350  		m.SetGray(4, 5, c)
   351  	}
   352  }
   353  
   354  func BenchmarkGray16At(b *testing.B) {
   355  	m := NewGray16(Rect(0, 0, 10, 10))
   356  	b.ResetTimer()
   357  
   358  	for i := 0; i < b.N; i++ {
   359  		m.Gray16At(4, 5)
   360  	}
   361  }
   362  
   363  func BenchmarkGraySetGray16(b *testing.B) {
   364  	m := NewGray16(Rect(0, 0, 10, 10))
   365  	c := color.Gray16{0x13}
   366  	b.ResetTimer()
   367  
   368  	for i := 0; i < b.N; i++ {
   369  		m.SetGray16(4, 5, c)
   370  	}
   371  }