///|
/// 随机点阵水印:按 `DotConfig` 的归一化网格 + PRNG 布局,在全图散布深色点。
///
/// - 落点网格使用**归一化坐标**(单元边长 = 图宽 8%),点位置按比例跟随
///   图像尺寸——因此缩放(resize)后提取仍能命中,鲁棒性矩阵实测通过。
/// - 每个单元由 `seed` 驱动的确定性 PRNG 决定是否落点(`density` 为落点
///   单元概率)及点在单元内的偏移比例(叠加 `grid_offset_x / grid_offset_y`
///   像素偏移,非零偏移在缩放场景会有轻微漂移,建议默认 0)。
/// - 点颜色固定为深色(`0x0000_00FF`),半透明时由 `opacity` 控制;
///   同一配置(尤其同一 `seed`)嵌入结果完全一致,可被 `extract_dots` 复现。
pub fn RgbaImage::embed_dots(self : RgbaImage, cfg : DotConfig) -> RgbaImage {
  let cell_ratio = 0.08 // 单元边长占图宽的比例(≈ 原 8px @100px 的观感)
  let alpha = clamp_opacity(cfg.opacity)
  let threshold = (cfg.density * 1000.0).to_int()
  let mut st = seed_to_state(cfg.seed)
  let cols = (1.0 / cell_ratio).ceil().to_int()
  let rows = cols
  for cy in 0.. Double {
  let thr = match brightness_threshold {
    Some(v) => v
    None => 128
  }
  let cell_ratio = 0.08 // 与 embed_dots 保持一致
  let mut st = seed_to_state(cfg.seed)
  let cols = (1.0 / cell_ratio).ceil().to_int()
  let rows = cols
  let threshold = (cfg.density * 1000.0).to_int()
  let mut hits = 0
  let mut total = 0
  for cy in 0..> 24) & 0xFF
              let g2 = (p >> 16) & 0xFF
              let b2 = (p >> 8) & 0xFF
              if (r2 + g2 + b2) / 3 < thr {
                any = true
              }
            }
          }
        }
        // 与 embed 对齐:embed 对越界格不画点,提取时也跳过(避免分母虚增)
        if checked {
          total += 1
          if any {
            hits += 1
          }
        }
      }
    }
  }
  if total == 0 {
    0.0
  } else {
    (hits * 1000 / total).to_double() / 1000.0
  }
}