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