// This is the meat of the gradient computation. It returns a HCL-blend between
// the two colors around `t`.
// Note: It relies heavily on the fact that the gradient keypoints are sorted.
965427
func (self GradientTable) GetInterpolatedColorFor(t float64) colorful.Color {
	for i := 0; i < len(self)-1; i++ {
		c1 := self[i]
		c2 := self[i+1]
		if c1.Pos <= t && t <= c2.Pos {
			// We are in between c1 and c2. Go blend them!
			t := (t - c1.Pos) / (c2.Pos - c1.Pos)
			return c1.Col.BlendHcl(c2.Col, t).Clamped()
		}
	}

	// Nothing found? Means we're at (or past) the last gradient keypoint.
	return self[len(self)-1].Col
}
995364
func (c1 Color) BlendLuv(c2 Color, t float64) Color {
	l1, u1, v1 := c1.Luv()
	l2, u2, v2 := c2.Luv()
	return Luv(l1+t*(l2-l1),
		u1+t*(u2-u1),
		v1+t*(v2-v1))
}
396219
func (m mathUtil) PercentDifference(v1, v2 float64) float64 {
	if v1 == 0 {
		return 0
	}
	return (v2 - v1) / v1
}
493992
func (cl Color) DistanceCIEDE2000klch(cr Color, kl, kc, kh float64) float64 {
	l1, a1, b1 := cl.Lab()
	l2, a2, b2 := cr.Lab()

	// As with CIE94, we scale up the ranges of L,a,b beforehand and scale
	// them down again afterwards.
	l1, a1, b1 = l1*100.0, a1*100.0, b1*100.0
	l2, a2, b2 = l2*100.0, a2*100.0, b2*100.0

	cab1 := math.Sqrt(sq(a1) + sq(b1))
	cab2 := math.Sqrt(sq(a2) + sq(b2))
	cabmean := (cab1 + cab2) / 2

	g := 0.5 * (1 - math.Sqrt(math.Pow(cabmean, 7)/(math.Pow(cabmean, 7)+math.Pow(25, 7))))
	ap1 := (1 + g) * a1
	ap2 := (1 + g) * a2
	cp1 := math.Sqrt(sq(ap1) + sq(b1))
	cp2 := math.Sqrt(sq(ap2) + sq(b2))

	hp1 := 0.0
	if b1 != ap1 || ap1 != 0 {
		hp1 = math.Atan2(b1, ap1)
		if hp1 < 0 {
			hp1 += math.Pi * 2
		}
		hp1 *= 180 / math.Pi
	}
	hp2 := 0.0
	if b2 != ap2 || ap2 != 0 {
		hp2 = math.Atan2(b2, ap2)
		if hp2 < 0 {
			hp2 += math.Pi * 2
		}
		hp2 *= 180 / math.Pi
	}

	deltaLp := l2 - l1
	deltaCp := cp2 - cp1
	dhp := 0.0
	cpProduct := cp1 * cp2
	if cpProduct != 0 {
		dhp = hp2 - hp1
		if dhp > 180 {
			dhp -= 360
		} else if dhp < -180 {
			dhp += 360
		}
	}
	deltaHp := 2 * math.Sqrt(cpProduct) * math.Sin(dhp/2*math.Pi/180)

	lpmean := (l1 + l2) / 2
	cpmean := (cp1 + cp2) / 2
	hpmean := hp1 + hp2
	if cpProduct != 0 {
		hpmean /= 2
		if math.Abs(hp1-hp2) > 180 {
			if hp1+hp2 < 360 {
				hpmean += 180
			} else {
				hpmean -= 180
			}
		}
	}

	t := 1 - 0.17*math.Cos((hpmean-30)*math.Pi/180) + 0.24*math.Cos(2*hpmean*math.Pi/180) + 0.32*math.Cos((3*hpmean+6)*math.Pi/180) - 0.2*math.Cos((4*hpmean-63)*math.Pi/180)
	deltaTheta := 30 * math.Exp(-sq((hpmean-275)/25))
	rc := 2 * math.Sqrt(math.Pow(cpmean, 7)/(math.Pow(cpmean, 7)+math.Pow(25, 7)))
	sl := 1 + (0.015*sq(lpmean-50))/math.Sqrt(20+sq(lpmean-50))
	sc := 1 + 0.045*cpmean
	sh := 1 + 0.015*cpmean*t
	rt := -math.Sin(2*deltaTheta*math.Pi/180) * rc

	return math.Sqrt(sq(deltaLp/(kl*sl))+sq(deltaCp/(kc*sc))+sq(deltaHp/(kh*sh))+rt*(deltaCp/(kc*sc))*(deltaHp/(kh*sh))) * 0.01
}
1010660
func (ss *segmentStack) calcTargetTopLevel() int {
	var minMergePercentage float64
	if ss.options != nil {
		minMergePercentage = ss.options.MinMergePercentage
	}
	if minMergePercentage <= 0 {
		minMergePercentage = DefaultCollectionOptions.MinMergePercentage
	}

	newTopLevel := 0
	maxTopLevel := len(ss.a) - 2

	for newTopLevel < maxTopLevel {
		numX0 := ss.a[newTopLevel].Len()
		numX1 := ss.a[newTopLevel+1].Len()
		if (float64(numX1) / float64(numX0)) > minMergePercentage {
			break
		}

		newTopLevel++
	}

	return newTopLevel
}
954479
func (col1 Color) BlendHcl(col2 Color, t float64) Color {
	h1, c1, l1 := col1.Hcl()
	h2, c2, l2 := col2.Hcl()

	// We know that h are both in [0..360]
	return Hcl(interp_angle(h1, h2, t), c1+t*(c2-c1), l1+t*(l2-l1))
}
169665
func Normal(bg image.Image, fg image.Image) *image.RGBA {
	dst := blend(bg, fg, func(c0, c1 fcolor.RGBAF64) fcolor.RGBAF64 {
		return alphaComp(c0, c1)
	})

	return dst
}
431462
func (c1 Color) DistanceLuv(c2 Color) float64 {
	l1, u1, v1 := c1.Luv()
	l2, u2, v2 := c2.Luv()
	return math.Sqrt(sq(l1-l2) + sq(u1-u2) + sq(v1-v2))
}
836043
func RGBASlicesEqual(a, b []color.RGBA) bool {
	if a == nil && b == nil {
		return true
	}

	if len(a) != len(b) {
		return false
	}

	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}

	return true
}
1214969
func baseShader(c *Canvas) {
	gs := &glShader{
		vf: defaultCanvasVertexFormat,
		vs: baseCanvasVertexShader,
		fs: baseCanvasFragmentShader,
	}

	gs.setUniform("uTransform", &gs.uniformDefaults.transform)
	gs.setUniform("uColorMask", &gs.uniformDefaults.colormask)
	gs.setUniform("uBounds", &gs.uniformDefaults.bounds)
	gs.setUniform("uTexBounds", &gs.uniformDefaults.texbounds)

	c.shader = gs
}
888501
func ConvexHull(geometry geom.T) geom.T {
	// copy coords because the algorithm reorders them
	calc := convexHullCalculator{
		layout:   geometry.Layout(),
		stride:   geometry.Layout().Stride(),
		inputPts: geometry.FlatCoords(),
	}

	return calc.getConvexHull()
}
1327767
func (c Colour) Distance(e2 Colour) float64 {
	ar, ag, ab := int64(c.Red()), int64(c.Green()), int64(c.Blue())
	br, bg, bb := int64(e2.Red()), int64(e2.Green()), int64(e2.Blue())
	rmean := (ar + br) / 2
	r := ar - br
	g := ag - bg
	b := ab - bb
	return math.Sqrt(float64((((512 + rmean) * r * r) >> 8) + 4*g*g + (((767 - rmean) * b * b) >> 8)))
}
1352311
func HlineColor(renderer *sdl.Renderer, x1, x2, y int32, color sdl.Color) bool {
	_x1 := C.Sint16(x1)
	_x2 := C.Sint16(x2)
	_y := C.Sint16(y)
	_color := C.Uint32(gfxColor(color))
	return C.hlineColor((*C.SDL_Renderer)(unsafe.Pointer(renderer)), _x1, _x2, _y, _color) == 0
}
959398
func AALineColor(renderer *sdl.Renderer, x1, y1, x2, y2 int32, color sdl.Color) bool {
	_x1 := C.Sint16(x1)
	_y1 := C.Sint16(y1)
	_x2 := C.Sint16(x2)
	_y2 := C.Sint16(y2)
	_color := C.Uint32(gfxColor(color))
	return C.aalineColor((*C.SDL_Renderer)(unsafe.Pointer(renderer)), _x1, _y1, _x2, _y2, _color) == 0
}
940923
func ThickLineColor(renderer *sdl.Renderer, x1, y1, x2, y2, width int32, color sdl.Color) bool {
	_x1 := C.Sint16(x1)
	_y1 := C.Sint16(y1)
	_x2 := C.Sint16(x2)
	_y2 := C.Sint16(y2)
	_width := C.Uint8(width)
	_color := C.Uint32(gfxColor(color))
	return C.thickLineColor((*C.SDL_Renderer)(unsafe.Pointer(renderer)), _x1, _y1, _x2, _y2, _width, _color) == 0
}
54197
func (c1 Color) BlendLab(c2 Color, t float64) Color {
	l1, a1, b1 := c1.Lab()
	l2, a2, b2 := c2.Lab()
	return Lab(l1+t*(l2-l1),
		a1+t*(a2-a1),
		b1+t*(b2-b1))
}
1086169
func (c1 Color) BlendHsv(c2 Color, t float64) Color {
	h1, s1, v1 := c1.Hsv()
	h2, s2, v2 := c2.Hsv()

	// We know that h are both in [0..360]
	return Hsv(interp_angle(h1, h2, t), s1+t*(s2-s1), v1+t*(v2-v1))
}