addSample :: Film -> (Double, Double) -> P.Pixel8 -> Film
addSample (Film (fw, fh) f p) (x, y) v = Film (fw, fh) f (p // updates)
  where (ex, ey) = filterExtent f
        (minX, minY) = (max 0      (ceiling (x - 0.5 - ex)), max 0      (ceiling (y - 0.5 - ey)))
        (maxX, maxY) = (min (fw-1) (floor   (x - 0.5 + ex)), min (fh-1) (floor   (y - 0.5 + ey)))
        updates      = [((ux, uy), update ux uy) | ux <- [minX..maxX], uy <- [minY..maxY]]
        update ux uy = let (Pixel s ws) = p ! (ux, uy)
                           pv           = filterWeight f (fromIntegral ux - x - 0.5, fromIntegral uy - y - 0.5)
                       in Pixel (s + fromIntegral v*pv) (ws + pv)
addSample :: Film -> (Double, Double) -> P.Pixel8 -> Film
addSample (Film (fw, fh) f p) (x, y) v = Film (fw, fh) f (p // updates)
  where (ex, ey) = filterExtent f
        (minX, minY) = (max 0      (ceiling (x - 0.5 - ex)), max 0      (ceiling (y - 0.5 - ey)))
        (maxX, maxY) = (min (fw-1) (floor   (x - 0.5 + ex)), min (fh-1) (floor   (y - 0.5 + ey)))
        updates      = [((ux, uy), update ux uy) | ux <- [minX..maxX], uy <- [minY..maxY]]
        update ux uy = let (Pixel s ws) = p ! (ux, uy)
                           pv           = filterWeight f (fromIntegral ux - x - 0.5, fromIntegral uy - y - 0.5)
                       in Pixel (s + fromIntegral v*pv) (ws + pv)
addSample (Film (fw, fh) f p) (x, y) v = Film (fw, fh) f (p // updates)
  where (ex, ey) = filterExtent f
        (minX, minY) = (max 0      (ceiling (x - 0.5 - ex)), max 0      (ceiling (y - 0.5 - ey)))
        (maxX, maxY) = (min (fw-1) (floor   (x - 0.5 + ex)), min (fh-1) (floor   (y - 0.5 + ey)))
        updates      = [((ux, uy), update ux uy) | ux <- [minX..maxX], uy <- [minY..maxY]]
        update ux uy = let (Pixel s ws) = p ! (ux, uy)
                           pv           = filterWeight f (fromIntegral ux - x - 0.5, fromIntegral uy - y - 0.5)
                       in Pixel (s + fromIntegral v*pv) (ws + pv)