// 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) }