calculate static method

({int height, int width}) calculate({
  1. required int srcWidth,
  2. required int srcHeight,
  3. int? maxWidth,
  4. int? maxHeight,
  5. int? targetWidth,
  6. int? targetHeight,
  7. double? scale,
  8. bool preserveAspectRatio = true,
  9. bool allowStretch = false,
  10. int modulus = 2,
})

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);
}