github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/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 "github.com/x04/go/src/image/color" 9 "github.com/x04/go/src/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 Test16BitsPerColorChannel(t *testing.T) { 92 testColorModel := []color.Model{ 93 color.RGBA64Model, 94 color.NRGBA64Model, 95 color.Alpha16Model, 96 color.Gray16Model, 97 } 98 for _, cm := range testColorModel { 99 c := cm.Convert(color.RGBA64{0x1234, 0x1234, 0x1234, 0x1234}) // Premultiplied alpha. 100 r, _, _, _ := c.RGBA() 101 if r != 0x1234 { 102 t.Errorf("%T: want red value 0x%04x got 0x%04x", c, 0x1234, r) 103 continue 104 } 105 } 106 testImage := []image{ 107 NewRGBA64(Rect(0, 0, 10, 10)), 108 NewNRGBA64(Rect(0, 0, 10, 10)), 109 NewAlpha16(Rect(0, 0, 10, 10)), 110 NewGray16(Rect(0, 0, 10, 10)), 111 } 112 for _, m := range testImage { 113 m.Set(1, 2, color.NRGBA64{0xffff, 0xffff, 0xffff, 0x1357}) // Non-premultiplied alpha. 114 r, _, _, _ := m.At(1, 2).RGBA() 115 if r != 0x1357 { 116 t.Errorf("%T: want red value 0x%04x got 0x%04x", m, 0x1357, r) 117 continue 118 } 119 } 120 } 121 122 func BenchmarkAt(b *testing.B) { 123 for _, tc := range testImages { 124 b.Run(tc.name, func(b *testing.B) { 125 m := tc.image() 126 b.ReportAllocs() 127 b.ResetTimer() 128 for i := 0; i < b.N; i++ { 129 m.At(4, 5) 130 } 131 }) 132 } 133 } 134 135 func BenchmarkSet(b *testing.B) { 136 c := color.Gray{0xff} 137 for _, tc := range testImages { 138 b.Run(tc.name, func(b *testing.B) { 139 m := tc.image() 140 b.ReportAllocs() 141 b.ResetTimer() 142 for i := 0; i < b.N; i++ { 143 m.Set(4, 5, c) 144 } 145 }) 146 } 147 } 148 149 func BenchmarkRGBAAt(b *testing.B) { 150 m := NewRGBA(Rect(0, 0, 10, 10)) 151 b.ResetTimer() 152 153 for i := 0; i < b.N; i++ { 154 m.RGBAAt(4, 5) 155 } 156 } 157 158 func BenchmarkRGBASetRGBA(b *testing.B) { 159 m := NewRGBA(Rect(0, 0, 10, 10)) 160 c := color.RGBA{0xff, 0xff, 0xff, 0x13} 161 b.ResetTimer() 162 163 for i := 0; i < b.N; i++ { 164 m.SetRGBA(4, 5, c) 165 } 166 } 167 168 func BenchmarkRGBA64At(b *testing.B) { 169 m := NewRGBA64(Rect(0, 0, 10, 10)) 170 b.ResetTimer() 171 172 for i := 0; i < b.N; i++ { 173 m.RGBA64At(4, 5) 174 } 175 } 176 177 func BenchmarkRGBA64SetRGBA64(b *testing.B) { 178 m := NewRGBA64(Rect(0, 0, 10, 10)) 179 c := color.RGBA64{0xffff, 0xffff, 0xffff, 0x1357} 180 b.ResetTimer() 181 182 for i := 0; i < b.N; i++ { 183 m.SetRGBA64(4, 5, c) 184 } 185 } 186 187 func BenchmarkNRGBAAt(b *testing.B) { 188 m := NewNRGBA(Rect(0, 0, 10, 10)) 189 b.ResetTimer() 190 191 for i := 0; i < b.N; i++ { 192 m.NRGBAAt(4, 5) 193 } 194 } 195 196 func BenchmarkNRGBASetNRGBA(b *testing.B) { 197 m := NewNRGBA(Rect(0, 0, 10, 10)) 198 c := color.NRGBA{0xff, 0xff, 0xff, 0x13} 199 b.ResetTimer() 200 201 for i := 0; i < b.N; i++ { 202 m.SetNRGBA(4, 5, c) 203 } 204 } 205 206 func BenchmarkNRGBA64At(b *testing.B) { 207 m := NewNRGBA64(Rect(0, 0, 10, 10)) 208 b.ResetTimer() 209 210 for i := 0; i < b.N; i++ { 211 m.NRGBA64At(4, 5) 212 } 213 } 214 215 func BenchmarkNRGBA64SetNRGBA64(b *testing.B) { 216 m := NewNRGBA64(Rect(0, 0, 10, 10)) 217 c := color.NRGBA64{0xffff, 0xffff, 0xffff, 0x1357} 218 b.ResetTimer() 219 220 for i := 0; i < b.N; i++ { 221 m.SetNRGBA64(4, 5, c) 222 } 223 } 224 225 func BenchmarkAlphaAt(b *testing.B) { 226 m := NewAlpha(Rect(0, 0, 10, 10)) 227 b.ResetTimer() 228 229 for i := 0; i < b.N; i++ { 230 m.AlphaAt(4, 5) 231 } 232 } 233 234 func BenchmarkAlphaSetAlpha(b *testing.B) { 235 m := NewAlpha(Rect(0, 0, 10, 10)) 236 c := color.Alpha{0x13} 237 b.ResetTimer() 238 239 for i := 0; i < b.N; i++ { 240 m.SetAlpha(4, 5, c) 241 } 242 } 243 244 func BenchmarkAlpha16At(b *testing.B) { 245 m := NewAlpha16(Rect(0, 0, 10, 10)) 246 b.ResetTimer() 247 248 for i := 0; i < b.N; i++ { 249 m.Alpha16At(4, 5) 250 } 251 } 252 253 func BenchmarkAlphaSetAlpha16(b *testing.B) { 254 m := NewAlpha16(Rect(0, 0, 10, 10)) 255 c := color.Alpha16{0x13} 256 b.ResetTimer() 257 258 for i := 0; i < b.N; i++ { 259 m.SetAlpha16(4, 5, c) 260 } 261 } 262 263 func BenchmarkGrayAt(b *testing.B) { 264 m := NewGray(Rect(0, 0, 10, 10)) 265 b.ResetTimer() 266 267 for i := 0; i < b.N; i++ { 268 m.GrayAt(4, 5) 269 } 270 } 271 272 func BenchmarkGraySetGray(b *testing.B) { 273 m := NewGray(Rect(0, 0, 10, 10)) 274 c := color.Gray{0x13} 275 b.ResetTimer() 276 277 for i := 0; i < b.N; i++ { 278 m.SetGray(4, 5, c) 279 } 280 } 281 282 func BenchmarkGray16At(b *testing.B) { 283 m := NewGray16(Rect(0, 0, 10, 10)) 284 b.ResetTimer() 285 286 for i := 0; i < b.N; i++ { 287 m.Gray16At(4, 5) 288 } 289 } 290 291 func BenchmarkGraySetGray16(b *testing.B) { 292 m := NewGray16(Rect(0, 0, 10, 10)) 293 c := color.Gray16{0x13} 294 b.ResetTimer() 295 296 for i := 0; i < b.N; i++ { 297 m.SetGray16(4, 5, c) 298 } 299 }