Files
2026-09-18 01:30:11 +03:00

75 lines
1.7 KiB
Go

package generator
import "math"
const movingSquareSize = 150
type baseColorFunc func(x, y, width, height int) YCbCr10
type squareBounds struct {
minX float64
maxX float64
minY float64
maxY float64
}
func movingSquareBounds(width, height, frameIndex int) squareBounds {
const half = float64(movingSquareSize) / 2
centerX := float64(width) / 2
centerY := float64(height) / 2
time := float64(frameIndex) / 25.0
offset := math.Sin(time*0.5) * (centerX - half)
return squareBounds{
minX: centerX - half + offset,
maxX: centerX + half + offset,
minY: centerY - half,
maxY: centerY + half,
}
}
func (b squareBounds) contains(x, y int) bool {
return float64(x) >= b.minX && float64(x) < b.maxX &&
float64(y) >= b.minY && float64(y) < b.maxY
}
func patchMovingSquare(
dst []byte,
width, height, frameIndex int,
baseColor baseColorFunc,
) error {
bounds := movingSquareBounds(width, height, frameIndex)
firstPixelX := max(0, int(math.Floor(bounds.minX)))
lastPixelX := min(width, int(math.Ceil(bounds.maxX)))
firstBlockX := firstPixelX / 6 * 6
lastBlockX := min(width, (lastPixelX+5)/6*6)
firstY := max(0, int(math.Floor(bounds.minY)))
lastY := min(height, int(math.Ceil(bounds.maxY)))
stride := V210LineSize(width)
for y := firstY; y < lastY; y++ {
for x := firstBlockX; x < lastBlockX; x += 6 {
var pixels [6]YCbCr10
for i := range pixels {
px := x + i
color := baseColor(px, y, width, height)
if bounds.contains(px, y) {
color = invertStudioRange(color)
}
pixels[i] = color
}
offset := y*stride + x/6*16
packV210Block(dst[offset:offset+16], pixels)
}
}
return nil
}
func invertStudioRange(color YCbCr10) YCbCr10 {
return YCbCr10{
Y: 1004 - color.Y,
Cb: 1024 - color.Cb,
Cr: 1024 - color.Cr,
}
}