calculate static method
Compute output dimensions from source + constraints.
srcWidth/srcHeight are rotation-corrected (like job->width/height after HandBrake's geometry fix).
Returns even (modulo=2) dimensions, never 0.
Implementation
static ({int width, int height}) calculate({
required int srcWidth,
required int srcHeight,
int? maxWidth,
int? maxHeight,
int? targetWidth,
int? targetHeight,
double? scale,
bool preserveAspectRatio = true,
bool allowStretch = false,
int modulus = 2,
}) {
assert(srcWidth > 0 && srcHeight > 0);
final aspect = srcWidth / srcHeight;
int w = srcWidth;
int h = srcHeight;
// Priority: explicit target > scale > max constraints (same as HandBrake's PictureForce* vs max PictureWidth/Height)
if (targetWidth != null || targetHeight != null) {
if (!preserveAspectRatio || allowStretch) {
w = targetWidth ?? ((targetHeight! * aspect).round());
h = targetHeight ?? ((targetWidth! / aspect).round());
} else {
// preserve aspect: fit inside targetW×targetH
if (targetWidth != null && targetHeight != null) {
final targetAspect = targetWidth / targetHeight;
if (aspect > targetAspect) {
w = targetWidth;
h = (w / aspect).round();
} else {
h = targetHeight;
w = (h * aspect).round();
}
} else if (targetWidth != null) {
w = targetWidth;
h = (w / aspect).round();
} else {
h = targetHeight!;
w = (h * aspect).round();
}
}
} else if (scale != null) {
w = (srcWidth * scale).round();
h = (srcHeight * scale).round();
} else {
// maxWidth/maxHeight as ceiling (HandBrake's PictureWidth/Height with KeepRatio)
if (maxWidth != null && w > maxWidth) {
w = maxWidth;
h = (w / aspect).round();
}
if (maxHeight != null && h > maxHeight) {
h = maxHeight;
w = (h * aspect).round();
}
}
w = _alignToModulus(w, modulus);
h = _alignToModulus(h, modulus);
w = w.clamp(modulus, 7680); // cap at 8K — avoids OOM on exotic inputs
h = h.clamp(modulus, 7680);
// never upscale unless explicitly asked via targetWidth/targetHeight/scale
final isExplicitUpscale =
targetWidth != null || targetHeight != null || scale != null;
if (!isExplicitUpscale) {
if (w > srcWidth || h > srcHeight) {
w = _alignToModulus(srcWidth, modulus);
h = _alignToModulus(srcHeight, modulus);
}
}
return (width: w, height: h);
}