src/main/java/de/digitalcollections/iiif/model/image/SizeRequest.java
public Dimension resolve(Dimension nativeSize, List<Dimension> availableSizes, ImageApiProfile profile) throws ResolvingException {
    double aspect = (double) nativeSize.width / (double) nativeSize.height;
    // "max"
    if (max) {
      // By default, identical to the largest available size or the native size if no sizes were specified
      Dimension dim = availableSizes.stream()
          // Avoid upscaling when dealing with region requests
          .filter(s -> s.width <= nativeSize.width && s.height <= nativeSize.height)
          // Select the largest available size
          .max(Comparator.comparing(Dimension::getWidth).thenComparing(Dimension::getHeight))
          // Otherwise, fall back to the native size
          .orElse(new Dimension(nativeSize.width, nativeSize.height));
      if (profile != null && profile.maxWidth != null) {
        if (dim.width > profile.maxWidth) {
          // If maximum width is set, width cannot exceed it
          dim.width = profile.maxWidth;
          dim.height = (int) (profile.maxWidth / aspect);
        }
        int maxHeight = profile.maxHeight != null ? profile.maxHeight : profile.maxWidth;
        if (dim.height > maxHeight) {
          // Adjust height if it exceeds maximum height
          dim.height = maxHeight;
          dim.width = (int) (aspect * dim.height);
        }
      }
      if (profile != null && profile.maxArea != null) {
        // Fit width and height into the maximum available area, preserving the aspect ratio
        long currentArea = (long) dim.width * (long) dim.height;
        if (currentArea > profile.maxArea) {
          dim.width = (int) Math.sqrt(aspect * (double) profile.maxArea);
          dim.height = (int) (dim.width / aspect);
          if (dim.width <= 0 || dim.height <= 0) {
            throw new ResolvingException(String.format(
                "Cannot fit image with dimensions %dx%d into maximum area of %d pixels.",
                nativeSize.width, nativeSize.height, profile.maxArea));
          }
        }
      }
      return dim;
    }
    Dimension out;
    if (percentage != null || bestFit) {  // "pct:"
      double ratio;
      if (percentage != null) {
        ratio = percentage.doubleValue() / 100.0;
      } else {
        ratio = Math.min(width / nativeSize.getWidth(), height / nativeSize.getHeight());
      }
      out = new Dimension((int) (ratio * nativeSize.width), (int) (ratio * nativeSize.height));
    } else if (width == null && height == null) {  // "full"
      out = nativeSize;
    } else {
      out = new Dimension();
      if (width != null) {
        out.width = width;
      }
      if (height != null) {
        out.height = height;
      }
      if (width == null) {  // ",h"
        out.width = (int) (out.height * aspect);
      }
      if (height == null) { // "w,"
        out.height = (int) (out.width / aspect);
      }
    }
    Integer maxHeight = profile.maxHeight != null ? profile.maxHeight : profile.maxWidth;
    if (profile.maxWidth != null && out.width > profile.maxWidth) {
      throw new ResolvingException(String.format(
          "Requested width (%d) exceeds maximum width (%d) as specified in the profile.", out.width, profile.maxWidth));
    } else if (maxHeight != null && out.height > maxHeight) {
      throw new ResolvingException(String.format(
          "Requested height (%d) exceeds maximum height (%d) as specified in the profile.", out.height, maxHeight));
    } else if (profile.maxArea != null && out.height * out.width > profile.maxArea) {
      throw new ResolvingException(String.format(
          "Requested area (%d*%d = %d) exceeds maximum area (%d) as specified in the profile",
          out.width, out.height, out.width * out.height, profile.maxArea));
    } else if ((profile.features == null || !profile.features.contains(ImageApiProfile.Feature.SIZE_ABOVE_FULL))
               && (out.width > nativeSize.width || out.height > nativeSize.height)) {
      throw new ResolvingException(String.format(
          "Requested dimensions (%dx%d) exceed native dimensions (%dx%d), profile states that upscaling is not supported.",
          out.width, out.height, nativeSize.width, nativeSize.height));
    }
    return out;
  }
