Address review decision: previews (4037) and other decodes (4040) had two
busy errors for one condition. ErrDecodeBusy now carries 4037 and the
preview-only error is gone.
Attachment previews now decode through imageutils.Decode, which holds an
image's pixels against one process-wide budget until the caller is done
with the decoded image. Other decode sites move onto it next.
Decoding now validates image dimensions before allocating pixels
(imaging.Fit replaces unbounded Resize so neither side can blow up),
backgrounds decode once and reuse the image for the blur hash, and
DownloadImage is bounded at the configured max file size. Small sources
now keep their native size (Fit does not upscale); the frontend scales
via CSS.