145 lines
4.8 KiB
Go
145 lines
4.8 KiB
Go
package math
|
|
|
|
import (
|
|
"fmt"
|
|
"git.gammaspectra.live/WeebDataHoarder/swf-go/types"
|
|
"math"
|
|
)
|
|
|
|
type ColorTransform struct {
|
|
Multiply struct {
|
|
Red types.Fixed8
|
|
Green types.Fixed8
|
|
Blue types.Fixed8
|
|
Alpha types.Fixed8
|
|
}
|
|
Add struct {
|
|
Red int16
|
|
Green int16
|
|
Blue int16
|
|
Alpha int16
|
|
}
|
|
}
|
|
|
|
const ColorTransformMultiplyFactor = math.MaxUint8 + 1
|
|
|
|
func IdentityColorTransform() ColorTransform {
|
|
return ColorTransform{
|
|
Multiply: struct {
|
|
Red types.Fixed8
|
|
Green types.Fixed8
|
|
Blue types.Fixed8
|
|
Alpha types.Fixed8
|
|
}{
|
|
Red: ColorTransformMultiplyFactor,
|
|
Green: ColorTransformMultiplyFactor,
|
|
Blue: ColorTransformMultiplyFactor,
|
|
Alpha: ColorTransformMultiplyFactor,
|
|
},
|
|
Add: struct {
|
|
Red int16
|
|
Green int16
|
|
Blue int16
|
|
Alpha int16
|
|
}{},
|
|
}
|
|
}
|
|
|
|
func (t ColorTransform) String() string {
|
|
return fmt.Sprintf("ColorTransform{MULT(%d,%d,%d,%d),ADD(%d,%d,%d,%d)}",
|
|
t.Multiply.Red,
|
|
t.Multiply.Green,
|
|
t.Multiply.Blue,
|
|
t.Multiply.Alpha,
|
|
t.Add.Red,
|
|
t.Add.Green,
|
|
t.Add.Blue,
|
|
t.Add.Alpha,
|
|
)
|
|
}
|
|
|
|
func (t ColorTransform) IsIdentity() bool {
|
|
return t.Add.Red == 0 && t.Add.Green == 0 && t.Add.Blue == 0 && t.Add.Alpha == 0 && t.Multiply.Red == 256 && t.Multiply.Green == 256 && t.Multiply.Blue == 256 && t.Multiply.Alpha == 256
|
|
}
|
|
|
|
func (t ColorTransform) ApplyMultiplyToColor(color Color) Color {
|
|
return Color{
|
|
R: uint8(max(0, min((int64(t.Multiply.Red)*int64(color.R))/(math.MaxUint8+1), 255))),
|
|
G: uint8(max(0, min((int64(t.Multiply.Green)*int64(color.G))/(math.MaxUint8+1), 255))),
|
|
B: uint8(max(0, min((int64(t.Multiply.Blue)*int64(color.B))/(math.MaxUint8+1), 255))),
|
|
Alpha: uint8(max(0, min((int64(t.Multiply.Alpha)*int64(color.Alpha))/(math.MaxUint8+1), 255))),
|
|
}
|
|
}
|
|
|
|
func (t ColorTransform) ApplyAdditionToColor(color Color) Color {
|
|
return Color{
|
|
R: uint8(max(0, min(int64(t.Add.Red)+int64(color.R), 255))),
|
|
G: uint8(max(0, min(int64(t.Add.Green)+int64(color.G), 255))),
|
|
B: uint8(max(0, min(int64(t.Add.Blue)+int64(color.B), 255))),
|
|
Alpha: uint8(max(0, min(int64(t.Add.Alpha)+int64(color.Alpha), 255))),
|
|
}
|
|
}
|
|
|
|
func (t ColorTransform) ApplyToColor(color Color) Color {
|
|
return Color{
|
|
R: uint8(max(0, min((int64(t.Multiply.Red)*int64(color.R))/ColorTransformMultiplyFactor+int64(t.Add.Red), 255))),
|
|
G: uint8(max(0, min((int64(t.Multiply.Green)*int64(color.G))/ColorTransformMultiplyFactor+int64(t.Add.Green), 255))),
|
|
B: uint8(max(0, min((int64(t.Multiply.Blue)*int64(color.B))/ColorTransformMultiplyFactor+int64(t.Add.Blue), 255))),
|
|
Alpha: uint8(max(0, min((int64(t.Multiply.Alpha)*int64(color.Alpha))/ColorTransformMultiplyFactor+int64(t.Add.Alpha), 255))),
|
|
}
|
|
}
|
|
|
|
func (t ColorTransform) Combine(o ColorTransform) ColorTransform {
|
|
return ColorTransform{
|
|
Multiply: struct {
|
|
Red types.Fixed8
|
|
Green types.Fixed8
|
|
Blue types.Fixed8
|
|
Alpha types.Fixed8
|
|
}{
|
|
//TODO: maybe needs more than just /(math.MaxUint8+1)
|
|
//TODO: maybe this wraps?
|
|
Red: types.Fixed8(max(math.MinInt16, min((int64(t.Multiply.Red)*int64(o.Multiply.Red))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Green: types.Fixed8(max(math.MinInt16, min((int64(t.Multiply.Green)*int64(o.Multiply.Green))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Blue: types.Fixed8(max(math.MinInt16, min((int64(t.Multiply.Blue)*int64(o.Multiply.Blue))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Alpha: types.Fixed8(max(math.MinInt16, min((int64(t.Multiply.Alpha)*int64(o.Multiply.Alpha))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
},
|
|
|
|
Add: struct {
|
|
Red int16
|
|
Green int16
|
|
Blue int16
|
|
Alpha int16
|
|
}{
|
|
Red: int16(max(math.MinInt16, min(int64(t.Add.Red)+(int64(t.Multiply.Red)*int64(o.Add.Red))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Green: int16(max(math.MinInt16, min(int64(t.Add.Green)+(int64(t.Multiply.Green)*int64(o.Add.Green))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Blue: int16(max(math.MinInt16, min(int64(t.Add.Blue)+(int64(t.Multiply.Blue)*int64(o.Add.Blue))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
Alpha: int16(max(math.MinInt16, min(int64(t.Add.Alpha)+(int64(t.Multiply.Alpha)*int64(o.Add.Alpha))/ColorTransformMultiplyFactor, math.MaxInt16))),
|
|
},
|
|
}
|
|
}
|
|
|
|
func ColorTransformFromSWFAlpha(cx types.CXFORMWITHALPHA) (t ColorTransform) {
|
|
t.Multiply.Red = cx.Multiply.Red
|
|
t.Multiply.Green = cx.Multiply.Red
|
|
t.Multiply.Blue = cx.Multiply.Blue
|
|
t.Multiply.Alpha = cx.Multiply.Alpha
|
|
t.Add.Red = cx.Add.Red
|
|
t.Add.Green = cx.Add.Green
|
|
t.Add.Blue = cx.Add.Blue
|
|
t.Add.Alpha = cx.Add.Alpha
|
|
return t
|
|
}
|
|
|
|
func ColorTransformFromSWF(cx types.CXFORM) (t ColorTransform) {
|
|
t.Multiply.Red = cx.Multiply.Red
|
|
t.Multiply.Green = cx.Multiply.Red
|
|
t.Multiply.Blue = cx.Multiply.Blue
|
|
t.Multiply.Alpha = ColorTransformMultiplyFactor
|
|
t.Add.Red = cx.Add.Red
|
|
t.Add.Green = cx.Add.Green
|
|
t.Add.Blue = cx.Add.Blue
|
|
t.Add.Alpha = 0
|
|
return t
|
|
}
|