public Dimension resolve(Dimension nativeSize, List<Dimension> availableSizes, ImageApiProfile profile) throws ResolvingException {
    double aspect = (double) nativeSize.width / (double) nativeSize.height;
    // "max"
    if (max) {
      // By default, identical to the largest available size or the native size if no sizes were specified
      Dimension dim = availableSizes.stream()
          // Avoid upscaling when dealing with region requests
          .filter(s -> s.width <= nativeSize.width && s.height <= nativeSize.height)
          // Select the largest available size
          .max(Comparator.comparing(Dimension::getWidth).thenComparing(Dimension::getHeight))
          // Otherwise, fall back to the native size
          .orElse(new Dimension(nativeSize.width, nativeSize.height));
      if (profile != null && profile.maxWidth != null) {
        if (dim.width > profile.maxWidth) {
          // If maximum width is set, width cannot exceed it
          dim.width = profile.maxWidth;
          dim.height = (int) (profile.maxWidth / aspect);
        }
        int maxHeight = profile.maxHeight != null ? profile.maxHeight : profile.maxWidth;
        if (dim.height > maxHeight) {
          // Adjust height if it exceeds maximum height
          dim.height = maxHeight;
          dim.width = (int) (aspect * dim.height);
        }
      }
      if (profile != null && profile.maxArea != null) {
        // Fit width and height into the maximum available area, preserving the aspect ratio
        long currentArea = (long) dim.width * (long) dim.height;
        if (currentArea > profile.maxArea) {
          dim.width = (int) Math.sqrt(aspect * (double) profile.maxArea);
          dim.height = (int) (dim.width / aspect);
          if (dim.width <= 0 || dim.height <= 0) {
            throw new ResolvingException(String.format(
                "Cannot fit image with dimensions %dx%d into maximum area of %d pixels.",
                nativeSize.width, nativeSize.height, profile.maxArea));
          }
        }
      }
      return dim;
    }
    Dimension out;
    if (percentage != null || bestFit) {  // "pct:"
      double ratio;
      if (percentage != null) {
        ratio = percentage.doubleValue() / 100.0;
      } else {
        ratio = Math.min(width / nativeSize.getWidth(), height / nativeSize.getHeight());
      }
      out = new Dimension((int) (ratio * nativeSize.width), (int) (ratio * nativeSize.height));
    } else if (width == null && height == null) {  // "full"
      out = nativeSize;
    } else {
      out = new Dimension();
      if (width != null) {
        out.width = width;
      }
      if (height != null) {
        out.height = height;
      }
      if (width == null) {  // ",h"
        out.width = (int) (out.height * aspect);
      }
      if (height == null) { // "w,"
        out.height = (int) (out.width / aspect);
      }
    }
    Integer maxHeight = profile.maxHeight != null ? profile.maxHeight : profile.maxWidth;
    if (profile.maxWidth != null && out.width > profile.maxWidth) {
      throw new ResolvingException(String.format(
          "Requested width (%d) exceeds maximum width (%d) as specified in the profile.", out.width, profile.maxWidth));
    } else if (maxHeight != null && out.height > maxHeight) {
      throw new ResolvingException(String.format(
          "Requested height (%d) exceeds maximum height (%d) as specified in the profile.", out.height, maxHeight));
    } else if (profile.maxArea != null && out.height * out.width > profile.maxArea) {
      throw new ResolvingException(String.format(
          "Requested area (%d*%d = %d) exceeds maximum area (%d) as specified in the profile",
          out.width, out.height, out.width * out.height, profile.maxArea));
    } else if ((profile.features == null || !profile.features.contains(ImageApiProfile.Feature.SIZE_ABOVE_FULL))
               && (out.width > nativeSize.width || out.height > nativeSize.height)) {
      throw new ResolvingException(String.format(
          "Requested dimensions (%dx%d) exceed native dimensions (%dx%d), profile states that upscaling is not supported.",
          out.width, out.height, nativeSize.width, nativeSize.height));
    }
    return out;
  }
Resolve the request to dimensions that can be used for scaling, based on the native size of the image region and the available profile.

@param nativeSize native size of the image region
@param availableSizes available sizes
@param profile image api profile
@return resolved dimension
@throws de.digitalcollections.iiif.model.image.ResolvingException if params can not be resolved to Dimension