alpha patterns

This commit is contained in:
Dmitry Sergeev
2026-09-18 10:11:07 +03:00
parent 9b194b5591
commit dea2e6a59f
12 changed files with 643 additions and 3 deletions
+63
View File
@@ -0,0 +1,63 @@
package generator
import "fmt"
// V210AGenerator combines a v210 fill generator with a packed 10-bit alpha
// plane. It owns the fill generator and closes it from Close.
type V210AGenerator struct {
fill FrameGenerator
width int
height int
fillSize int
alphaBase []byte
}
var _ FrameGenerator = (*V210AGenerator)(nil)
func NewV210AGenerator(
fill FrameGenerator,
width, height uint,
) (*V210AGenerator, error) {
if fill == nil {
return nil, fmt.Errorf("v210a: fill generator is nil")
}
if width == 0 || height == 0 {
return nil, fmt.Errorf("v210a: width and height must be greater than zero, got %dx%d", width, height)
}
if width%2 != 0 {
return nil, fmt.Errorf("v210a: width must be even for 4:2:2 video, got %d", width)
}
g := &V210AGenerator{
fill: fill,
width: int(width),
height: int(height),
fillSize: V210FrameSize(int(width), int(height)),
alphaBase: make([]byte, AlphaFrameSize(int(width), int(height))),
}
if err := fillAlphaPlane(g.alphaBase, g.width, g.height, alphaOpaque); err != nil {
return nil, fmt.Errorf("v210a: initialize alpha plane: %w", err)
}
return g, nil
}
func (g *V210AGenerator) GenerateFrame(dst []byte, frameIndex int) error {
need := V210AFrameSize(g.width, g.height)
if len(dst) < need {
return fmt.Errorf("v210a: destination is too small: got %d bytes, need %d", len(dst), need)
}
if err := g.fill.GenerateFrame(dst[:g.fillSize], frameIndex); err != nil {
return fmt.Errorf("v210a: generate fill frame %d: %w", frameIndex, err)
}
alpha := dst[g.fillSize:need]
copy(alpha, g.alphaBase)
if err := patchAlphaMovingSquare(alpha, g.width, g.height, frameIndex); err != nil {
return fmt.Errorf("v210a: patch alpha frame %d: %w", frameIndex, err)
}
return nil
}
func (g *V210AGenerator) Close() error {
return g.fill.Close()
}