Text + MXL logo pattern

This commit is contained in:
Dmitry Sergeev
2026-09-13 16:33:50 +03:00
parent 94ff41a124
commit 97dec92b8b
15 changed files with 999 additions and 23 deletions
+76
View File
@@ -0,0 +1,76 @@
// Logo plane construction for texture-sampling kernels (v210_dvd_logo.wgsl).
package generator
import (
"fmt"
"image"
"math"
"os"
// PNG decoder registration for LoadLogoPNG.
_ "image/png"
)
// BuildLogoPlane converts an image into the packed logo plane consumed by
// v210_dvd_logo.wgsl as read-only storage binding 2:
//
// logo[0] = width | height<<16
// logo[1+dy*w+dx] = opaque<<30 | Cr<<20 | Cb<<10 | Y
//
// Rec.709 full-range RGB -> 10-bit studio swing, the same transform behind
// the color-bar tables in the kernels (verified against all 21 bar values).
// Semi-transparent pixels (alpha >= 50%) count as opaque; the rest show the
// kernel background through.
func BuildLogoPlane(img image.Image) ([]uint32, error) {
b := img.Bounds()
w, h := b.Dx(), b.Dy()
if w <= 0 || h <= 0 || w > 0xFFFF || h > 0xFFFF {
return nil, fmt.Errorf("logo: bad dimensions %dx%d", w, h)
}
plane := make([]uint32, 1+w*h)
plane[0] = uint32(w) | uint32(h)<<16
for yy := 0; yy < h; yy++ {
for xx := 0; xx < w; xx++ {
r, g, bl, a := img.At(b.Min.X+xx, b.Min.Y+yy).RGBA()
if a < 1<<15 {
continue // transparent: shader falls back to background
}
// At().RGBA() is premultiplied; unpremultiply to full-range RGB.
rf := float64(r) / float64(a)
gf := float64(g) / float64(a)
bf := float64(bl) / float64(a)
luma := 0.2126*rf + 0.7152*gf + 0.0722*bf
yc := clamp10(64 + math.Round(876*luma))
cb := clamp10(512 + math.Round(448*(bf-luma)/(1-0.0722)))
cr := clamp10(512 + math.Round(448*(rf-luma)/(1-0.2126)))
plane[1+yy*w+xx] = 1<<30 | cr<<20 | cb<<10 | yc
}
}
return plane, nil
}
// clamp10 keeps a 10-bit code inside the legal 4..1019 range.
func clamp10(v float64) uint32 {
switch {
case v < 4:
return 4
case v > 1019:
return 1019
default:
return uint32(v)
}
}
// LoadLogoPNG reads a PNG file and builds the logo plane.
func LoadLogoPNG(path string) ([]uint32, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("logo: %w", err)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return nil, fmt.Errorf("logo: decode %s: %w", path, err)
}
return BuildLogoPlane(img)
}