writeDepthPNG min-max normalises a depth map and writes it as an 8-bit grayscale PNG. Near = bright (255), far = dark (0), matching the usual depth-map convention for inverse-depth-like outputs.
(dst string, depth []float32, h, w int)
| 501 | // grayscale PNG. Near = bright (255), far = dark (0), matching the usual |
| 502 | // depth-map convention for inverse-depth-like outputs. |
| 503 | func writeDepthPNG(dst string, depth []float32, h, w int) error { |
| 504 | if h <= 0 || w <= 0 || len(depth) < h*w { |
| 505 | return fmt.Errorf("depth-anything-cpp: writeDepthPNG: bad dims h=%d w=%d len=%d", h, w, len(depth)) |
| 506 | } |
| 507 | dmin, dmax := minMax(depth) |
| 508 | span := dmax - dmin |
| 509 | if span <= 0 || math.IsNaN(float64(span)) { |
| 510 | span = 1 |
| 511 | } |
| 512 | img := image.NewGray(image.Rect(0, 0, w, h)) |
| 513 | for y := 0; y < h; y++ { |
| 514 | for x := 0; x < w; x++ { |
| 515 | v := depth[y*w+x] |
| 516 | n := (v - dmin) / span // 0..1 |
| 517 | if math.IsNaN(float64(n)) { |
| 518 | n = 0 |
| 519 | } |
| 520 | if n < 0 { |
| 521 | n = 0 |
| 522 | } else if n > 1 { |
| 523 | n = 1 |
| 524 | } |
| 525 | img.Pix[y*img.Stride+x] = uint8(n * 255) |
| 526 | } |
| 527 | } |
| 528 | // dst is the gRPC-provided output path chosen by the LocalAI core (the |
| 529 | // intended write destination for the rendered depth map), not |
| 530 | // attacker-controlled input, so the variable path is expected here. |
| 531 | f, err := os.Create(dst) // #nosec G304 |
| 532 | if err != nil { |
| 533 | return err |
| 534 | } |
| 535 | defer func() { _ = f.Close() }() |
| 536 | return png.Encode(f, img) |
| 537 | } |
| 538 | |
| 539 | func minMax(v []float32) (mn, mx float32) { |
| 540 | if len(v) == 0 { |
no test coverage detected