1package imaging 2 3import ( 4 "bytes" 5 "image" 6 "image/color" 7 "testing" 8) 9 10func TestNew(t *testing.T) { 11 testCases := []struct { 12 name string 13 w, h int 14 c color.Color 15 dstBounds image.Rectangle 16 dstPix []uint8 17 }{ 18 { 19 "New 1x1 transparent", 20 1, 1, 21 color.Transparent, 22 image.Rect(0, 0, 1, 1), 23 []uint8{0x00, 0x00, 0x00, 0x00}, 24 }, 25 { 26 "New 1x2 red", 27 1, 2, 28 color.RGBA{255, 0, 0, 255}, 29 image.Rect(0, 0, 1, 2), 30 []uint8{0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff}, 31 }, 32 { 33 "New 2x1 white", 34 2, 1, 35 color.White, 36 image.Rect(0, 0, 2, 1), 37 []uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 38 }, 39 { 40 "New 3x3 with alpha", 41 3, 3, 42 color.NRGBA{0x01, 0x23, 0x45, 0x67}, 43 image.Rect(0, 0, 3, 3), 44 []uint8{ 45 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 46 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 47 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 48 }, 49 }, 50 { 51 "New 0x0 white", 52 0, 0, 53 color.White, 54 image.Rect(0, 0, 0, 0), 55 nil, 56 }, 57 { 58 "New 800x600 custom", 59 800, 600, 60 color.NRGBA{1, 2, 3, 4}, 61 image.Rect(0, 0, 800, 600), 62 bytes.Repeat([]byte{1, 2, 3, 4}, 800*600), 63 }, 64 } 65 66 for _, tc := range testCases { 67 t.Run(tc.name, func(t *testing.T) { 68 got := New(tc.w, tc.h, tc.c) 69 want := image.NewNRGBA(tc.dstBounds) 70 want.Pix = tc.dstPix 71 if !compareNRGBA(got, want, 0) { 72 t.Fatalf("got result %#v want %#v", got, want) 73 } 74 }) 75 } 76} 77 78func BenchmarkNew(b *testing.B) { 79 b.ReportAllocs() 80 for i := 0; i < b.N; i++ { 81 New(1024, 1024, color.White) 82 } 83} 84 85func TestClone(t *testing.T) { 86 testCases := []struct { 87 name string 88 src image.Image 89 want *image.NRGBA 90 }{ 91 { 92 "Clone NRGBA", 93 &image.NRGBA{ 94 Rect: image.Rect(-1, -1, 0, 1), 95 Stride: 1 * 4, 96 Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 97 }, 98 &image.NRGBA{ 99 Rect: image.Rect(0, 0, 1, 2), 100 Stride: 1 * 4, 101 Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 102 }, 103 }, 104 { 105 "Clone NRGBA64", 106 &image.NRGBA64{ 107 Rect: image.Rect(-1, -1, 0, 1), 108 Stride: 1 * 8, 109 Pix: []uint8{ 110 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 111 0xcc, 0xcc, 0xdd, 0xdd, 0xee, 0xee, 0xff, 0xff, 112 }, 113 }, 114 &image.NRGBA{ 115 Rect: image.Rect(0, 0, 1, 2), 116 Stride: 1 * 4, 117 Pix: []uint8{0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 118 }, 119 }, 120 { 121 "Clone RGBA", 122 &image.RGBA{ 123 Rect: image.Rect(-1, -1, 0, 2), 124 Stride: 1 * 4, 125 Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 126 }, 127 &image.NRGBA{ 128 Rect: image.Rect(0, 0, 1, 3), 129 Stride: 1 * 4, 130 Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 131 }, 132 }, 133 { 134 "Clone RGBA64", 135 &image.RGBA64{ 136 Rect: image.Rect(-1, -1, 0, 2), 137 Stride: 1 * 8, 138 Pix: []uint8{ 139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33, 141 0xcc, 0xcc, 0xdd, 0xdd, 0xee, 0xee, 0xff, 0xff, 142 }, 143 }, 144 &image.NRGBA{ 145 Rect: image.Rect(0, 0, 1, 3), 146 Stride: 1 * 4, 147 Pix: []uint8{0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x33, 0xcc, 0xdd, 0xee, 0xff}, 148 }, 149 }, 150 { 151 "Clone Gray", 152 &image.Gray{ 153 Rect: image.Rect(-1, -1, 0, 1), 154 Stride: 1 * 1, 155 Pix: []uint8{0x11, 0xee}, 156 }, 157 &image.NRGBA{ 158 Rect: image.Rect(0, 0, 1, 2), 159 Stride: 1 * 4, 160 Pix: []uint8{0x11, 0x11, 0x11, 0xff, 0xee, 0xee, 0xee, 0xff}, 161 }, 162 }, 163 { 164 "Clone Gray16", 165 &image.Gray16{ 166 Rect: image.Rect(-1, -1, 0, 1), 167 Stride: 1 * 2, 168 Pix: []uint8{0x11, 0x11, 0xee, 0xee}, 169 }, 170 &image.NRGBA{ 171 Rect: image.Rect(0, 0, 1, 2), 172 Stride: 1 * 4, 173 Pix: []uint8{0x11, 0x11, 0x11, 0xff, 0xee, 0xee, 0xee, 0xff}, 174 }, 175 }, 176 { 177 "Clone Alpha", 178 &image.Alpha{ 179 Rect: image.Rect(-1, -1, 0, 1), 180 Stride: 1 * 1, 181 Pix: []uint8{0x11, 0xee}, 182 }, 183 &image.NRGBA{ 184 Rect: image.Rect(0, 0, 1, 2), 185 Stride: 1 * 4, 186 Pix: []uint8{0xff, 0xff, 0xff, 0x11, 0xff, 0xff, 0xff, 0xee}, 187 }, 188 }, 189 { 190 "Clone YCbCr", 191 &image.YCbCr{ 192 Rect: image.Rect(-1, -1, 5, 0), 193 SubsampleRatio: image.YCbCrSubsampleRatio444, 194 YStride: 6, 195 CStride: 6, 196 Y: []uint8{0x00, 0xff, 0x7f, 0x26, 0x4b, 0x0e}, 197 Cb: []uint8{0x80, 0x80, 0x80, 0x6b, 0x56, 0xc0}, 198 Cr: []uint8{0x80, 0x80, 0x80, 0xc0, 0x4b, 0x76}, 199 }, 200 &image.NRGBA{ 201 Rect: image.Rect(0, 0, 6, 1), 202 Stride: 6 * 4, 203 Pix: []uint8{ 204 0x00, 0x00, 0x00, 0xff, 205 0xff, 0xff, 0xff, 0xff, 206 0x7f, 0x7f, 0x7f, 0xff, 207 0x7f, 0x00, 0x00, 0xff, 208 0x00, 0x7f, 0x00, 0xff, 209 0x00, 0x00, 0x7f, 0xff, 210 }, 211 }, 212 }, 213 { 214 "Clone YCbCr 444", 215 &image.YCbCr{ 216 Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff}, 217 Cb: []uint8{0x55, 0xd4, 0xff, 0x8e, 0x2c, 0x01, 0x6b, 0xaa, 0xc0, 0x95, 0x56, 0x40, 0x80, 0x80, 0x80, 0x80}, 218 Cr: []uint8{0xff, 0xeb, 0x6b, 0x36, 0x15, 0x95, 0xc0, 0xb5, 0x76, 0x41, 0x4b, 0x8c, 0x80, 0x80, 0x80, 0x80}, 219 YStride: 4, 220 CStride: 4, 221 SubsampleRatio: image.YCbCrSubsampleRatio444, 222 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 223 }, 224 &image.NRGBA{ 225 Pix: []uint8{0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0x49, 0xe1, 0xca, 0xff, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0x0, 0xff, 0x7f, 0x0, 0x0, 0xff, 0x7f, 0x0, 0x7f, 0xff, 0x0, 0x0, 0x7f, 0xff, 0x0, 0x7f, 0x7f, 0xff, 0x0, 0x7f, 0x0, 0xff, 0x82, 0x7f, 0x0, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff}, 226 Stride: 16, 227 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 228 }, 229 }, 230 { 231 "Clone YCbCr 440", 232 &image.YCbCr{ 233 Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff}, 234 Cb: []uint8{0x2c, 0x01, 0x6b, 0xaa, 0x80, 0x80, 0x80, 0x80}, 235 Cr: []uint8{0x15, 0x95, 0xc0, 0xb5, 0x80, 0x80, 0x80, 0x80}, 236 YStride: 4, 237 CStride: 4, 238 SubsampleRatio: image.YCbCrSubsampleRatio440, 239 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 240 }, 241 &image.NRGBA{ 242 Pix: []uint8{0x0, 0xb5, 0x0, 0xff, 0x86, 0x86, 0x0, 0xff, 0x77, 0x0, 0x0, 0xff, 0xfb, 0x7d, 0xfb, 0xff, 0x0, 0xff, 0x1, 0xff, 0xff, 0xff, 0x1, 0xff, 0x80, 0x0, 0x1, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0xe, 0xe, 0xe, 0xff, 0x59, 0x59, 0x59, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0x71, 0x71, 0x71, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff}, 243 Stride: 16, 244 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 245 }, 246 }, 247 { 248 "Clone YCbCr 422", 249 &image.YCbCr{ 250 Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff}, 251 Cb: []uint8{0xd4, 0x8e, 0x01, 0xaa, 0x95, 0x40, 0x80, 0x80}, 252 Cr: []uint8{0xeb, 0x36, 0x95, 0xb5, 0x41, 0x8c, 0x80, 0x80}, 253 YStride: 4, 254 CStride: 2, 255 SubsampleRatio: image.YCbCrSubsampleRatio422, 256 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 257 }, 258 &image.NRGBA{ 259 Pix: []uint8{0xe2, 0x0, 0xe1, 0xff, 0xff, 0x0, 0xfe, 0xff, 0x0, 0x4d, 0x36, 0xff, 0x49, 0xe1, 0xca, 0xff, 0xb3, 0xb3, 0x0, 0xff, 0xff, 0xff, 0x1, 0xff, 0x70, 0x0, 0x70, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0x0, 0x34, 0x33, 0xff, 0x1, 0x7f, 0x7e, 0xff, 0x5c, 0x58, 0x0, 0xff, 0x82, 0x7e, 0x0, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff}, 260 Stride: 16, 261 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 262 }, 263 }, 264 { 265 "Clone YCbCr 420", 266 &image.YCbCr{ 267 Y: []uint8{0x4c, 0x69, 0x1d, 0xb1, 0x96, 0xe2, 0x26, 0x34, 0xe, 0x59, 0x4b, 0x71, 0x0, 0x4c, 0x99, 0xff}, 268 Cb: []uint8{0x01, 0xaa, 0x80, 0x80}, 269 Cr: []uint8{0x95, 0xb5, 0x80, 0x80}, 270 YStride: 4, CStride: 2, 271 SubsampleRatio: image.YCbCrSubsampleRatio420, 272 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 273 }, 274 &image.NRGBA{ 275 Pix: []uint8{0x69, 0x69, 0x0, 0xff, 0x86, 0x86, 0x0, 0xff, 0x67, 0x0, 0x67, 0xff, 0xfb, 0x7d, 0xfb, 0xff, 0xb3, 0xb3, 0x0, 0xff, 0xff, 0xff, 0x1, 0xff, 0x70, 0x0, 0x70, 0xff, 0x7e, 0x0, 0x7e, 0xff, 0xe, 0xe, 0xe, 0xff, 0x59, 0x59, 0x59, 0xff, 0x4b, 0x4b, 0x4b, 0xff, 0x71, 0x71, 0x71, 0xff, 0x0, 0x0, 0x0, 0xff, 0x4c, 0x4c, 0x4c, 0xff, 0x99, 0x99, 0x99, 0xff, 0xff, 0xff, 0xff, 0xff}, 276 Stride: 16, 277 Rect: image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: 4, Y: 4}}, 278 }, 279 }, 280 { 281 "Clone Paletted", 282 &image.Paletted{ 283 Rect: image.Rect(-1, -1, 5, 0), 284 Stride: 6 * 1, 285 Palette: color.Palette{ 286 color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff}, 287 color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, 288 color.NRGBA{R: 0x7f, G: 0x7f, B: 0x7f, A: 0xff}, 289 color.NRGBA{R: 0x7f, G: 0x00, B: 0x00, A: 0xff}, 290 color.NRGBA{R: 0x00, G: 0x7f, B: 0x00, A: 0xff}, 291 color.NRGBA{R: 0x00, G: 0x00, B: 0x7f, A: 0xff}, 292 }, 293 Pix: []uint8{0x0, 0x1, 0x2, 0x3, 0x4, 0x5}, 294 }, 295 &image.NRGBA{ 296 Rect: image.Rect(0, 0, 6, 1), 297 Stride: 6 * 4, 298 Pix: []uint8{ 299 0x00, 0x00, 0x00, 0xff, 300 0xff, 0xff, 0xff, 0xff, 301 0x7f, 0x7f, 0x7f, 0xff, 302 0x7f, 0x00, 0x00, 0xff, 303 0x00, 0x7f, 0x00, 0xff, 304 0x00, 0x00, 0x7f, 0xff, 305 }, 306 }, 307 }, 308 } 309 310 for _, tc := range testCases { 311 t.Run(tc.name, func(t *testing.T) { 312 got := Clone(tc.src) 313 delta := 0 314 if _, ok := tc.src.(*image.YCbCr); ok { 315 delta = 1 316 } 317 if !compareNRGBA(got, tc.want, delta) { 318 t.Fatalf("got result %#v want %#v", got, tc.want) 319 } 320 }) 321 } 322} 323 324func TestCrop(t *testing.T) { 325 testCases := []struct { 326 name string 327 src image.Image 328 r image.Rectangle 329 want *image.NRGBA 330 }{ 331 { 332 "Crop 2x3 2x1", 333 &image.NRGBA{ 334 Rect: image.Rect(-1, -1, 1, 2), 335 Stride: 2 * 4, 336 Pix: []uint8{ 337 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 338 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 339 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 340 }, 341 }, 342 image.Rect(-1, 0, 1, 1), 343 &image.NRGBA{ 344 Rect: image.Rect(0, 0, 2, 1), 345 Stride: 2 * 4, 346 Pix: []uint8{ 347 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 348 }, 349 }, 350 }, 351 } 352 for _, tc := range testCases { 353 t.Run(tc.name, func(t *testing.T) { 354 got := Crop(tc.src, tc.r) 355 if !compareNRGBA(got, tc.want, 0) { 356 t.Fatalf("got result %#v want %#v", got, tc.want) 357 } 358 }) 359 } 360} 361 362func BenchmarkCrop(b *testing.B) { 363 b.ReportAllocs() 364 for i := 0; i < b.N; i++ { 365 Crop(testdataBranchesJPG, image.Rect(100, 100, 300, 300)) 366 } 367} 368 369func TestCropCenter(t *testing.T) { 370 testCases := []struct { 371 name string 372 src image.Image 373 w, h int 374 want *image.NRGBA 375 }{ 376 { 377 "CropCenter 2x3 2x1", 378 &image.NRGBA{ 379 Rect: image.Rect(-1, -1, 1, 2), 380 Stride: 2 * 4, 381 Pix: []uint8{ 382 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 383 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 384 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 385 }, 386 }, 387 2, 1, 388 &image.NRGBA{ 389 Rect: image.Rect(0, 0, 2, 1), 390 Stride: 2 * 4, 391 Pix: []uint8{ 392 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 393 }, 394 }, 395 }, 396 { 397 "CropCenter 2x3 0x1", 398 &image.NRGBA{ 399 Rect: image.Rect(-1, -1, 1, 2), 400 Stride: 2 * 4, 401 Pix: []uint8{ 402 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 403 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 404 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 405 }, 406 }, 407 0, 1, 408 &image.NRGBA{ 409 Rect: image.Rect(0, 0, 0, 0), 410 Stride: 0, 411 Pix: []uint8{}, 412 }, 413 }, 414 { 415 "CropCenter 2x3 5x5", 416 &image.NRGBA{ 417 Rect: image.Rect(-1, -1, 1, 2), 418 Stride: 2 * 4, 419 Pix: []uint8{ 420 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 421 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 422 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 423 }, 424 }, 425 5, 5, 426 &image.NRGBA{ 427 Rect: image.Rect(0, 0, 2, 3), 428 Stride: 2 * 4, 429 Pix: []uint8{ 430 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 431 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 432 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 433 }, 434 }, 435 }, 436 } 437 for _, tc := range testCases { 438 t.Run(tc.name, func(t *testing.T) { 439 got := CropCenter(tc.src, tc.w, tc.h) 440 if !compareNRGBA(got, tc.want, 0) { 441 t.Fatalf("got result %#v want %#v", got, tc.want) 442 } 443 }) 444 } 445} 446 447func TestCropAnchor(t *testing.T) { 448 testCases := []struct { 449 name string 450 src image.Image 451 w, h int 452 anchor Anchor 453 want *image.NRGBA 454 }{ 455 { 456 "CropAnchor 4x4 2x2 TopLeft", 457 &image.NRGBA{ 458 Rect: image.Rect(-1, -1, 3, 3), 459 Stride: 4 * 4, 460 Pix: []uint8{ 461 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 462 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 463 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 464 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 465 }, 466 }, 467 2, 2, 468 TopLeft, 469 &image.NRGBA{ 470 Rect: image.Rect(0, 0, 2, 2), 471 Stride: 2 * 4, 472 Pix: []uint8{ 473 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 474 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 475 }, 476 }, 477 }, 478 { 479 "CropAnchor 4x4 2x2 Top", 480 &image.NRGBA{ 481 Rect: image.Rect(-1, -1, 3, 3), 482 Stride: 4 * 4, 483 Pix: []uint8{ 484 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 485 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 486 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 487 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 488 }, 489 }, 490 2, 2, 491 Top, 492 &image.NRGBA{ 493 Rect: image.Rect(0, 0, 2, 2), 494 Stride: 2 * 4, 495 Pix: []uint8{ 496 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 497 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 498 }, 499 }, 500 }, 501 { 502 "CropAnchor 4x4 2x2 TopRight", 503 &image.NRGBA{ 504 Rect: image.Rect(-1, -1, 3, 3), 505 Stride: 4 * 4, 506 Pix: []uint8{ 507 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 508 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 509 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 510 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 511 }, 512 }, 513 2, 2, 514 TopRight, 515 &image.NRGBA{ 516 Rect: image.Rect(0, 0, 2, 2), 517 Stride: 2 * 4, 518 Pix: []uint8{ 519 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 520 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 521 }, 522 }, 523 }, 524 { 525 "CropAnchor 4x4 2x2 Left", 526 &image.NRGBA{ 527 Rect: image.Rect(-1, -1, 3, 3), 528 Stride: 4 * 4, 529 Pix: []uint8{ 530 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 531 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 532 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 533 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 534 }, 535 }, 536 2, 2, 537 Left, 538 &image.NRGBA{ 539 Rect: image.Rect(0, 0, 2, 2), 540 Stride: 2 * 4, 541 Pix: []uint8{ 542 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 543 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 544 }, 545 }, 546 }, 547 { 548 "CropAnchor 4x4 2x2 Center", 549 &image.NRGBA{ 550 Rect: image.Rect(-1, -1, 3, 3), 551 Stride: 4 * 4, 552 Pix: []uint8{ 553 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 554 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 555 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 556 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 557 }, 558 }, 559 2, 2, 560 Center, 561 &image.NRGBA{ 562 Rect: image.Rect(0, 0, 2, 2), 563 Stride: 2 * 4, 564 Pix: []uint8{ 565 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 566 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 567 }, 568 }, 569 }, 570 { 571 "CropAnchor 4x4 2x2 Right", 572 &image.NRGBA{ 573 Rect: image.Rect(-1, -1, 3, 3), 574 Stride: 4 * 4, 575 Pix: []uint8{ 576 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 577 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 578 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 579 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 580 }, 581 }, 582 2, 2, 583 Right, 584 &image.NRGBA{ 585 Rect: image.Rect(0, 0, 2, 2), 586 Stride: 2 * 4, 587 Pix: []uint8{ 588 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 589 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 590 }, 591 }, 592 }, 593 { 594 "CropAnchor 4x4 2x2 BottomLeft", 595 &image.NRGBA{ 596 Rect: image.Rect(-1, -1, 3, 3), 597 Stride: 4 * 4, 598 Pix: []uint8{ 599 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 600 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 601 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 602 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 603 }, 604 }, 605 2, 2, 606 BottomLeft, 607 &image.NRGBA{ 608 Rect: image.Rect(0, 0, 2, 2), 609 Stride: 2 * 4, 610 Pix: []uint8{ 611 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 612 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 613 }, 614 }, 615 }, 616 { 617 "CropAnchor 4x4 2x2 Bottom", 618 &image.NRGBA{ 619 Rect: image.Rect(-1, -1, 3, 3), 620 Stride: 4 * 4, 621 Pix: []uint8{ 622 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 623 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 624 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 625 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 626 }, 627 }, 628 2, 2, 629 Bottom, 630 &image.NRGBA{ 631 Rect: image.Rect(0, 0, 2, 2), 632 Stride: 2 * 4, 633 Pix: []uint8{ 634 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 635 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 636 }, 637 }, 638 }, 639 { 640 "CropAnchor 4x4 2x2 BottomRight", 641 &image.NRGBA{ 642 Rect: image.Rect(-1, -1, 3, 3), 643 Stride: 4 * 4, 644 Pix: []uint8{ 645 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 646 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 647 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 648 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 649 }, 650 }, 651 2, 2, 652 BottomRight, 653 &image.NRGBA{ 654 Rect: image.Rect(0, 0, 2, 2), 655 Stride: 2 * 4, 656 Pix: []uint8{ 657 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 658 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 659 }, 660 }, 661 }, 662 { 663 "CropAnchor 4x4 0x0 BottomRight", 664 &image.NRGBA{ 665 Rect: image.Rect(-1, -1, 3, 3), 666 Stride: 4 * 4, 667 Pix: []uint8{ 668 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 669 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 670 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 671 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 672 }, 673 }, 674 0, 0, 675 BottomRight, 676 &image.NRGBA{ 677 Rect: image.Rect(0, 0, 0, 0), 678 Stride: 0, 679 Pix: []uint8{}, 680 }, 681 }, 682 { 683 "CropAnchor 4x4 100x100 BottomRight", 684 &image.NRGBA{ 685 Rect: image.Rect(-1, -1, 3, 3), 686 Stride: 4 * 4, 687 Pix: []uint8{ 688 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 689 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 690 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 691 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 692 }, 693 }, 694 100, 100, 695 BottomRight, 696 &image.NRGBA{ 697 Rect: image.Rect(0, 0, 4, 4), 698 Stride: 4 * 4, 699 Pix: []uint8{ 700 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 701 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 702 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 703 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 704 }, 705 }, 706 }, 707 { 708 "CropAnchor 4x4 1x100 BottomRight", 709 &image.NRGBA{ 710 Rect: image.Rect(-1, -1, 3, 3), 711 Stride: 4 * 4, 712 Pix: []uint8{ 713 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 714 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 715 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 716 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 717 }, 718 }, 719 1, 100, 720 BottomRight, 721 &image.NRGBA{ 722 Rect: image.Rect(0, 0, 1, 4), 723 Stride: 1 * 4, 724 Pix: []uint8{ 725 0x0c, 0x0d, 0x0e, 0x0f, 726 0x1c, 0x1d, 0x1e, 0x1f, 727 0x2c, 0x2d, 0x2e, 0x2f, 728 0x3c, 0x3d, 0x3e, 0x3f, 729 }, 730 }, 731 }, 732 { 733 "CropAnchor 4x4 0x100 BottomRight", 734 &image.NRGBA{ 735 Rect: image.Rect(-1, -1, 3, 3), 736 Stride: 4 * 4, 737 Pix: []uint8{ 738 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 739 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 740 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 741 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 742 }, 743 }, 744 0, 100, 745 BottomRight, 746 &image.NRGBA{ 747 Rect: image.Rect(0, 0, 0, 0), 748 Stride: 0, 749 Pix: []uint8{}, 750 }, 751 }, 752 } 753 for _, tc := range testCases { 754 t.Run(tc.name, func(t *testing.T) { 755 got := CropAnchor(tc.src, tc.w, tc.h, tc.anchor) 756 if !compareNRGBA(got, tc.want, 0) { 757 t.Fatalf("got result %#v want %#v", got, tc.want) 758 } 759 }) 760 } 761} 762 763func TestPaste(t *testing.T) { 764 testCases := []struct { 765 name string 766 src1 image.Image 767 src2 image.Image 768 p image.Point 769 want *image.NRGBA 770 }{ 771 { 772 "Paste 2x3 2x1", 773 &image.NRGBA{ 774 Rect: image.Rect(-1, -1, 1, 2), 775 Stride: 2 * 4, 776 Pix: []uint8{ 777 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 778 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 779 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 780 }, 781 }, 782 &image.NRGBA{ 783 Rect: image.Rect(1, 1, 3, 2), 784 Stride: 2 * 4, 785 Pix: []uint8{ 786 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 787 }, 788 }, 789 image.Pt(-1, 0), 790 &image.NRGBA{ 791 Rect: image.Rect(0, 0, 2, 3), 792 Stride: 2 * 4, 793 Pix: []uint8{ 794 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 795 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 796 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 797 }, 798 }, 799 }, 800 { 801 "Paste 3x4 4x3 bottom right intersection", 802 &image.NRGBA{ 803 Rect: image.Rect(-1, -1, 2, 3), 804 Stride: 3 * 4, 805 Pix: []uint8{ 806 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 807 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 808 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 809 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 810 }, 811 }, 812 &image.NRGBA{ 813 Rect: image.Rect(1, 1, 5, 4), 814 Stride: 4 * 4, 815 Pix: []uint8{ 816 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 817 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 818 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 819 }, 820 }, 821 image.Pt(0, 1), 822 &image.NRGBA{ 823 Rect: image.Rect(0, 0, 3, 4), 824 Stride: 3 * 4, 825 Pix: []uint8{ 826 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 827 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 828 0x30, 0x31, 0x32, 0x33, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 829 0x40, 0x41, 0x42, 0x43, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 830 }, 831 }, 832 }, 833 { 834 "Paste 3x4 4x3 top left intersection", 835 &image.NRGBA{ 836 Rect: image.Rect(-1, -1, 2, 3), 837 Stride: 3 * 4, 838 Pix: []uint8{ 839 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 840 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 841 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 842 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 843 }, 844 }, 845 &image.NRGBA{ 846 Rect: image.Rect(1, 1, 5, 4), 847 Stride: 4 * 4, 848 Pix: []uint8{ 849 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 850 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 851 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 852 }, 853 }, 854 image.Pt(-3, -2), 855 &image.NRGBA{ 856 Rect: image.Rect(0, 0, 3, 4), 857 Stride: 3 * 4, 858 Pix: []uint8{ 859 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0x18, 0x19, 0x1a, 0x1b, 860 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x28, 0x29, 0x2a, 0x2b, 861 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 862 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 863 }, 864 }, 865 }, 866 { 867 "Paste 3x4 4x3 no intersection", 868 &image.NRGBA{ 869 Rect: image.Rect(-1, -1, 2, 3), 870 Stride: 3 * 4, 871 Pix: []uint8{ 872 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 873 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 874 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 875 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 876 }, 877 }, 878 &image.NRGBA{ 879 Rect: image.Rect(1, 1, 5, 4), 880 Stride: 4 * 4, 881 Pix: []uint8{ 882 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 883 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 884 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 885 }, 886 }, 887 image.Pt(-20, 20), 888 &image.NRGBA{ 889 Rect: image.Rect(0, 0, 3, 4), 890 Stride: 3 * 4, 891 Pix: []uint8{ 892 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 893 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 894 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 895 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 896 }, 897 }, 898 }, 899 } 900 for _, tc := range testCases { 901 t.Run(tc.name, func(t *testing.T) { 902 got := Paste(tc.src1, tc.src2, tc.p) 903 if !compareNRGBA(got, tc.want, 0) { 904 t.Fatalf("got result %#v want %#v", got, tc.want) 905 } 906 }) 907 } 908} 909 910func BenchmarkPaste(b *testing.B) { 911 b.ReportAllocs() 912 for i := 0; i < b.N; i++ { 913 Paste(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100)) 914 } 915} 916 917func TestPasteCenter(t *testing.T) { 918 testCases := []struct { 919 name string 920 src1 image.Image 921 src2 image.Image 922 want *image.NRGBA 923 }{ 924 { 925 "PasteCenter 2x3 2x1", 926 &image.NRGBA{ 927 Rect: image.Rect(-1, -1, 1, 2), 928 Stride: 2 * 4, 929 Pix: []uint8{ 930 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 931 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 932 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 933 }, 934 }, 935 &image.NRGBA{ 936 Rect: image.Rect(1, 1, 3, 2), 937 Stride: 2 * 4, 938 Pix: []uint8{ 939 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 940 }, 941 }, 942 &image.NRGBA{ 943 Rect: image.Rect(0, 0, 2, 3), 944 Stride: 2 * 4, 945 Pix: []uint8{ 946 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 947 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 948 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 949 }, 950 }, 951 }, 952 } 953 for _, tc := range testCases { 954 t.Run(tc.name, func(t *testing.T) { 955 got := PasteCenter(tc.src1, tc.src2) 956 if !compareNRGBA(got, tc.want, 0) { 957 t.Fatalf("got result %#v want %#v", got, tc.want) 958 } 959 }) 960 } 961} 962 963func TestOverlay(t *testing.T) { 964 testCases := []struct { 965 name string 966 src1 image.Image 967 src2 image.Image 968 p image.Point 969 a float64 970 want *image.NRGBA 971 }{ 972 { 973 "Overlay 2x3 2x1 1.0", 974 &image.NRGBA{ 975 Rect: image.Rect(-1, -1, 1, 2), 976 Stride: 2 * 4, 977 Pix: []uint8{ 978 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 979 0x60, 0x00, 0x90, 0xff, 0xff, 0x00, 0x99, 0x7f, 980 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 981 }, 982 }, 983 &image.NRGBA{ 984 Rect: image.Rect(1, 1, 3, 2), 985 Stride: 2 * 4, 986 Pix: []uint8{ 987 0x20, 0x40, 0x80, 0x7f, 0xaa, 0xbb, 0xcc, 0xff, 988 }, 989 }, 990 image.Pt(-1, 0), 991 1.0, 992 &image.NRGBA{ 993 Rect: image.Rect(0, 0, 2, 3), 994 Stride: 2 * 4, 995 Pix: []uint8{ 996 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff, 997 0x40, 0x1f, 0x88, 0xff, 0xaa, 0xbb, 0xcc, 0xff, 998 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 999 }, 1000 }, 1001 }, 1002 { 1003 "Overlay 2x2 2x2 0.5", 1004 &image.NRGBA{ 1005 Rect: image.Rect(-1, -1, 1, 1), 1006 Stride: 2 * 4, 1007 Pix: []uint8{ 1008 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 1009 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00, 1010 }, 1011 }, 1012 &image.NRGBA{ 1013 Rect: image.Rect(-1, -1, 1, 1), 1014 Stride: 2 * 4, 1015 Pix: []uint8{ 1016 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 1017 0xff, 0xff, 0x00, 0xff, 0x20, 0x20, 0x20, 0xff, 1018 }, 1019 }, 1020 image.Pt(-1, -1), 1021 0.5, 1022 &image.NRGBA{ 1023 Rect: image.Rect(0, 0, 2, 2), 1024 Stride: 2 * 4, 1025 Pix: []uint8{ 1026 0xff, 0x7f, 0x7f, 0xff, 0x00, 0xff, 0x00, 0xff, 1027 0x7f, 0x7f, 0x7f, 0xff, 0x20, 0x20, 0x20, 0x7f, 1028 }, 1029 }, 1030 }, 1031 { 1032 "Overlay 2x2 2x2 0.5 no intersection", 1033 &image.NRGBA{ 1034 Rect: image.Rect(-1, -1, 1, 1), 1035 Stride: 2 * 4, 1036 Pix: []uint8{ 1037 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 1038 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00, 1039 }, 1040 }, 1041 &image.NRGBA{ 1042 Rect: image.Rect(-1, -1, 1, 1), 1043 Stride: 2 * 4, 1044 Pix: []uint8{ 1045 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 1046 0xff, 0xff, 0x00, 0xff, 0x20, 0x20, 0x20, 0xff, 1047 }, 1048 }, 1049 image.Pt(-10, 10), 1050 0.5, 1051 &image.NRGBA{ 1052 Rect: image.Rect(0, 0, 2, 2), 1053 Stride: 2 * 4, 1054 Pix: []uint8{ 1055 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 1056 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00, 1057 }, 1058 }, 1059 }, 1060 } 1061 for _, tc := range testCases { 1062 t.Run(tc.name, func(t *testing.T) { 1063 got := Overlay(tc.src1, tc.src2, tc.p, tc.a) 1064 if !compareNRGBA(got, tc.want, 0) { 1065 t.Fatalf("got result %#v want %#v", got, tc.want) 1066 } 1067 }) 1068 } 1069} 1070 1071func BenchmarkOverlay(b *testing.B) { 1072 b.ReportAllocs() 1073 for i := 0; i < b.N; i++ { 1074 Overlay(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100), 0.5) 1075 } 1076} 1077 1078func TestOverlayCenter(t *testing.T) { 1079 testCases := []struct { 1080 name string 1081 src1 image.Image 1082 src2 image.Image 1083 a float64 1084 want *image.NRGBA 1085 }{ 1086 { 1087 "OverlayCenter 2x3 2x1", 1088 &image.NRGBA{ 1089 Rect: image.Rect(-1, -1, 1, 2), 1090 Stride: 2 * 4, 1091 Pix: []uint8{ 1092 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff, 1093 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff, 1094 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff, 1095 }, 1096 }, 1097 &image.NRGBA{ 1098 Rect: image.Rect(1, 1, 3, 2), 1099 Stride: 2 * 4, 1100 Pix: []uint8{ 1101 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 1102 }, 1103 }, 1104 0.5, 1105 &image.NRGBA{ 1106 Rect: image.Rect(0, 0, 2, 3), 1107 Stride: 2 * 4, 1108 Pix: []uint8{ 1109 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff, 1110 0x2c, 0x2c, 0x2c, 0xff, 0x2c, 0x2c, 0x2c, 0xff, 1111 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff, 1112 }, 1113 }, 1114 }, 1115 } 1116 for _, tc := range testCases { 1117 t.Run(tc.name, func(t *testing.T) { 1118 got := OverlayCenter(tc.src1, tc.src2, 0.5) 1119 if !compareNRGBA(got, tc.want, 0) { 1120 t.Fatalf("got result %#v want %#v", got, tc.want) 1121 } 1122 }) 1123 } 1124} 1125