github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/gift/gift_test.go (about) 1 package gift 2 3 import ( 4 "image" 5 "image/color" 6 "image/draw" 7 "testing" 8 ) 9 10 type testFilter struct { 11 z int 12 } 13 14 func (p *testFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { 15 dstBounds = image.Rect(0, 0, srcBounds.Dx()+p.z, srcBounds.Dy()+p.z*2) 16 return 17 } 18 19 func (p *testFilter) Draw(dst draw.Image, src image.Image, options *Options) { 20 dst.Set(dst.Bounds().Min.X, dst.Bounds().Min.Y, color.Gray{123}) 21 return 22 } 23 24 func TestGIFT(t *testing.T) { 25 g := New() 26 if g.Parallelization() != defaultOptions.Parallelization { 27 t.Error("unexpected parallelization property") 28 } 29 g.SetParallelization(true) 30 if g.Parallelization() != true { 31 t.Error("unexpected parallelization property") 32 } 33 g.SetParallelization(false) 34 if g.Parallelization() != false { 35 t.Error("unexpected parallelization property") 36 } 37 38 g = New( 39 &testFilter{1}, 40 &testFilter{2}, 41 &testFilter{3}, 42 ) 43 if len(g.Filters) != 3 { 44 t.Error("unexpected filters count") 45 } 46 47 g.Add( 48 &testFilter{4}, 49 &testFilter{5}, 50 &testFilter{6}, 51 ) 52 if len(g.Filters) != 6 { 53 t.Error("unexpected filters count") 54 } 55 b := g.Bounds(image.Rect(0, 0, 1, 2)) 56 if !b.Eq(image.Rect(0, 0, 22, 44)) { 57 t.Error("unexpected gift bounds") 58 } 59 60 g.Empty() 61 if len(g.Filters) != 0 { 62 t.Error("unexpected filters count") 63 } 64 b = g.Bounds(image.Rect(0, 0, 1, 2)) 65 if !b.Eq(image.Rect(0, 0, 1, 2)) { 66 t.Error("unexpected gift bounds") 67 } 68 69 g = &GIFT{} 70 src := image.NewGray(image.Rect(-1, -1, 1, 1)) 71 src.Pix = []uint8{ 72 1, 2, 73 3, 4, 74 } 75 dst := image.NewGray(g.Bounds(src.Bounds())) 76 g.Draw(dst, src) 77 if !dst.Bounds().Size().Eq(src.Bounds().Size()) { 78 t.Error("unexpected dst bounds") 79 } 80 for i := range dst.Pix { 81 if dst.Pix[i] != src.Pix[i] { 82 t.Error("unexpected dst pix") 83 } 84 } 85 86 g.Add(&testFilter{1}) 87 g.Add(&testFilter{2}) 88 dst = image.NewGray(g.Bounds(src.Bounds())) 89 g.Draw(dst, src) 90 if dst.Bounds().Dx() != src.Bounds().Dx()+3 || dst.Bounds().Dy() != src.Bounds().Dy()+6 { 91 t.Error("unexpected dst bounds") 92 } 93 if dst.Pix[0] != 123 { 94 t.Error("unexpected dst pix") 95 } 96 } 97 98 func TestDrawAt(t *testing.T) { 99 testDataGray := []struct { 100 desc string 101 filters []Filter 102 pt image.Point 103 op Operator 104 srcb, dstb image.Rectangle 105 srcPix, dstPix0, dstPix1 []uint8 106 }{ 107 { 108 "draw at (Gray, [], -2, -2, copy)", 109 []Filter{}, 110 image.Pt(-2, -2), 111 CopyOperator, 112 image.Rect(-1, -1, 2, 2), 113 image.Rect(-2, -2, 2, 2), 114 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 115 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 116 []uint8{1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9, 0, 0, 0, 0, 0}, 117 }, 118 { 119 "draw at (Gray, [], -1, -1, copy)", 120 []Filter{}, 121 image.Pt(-1, -1), 122 CopyOperator, 123 image.Rect(-1, -1, 2, 2), 124 image.Rect(-2, -2, 2, 2), 125 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 126 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 127 []uint8{0, 0, 0, 0, 0, 1, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9}, 128 }, 129 { 130 "draw at (Gray, [], 0, 0, copy)", 131 []Filter{}, 132 image.Pt(0, 0), 133 CopyOperator, 134 image.Rect(-1, -1, 2, 2), 135 image.Rect(-2, -2, 2, 2), 136 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 137 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 138 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 4, 5}, 139 }, 140 { 141 "draw at (Gray, [], 2, 2, copy)", 142 []Filter{}, 143 image.Pt(2, 2), 144 CopyOperator, 145 image.Rect(-1, -1, 2, 2), 146 image.Rect(-2, -2, 2, 2), 147 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 148 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 149 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 150 }, 151 { 152 "draw at (Gray, [], 0, -10, copy)", 153 []Filter{}, 154 image.Pt(0, -10), 155 CopyOperator, 156 image.Rect(-1, -1, 2, 2), 157 image.Rect(-2, -2, 2, 2), 158 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 159 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 160 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 161 }, 162 { 163 "draw at (Gray, [], -3, -3, copy)", 164 []Filter{}, 165 image.Pt(-3, -3), 166 CopyOperator, 167 image.Rect(-1, -1, 2, 2), 168 image.Rect(-2, -2, 2, 2), 169 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 170 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 171 []uint8{5, 6, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 172 }, 173 { 174 "draw at (Gray, [], -3, -3, over)", 175 []Filter{}, 176 image.Pt(-3, -3), 177 OverOperator, 178 image.Rect(-1, -1, 2, 2), 179 image.Rect(-2, -2, 2, 2), 180 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 181 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 182 []uint8{5, 6, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 183 }, 184 { 185 "draw at (Gray, [Resize], -2, -2, copy)", 186 []Filter{Resize(6, 6, NearestNeighborResampling)}, 187 image.Pt(-2, -2), 188 CopyOperator, 189 image.Rect(-1, -1, 2, 2), 190 image.Rect(-2, -2, 2, 2), 191 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 192 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 193 []uint8{1, 1, 2, 2, 1, 1, 2, 2, 4, 4, 5, 5, 4, 4, 5, 5}, 194 }, 195 { 196 "draw at (Gray, [Resize], -3, -3, copy)", 197 []Filter{Resize(6, 6, NearestNeighborResampling)}, 198 image.Pt(-3, -3), 199 CopyOperator, 200 image.Rect(-1, -1, 2, 2), 201 image.Rect(-2, -2, 2, 2), 202 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 203 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 204 []uint8{1, 2, 2, 3, 4, 5, 5, 6, 4, 5, 5, 6, 7, 8, 8, 9}, 205 }, 206 { 207 "draw at (Gray, [Resize], -1, -1, copy)", 208 []Filter{Resize(6, 6, NearestNeighborResampling)}, 209 image.Pt(-1, -1), 210 CopyOperator, 211 image.Rect(-1, -1, 2, 2), 212 image.Rect(-2, -2, 2, 2), 213 []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9}, 214 []uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 215 []uint8{0, 0, 0, 0, 0, 1, 1, 2, 0, 1, 1, 2, 0, 4, 4, 5}, 216 }, 217 { 218 "draw at (Gray, [Resize], -1, -1, copy, empty)", 219 []Filter{Resize(6, 6, NearestNeighborResampling)}, 220 image.Pt(-1, -1), 221 CopyOperator, 222 image.Rect(0, 0, 0, 0), 223 image.Rect(0, 0, 0, 0), 224 []uint8{}, 225 []uint8{}, 226 []uint8{}, 227 }, 228 } 229 230 for _, d := range testDataGray { 231 src := image.NewGray(d.srcb) 232 src.Pix = d.srcPix 233 234 g := New(d.filters...) 235 236 dst := image.NewGray(d.dstb) 237 dst.Pix = d.dstPix0 238 239 g.DrawAt(dst, src, d.pt, d.op) 240 241 if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix1) { 242 t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) 243 } 244 } 245 246 testDataNRGBA := []struct { 247 desc string 248 filters []Filter 249 pt image.Point 250 op Operator 251 srcb, dstb image.Rectangle 252 srcPix, dstPix0, dstPix1 []uint8 253 }{ 254 { 255 "draw at (NRGBA, [], 1, 1, over, 0% 100% alpha)", 256 []Filter{}, 257 image.Pt(1, 1), 258 OverOperator, 259 image.Rect(0, 0, 2, 2), 260 image.Rect(0, 0, 3, 3), 261 []uint8{ 262 10, 20, 30, 255, 40, 50, 60, 255, 263 100, 200, 0, 255, 0, 250, 200, 255, 264 }, 265 []uint8{ 266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269 }, 270 []uint8{ 271 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272 0, 0, 0, 0, 10, 20, 30, 255, 40, 50, 60, 255, 273 0, 0, 0, 0, 100, 200, 0, 255, 0, 250, 200, 255, 274 }, 275 }, 276 { 277 "draw at (NRGBA, [], 1, 1, over, 0% 50% alpha)", 278 []Filter{}, 279 image.Pt(1, 1), 280 OverOperator, 281 image.Rect(0, 0, 2, 2), 282 image.Rect(0, 0, 3, 3), 283 []uint8{ 284 10, 20, 30, 127, 40, 50, 60, 127, 285 100, 200, 0, 127, 0, 250, 200, 127, 286 }, 287 []uint8{ 288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291 }, 292 []uint8{ 293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 294 0, 0, 0, 0, 10, 20, 30, 127, 40, 50, 60, 127, 295 0, 0, 0, 0, 100, 200, 0, 127, 0, 250, 200, 127, 296 }, 297 }, 298 { 299 "draw at (NRGBA, [], 1, 1, over, 100% 50% alpha)", 300 []Filter{}, 301 image.Pt(1, 1), 302 OverOperator, 303 image.Rect(0, 0, 2, 2), 304 image.Rect(0, 0, 3, 3), 305 []uint8{ 306 10, 20, 30, 128, 40, 50, 60, 128, 307 100, 200, 0, 128, 0, 250, 200, 128, 308 }, 309 []uint8{ 310 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 311 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 312 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 313 }, 314 []uint8{ 315 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 316 0, 0, 0, 255, 5, 10, 15, 255, 20, 25, 30, 255, 317 0, 0, 0, 255, 50, 100, 0, 255, 0, 125, 100, 255, 318 }, 319 }, 320 { 321 "draw at (NRGBA, [], 1, 1, over, 100% 25% alpha)", 322 []Filter{}, 323 image.Pt(1, 1), 324 OverOperator, 325 image.Rect(0, 0, 2, 2), 326 image.Rect(0, 0, 3, 3), 327 []uint8{ 328 20, 40, 80, 64, 40, 80, 120, 64, 329 100, 200, 0, 64, 0, 100, 200, 64, 330 }, 331 []uint8{ 332 0, 0, 0, 255, 1, 2, 3, 255, 0, 0, 0, 255, 333 0, 0, 0, 255, 40, 80, 120, 255, 40, 40, 40, 255, 334 0, 0, 0, 255, 200, 200, 12, 255, 0, 0, 0, 255, 335 }, 336 []uint8{ 337 0, 0, 0, 255, 1, 2, 3, 255, 0, 0, 0, 255, 338 0, 0, 0, 255, 35, 70, 110, 255, 40, 50, 60, 255, 339 0, 0, 0, 255, 175, 200, 9, 255, 0, 25, 50, 255, 340 }, 341 }, 342 { 343 "draw at (NRGBA, [], 1, 1, over, shape)", 344 []Filter{}, 345 image.Pt(1, 1), 346 OverOperator, 347 image.Rect(0, 0, 2, 2), 348 image.Rect(0, 0, 3, 3), 349 []uint8{ 350 100, 100, 100, 255, 100, 100, 100, 255, 351 100, 100, 100, 255, 100, 100, 100, 0, 352 }, 353 []uint8{ 354 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 355 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 356 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 357 }, 358 []uint8{ 359 10, 10, 10, 255, 10, 10, 10, 255, 10, 10, 10, 255, 360 10, 10, 10, 255, 100, 100, 100, 255, 100, 100, 100, 255, 361 10, 10, 10, 255, 100, 100, 100, 255, 10, 10, 10, 255, 362 }, 363 }, 364 } 365 366 for _, d := range testDataNRGBA { 367 src := image.NewNRGBA(d.srcb) 368 src.Pix = d.srcPix 369 370 g := New(d.filters...) 371 372 dst := image.NewNRGBA(d.dstb) 373 dst.Pix = d.dstPix0 374 375 g.DrawAt(dst, src, d.pt, d.op) 376 377 if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix1) { 378 t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) 379 } 380 } 381 382 } 383 384 type fakeDrawImage struct { 385 r image.Rectangle 386 } 387 388 func (p fakeDrawImage) Bounds() image.Rectangle { return p.r } 389 func (p fakeDrawImage) At(x, y int) color.Color { return color.NRGBA{0, 0, 0, 0} } 390 func (p fakeDrawImage) ColorModel() color.Model { return color.NRGBAModel } 391 func (p fakeDrawImage) Set(x, y int, c color.Color) {} 392 393 func TestSubImage(t *testing.T) { 394 testData := []struct { 395 desc string 396 img draw.Image 397 ok bool 398 }{ 399 { 400 "sub image (Gray)", 401 image.NewGray(image.Rect(0, 0, 10, 10)), 402 true, 403 }, 404 { 405 "sub image (Gray16)", 406 image.NewGray16(image.Rect(0, 0, 10, 10)), 407 true, 408 }, 409 { 410 "sub image (RGBA)", 411 image.NewRGBA(image.Rect(0, 0, 10, 10)), 412 true, 413 }, 414 { 415 "sub image (RGBA64)", 416 image.NewRGBA64(image.Rect(0, 0, 10, 10)), 417 true, 418 }, 419 { 420 "sub image (NRGBA)", 421 image.NewNRGBA(image.Rect(0, 0, 10, 10)), 422 true, 423 }, 424 { 425 "sub image (NRGBA64)", 426 image.NewNRGBA64(image.Rect(0, 0, 10, 10)), 427 true, 428 }, 429 { 430 "sub image (fake)", 431 fakeDrawImage{image.Rect(0, 0, 10, 10)}, 432 false, 433 }, 434 } 435 436 for _, d := range testData { 437 simg, ok := getSubImage(d.img, image.Pt(3, 3)) 438 if ok != d.ok { 439 t.Errorf("test [%s] failed: expected %#v, got %#v", d.desc, d.ok, ok) 440 } else if ok { 441 simg.Set(5, 5, color.NRGBA{255, 255, 255, 255}) 442 r, g, b, a := d.img.At(5, 5).RGBA() 443 if r != 0xffff || g != 0xffff || b != 0xffff || a != 0xffff { 444 t.Errorf("test [%s] failed: expected (0xffff, 0xffff, 0xffff, 0xffff), got (%d, %d, %d, %d)", d.desc, r, g, b, a) 445 } 446 } 447 } 448 449 } 450 451 func TestDraw(t *testing.T) { 452 filters := [][]Filter{ 453 []Filter{}, 454 []Filter{Resize(2, 2, NearestNeighborResampling), Crop(image.Rect(0, 0, 1, 1))}, 455 []Filter{Resize(2, 2, NearestNeighborResampling), CropToSize(1, 1, CenterAnchor)}, 456 []Filter{FlipHorizontal()}, 457 []Filter{FlipVertical()}, 458 []Filter{Resize(2, 2, NearestNeighborResampling), Resize(1, 1, NearestNeighborResampling)}, 459 []Filter{Resize(2, 2, NearestNeighborResampling), ResizeToFit(1, 1, NearestNeighborResampling)}, 460 []Filter{Resize(2, 2, NearestNeighborResampling), ResizeToFill(1, 1, NearestNeighborResampling, CenterAnchor)}, 461 []Filter{Rotate(45, color.NRGBA{0, 0, 0, 0}, NearestNeighborInterpolation)}, 462 []Filter{Rotate90()}, 463 []Filter{Rotate180()}, 464 []Filter{Rotate270()}, 465 []Filter{Transpose()}, 466 []Filter{Transverse()}, 467 []Filter{Brightness(10)}, 468 []Filter{ColorBalance(10, 10, 10)}, 469 []Filter{ColorFunc(func(r0, g0, b0, a0 float32) (r, g, b, a float32) { return 1, 1, 1, 1 })}, 470 []Filter{Colorize(240, 50, 100)}, 471 []Filter{ColorspaceLinearToSRGB()}, 472 []Filter{ColorspaceSRGBToLinear()}, 473 []Filter{Contrast(10)}, 474 []Filter{Convolution([]float32{-1, -1, 0, -1, 1, 1, 0, 1, 1}, false, false, false, 0.0)}, 475 []Filter{Gamma(1.1)}, 476 []Filter{GaussianBlur(3)}, 477 []Filter{Grayscale()}, 478 []Filter{Hue(90)}, 479 []Filter{Invert()}, 480 []Filter{Maximum(3, true)}, 481 []Filter{Minimum(3, true)}, 482 []Filter{Mean(3, true)}, 483 []Filter{Median(3, true)}, 484 []Filter{Pixelate(3)}, 485 []Filter{Saturation(10)}, 486 []Filter{Sepia(10)}, 487 []Filter{Sigmoid(0.5, 5)}, 488 []Filter{Sobel()}, 489 []Filter{UnsharpMask(1.0, 1.5, 0.001)}, 490 } 491 492 for i, f := range filters { 493 src := image.NewNRGBA(image.Rect(1, 1, 2, 2)) 494 src.Pix = []uint8{255, 255, 255, 255} 495 g := New(f...) 496 dst := image.NewNRGBA(image.Rect(-100, -100, -95, -95)) 497 g.Draw(dst, src) 498 for x := dst.Bounds().Min.X; x < dst.Bounds().Max.X; x++ { 499 for y := dst.Bounds().Min.Y; y < dst.Bounds().Max.Y; y++ { 500 failed := false 501 if x == -100 && y == -100 { 502 if (color.NRGBAModel.Convert(dst.At(x, y)).(color.NRGBA) == color.NRGBA{0, 0, 0, 0}) { 503 failed = true 504 } 505 } else { 506 if (color.NRGBAModel.Convert(dst.At(x, y)).(color.NRGBA) != color.NRGBA{0, 0, 0, 0}) { 507 failed = true 508 } 509 } 510 if failed { 511 t.Errorf("test draw pos failed: %d %#v %#v", i, f, dst.Pix) 512 } 513 } 514 } 515 } 516 }