code: func Rotate(img image.Image, angle float64, bgColor color.Color) *image.NRGBA {
  	angle = angle - math.Floor(angle/360)*360
  
  	switch angle {
  	case 0:
  		return Clone(img)
  	case 90:
  		return Rotate90(img)
  	case 180:
  		return Rotate180(img)
  	case 270:
  		return Rotate270(img)
  	}
  
  	src := toNRGBA(img)
  	srcW := src.Bounds().Max.X
  	srcH := src.Bounds().Max.Y
  	dstW, dstH := rotatedSize(srcW, srcH, angle)
  	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  
  	if dstW <= 0 || dstH <= 0 {
  		return dst
  	}
  
  	srcXOff := float64(srcW)/2 - 0.5
  	srcYOff := float64(srcH)/2 - 0.5
  	dstXOff := float64(dstW)/2 - 0.5
  	dstYOff := float64(dstH)/2 - 0.5
  
  	bgColorNRGBA := color.NRGBAModel.Convert(bgColor).(color.NRGBA)
  	sin, cos := math.Sincos(math.Pi * angle / 180)
  
  	parallel(0, dstH, func(ys <-chan int) {
  		for dstY := range ys {
  			for dstX := 0; dstX < dstW; dstX++ {
  				xf, yf := rotatePoint(float64(dstX)-dstXOff, float64(dstY)-dstYOff, sin, cos)
  				xf, yf = xf+srcXOff, yf+srcYOff
  				interpolatePoint(dst, dstX, dstY, src, xf, yf, bgColorNRGBA)
  			}
  		}
  	})
  
  	return dst
  }
docs: // Rotate rotates an image by the given angle counter-clockwise .
  // The angle parameter is the rotation angle in degrees.
  // The bgColor parameter specifies the color of the uncovered zone after the rotation.