"""HDR 画像出力モジュール．

レンダリング結果の HDR float 配列を PNG または luminance.npy として保存する．
"""

from __future__ import annotations

from pathlib import Path

import numpy
from PIL import Image

from sm_tias_lightsim.uniformity import REC709_COEFF_B, REC709_COEFF_G, REC709_COEFF_R


def save_luminance(image: numpy.ndarray, path: Path) -> None:
    """HDR 画像を Rec.709 輝度に変換して .npy として保存する．

    uniformity.py の Rec.709 係数定数を再利用する（DRY）．
    HDR 値域（0〜∞）をそのまま保持するため clip は行わない．

    Args:
        image: HDR 画像 (H, W, 3) float．
        path: 出力 .npy ファイルパス．
    """
    luminance = (
        REC709_COEFF_R * image[..., 0]
        + REC709_COEFF_G * image[..., 1]
        + REC709_COEFF_B * image[..., 2]
    )
    numpy.save(path, luminance.astype(numpy.float64))


def save_png(image: numpy.ndarray, path: Path, gain: float = 1.0) -> None:
    """HDR 画像をトーンマップして 8-bit PNG として保存する．

    線形スケール（gain 倍）して [0, 1] にクリップ後，uint8 [0, 255] に変換する．
    物理的に妥当なトーンマッピングではなく，目視確認・デバッグ用途の簡易実装．

    Args:
        image: HDR 画像 (H, W, 3) float．
        path: 出力 PNG パス．
        gain: 露出補正係数．既定 1.0．
    """
    # gain を掛けて [0, 1] にクリップし uint8 化
    tonemapped = numpy.clip(image * gain, 0.0, 1.0)
    uint8_image = (tonemapped * 255.0).astype(numpy.uint8)
    pil_image = Image.fromarray(uint8_image, mode="RGB")
    pil_image.save(str(path))
