@@ -247,6 +247,293 @@ func BenchmarkAdjustSaturation(b *testing.B) {
247247 }
248248}
249249
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+
250537func TestAdjustContrast (t * testing.T ) {
251538 testCases := []struct {
252539 name string
0 commit comments