// Package media holds shared media size/resolution policy (no I/O). // Server enforces image ≤150 KiB (auto-compress on server write paths); // client App should still compress before direct-to-object uploads. package media // Default limits: images ≤150 KiB server-wide; resolution caps align with App. const ( DefaultImageMaxEdge = 1080 DefaultVideoMaxEdge = 720 DefaultAvatarMaxEdge = 200 DefaultImageMaxBytes = 150 * 1024 // 150 KiB — all server-stored images DefaultVideoMaxBytes = 100 << 20 // 100 MiB DefaultAvatarMaxBytes = 150 * 1024 // 150 KiB (same hard cap as images) DefaultJPEGQuality = 85 DefaultVideoCRF = 23 // MinImageEdge is the floor when iteratively scaling to meet ImageMaxBytes. MinImageEdge = 240 ) // Limits is the resolution/size policy shared by user checks and compressors. type Limits struct { ImageMaxEdge int VideoMaxEdge int AvatarMaxEdge int ImageMaxBytes int64 VideoMaxBytes int64 AvatarMaxBytes int64 } // DefaultLimits returns server-aligned defaults (image/avatar ≤150 KiB). func DefaultLimits() Limits { return Limits{ ImageMaxEdge: DefaultImageMaxEdge, VideoMaxEdge: DefaultVideoMaxEdge, AvatarMaxEdge: DefaultAvatarMaxEdge, ImageMaxBytes: DefaultImageMaxBytes, VideoMaxBytes: DefaultVideoMaxBytes, AvatarMaxBytes: DefaultAvatarMaxBytes, } } // Normalize fills zero fields with defaults. func (l Limits) Normalize() Limits { d := DefaultLimits() if l.ImageMaxEdge <= 0 { l.ImageMaxEdge = d.ImageMaxEdge } if l.VideoMaxEdge <= 0 { l.VideoMaxEdge = d.VideoMaxEdge } if l.AvatarMaxEdge <= 0 { l.AvatarMaxEdge = d.AvatarMaxEdge } if l.ImageMaxBytes <= 0 { l.ImageMaxBytes = d.ImageMaxBytes } if l.VideoMaxBytes <= 0 { l.VideoMaxBytes = d.VideoMaxBytes } if l.AvatarMaxBytes <= 0 { l.AvatarMaxBytes = d.AvatarMaxBytes } return l } // LongestEdge returns max(w, h). func LongestEdge(w, h int) int { if w > h { return w } return h } // NeedsResize reports whether the frame exceeds maxEdge (already-smaller is kept as-is). func NeedsResize(w, h, maxEdge int) bool { if maxEdge <= 0 || w <= 0 || h <= 0 { return false } return LongestEdge(w, h) > maxEdge }