docs: def size_to_apply(self):
          """Calculate size of image scaled using size parameters.
  
          Assumes current image width and height are available in self.width and
          self.height, and self.request is IIIFRequest object.
  
          Formats are: w, ,h w,h pct:p !w,h full max
  
          Returns (None,None) if no scaling is required.
  
          If max is requested and neither max_area or max_width are
          specified then this is the same as full. Otherwise the limits
          are used to determine the size.
          """
          if (self.request.size_full or self.request.size_pct == 100.0):
              # full size
              return(None, None)
          # Not trivially full size, look at possibilities in turn
          w = self.width
          h = self.height
          if (self.request.size_max):
              # use size limits if present, else full
              if (self.max_area and self.max_area < (w * h)):
                  scale = (float(self.max_area) / float(w * h)) ** 0.5
                  w = int(w * scale + 0.5)
                  h = int(h * scale + 0.5)
              if (self.max_width):
                  max_height = self.max_height if self.max_height is not None else self.max_width
                  if (self.max_width < w):
                      # calculate wrt original width, height rather than
                      # w, h to avoid compounding rounding issues
                      scale = float(self.max_width) / float(self.width)
                      w = int(self.width * scale + 0.5)
                      h = int(self.height * scale + 0.5)
                  if (max_height < h):
                      scale = float(max_height) / float(self.height)
                      w = int(self.width * scale + 0.5)
                      h = int(self.height * scale + 0.5)
          elif (self.request.size_pct is not None):
              w = int(self.width * self.request.size_pct / 100.0 + 0.5)
              h = int(self.height * self.request.size_pct / 100.0 + 0.5)
          elif (self.request.size_bang):
              # Have "!w,h" form
              (mw, mh) = self.request.size_wh
              # Pick smaller fraction and then work from that...
              frac = min((float(mw) / float(self.width)),
                         (float(mh) / float(self.height)))
              w = int(self.width * frac + 0.5)
              h = int(self.height * frac + 0.5)
          else:
              # Must now be "w,h", "w," or ",h". If both are specified then this will the size,
              # otherwise find other to keep aspect ratio
              (w, h) = self.request.size_wh
              if (w is None):
                  w = int(self.width * h / self.height + 0.5)
              elif (h is None):
                  h = int(self.height * w / self.width + 0.5)
          # Now have w,h, sanity check and return
          if (w == 0 or h == 0):
              raise IIIFZeroSizeError(
                  code=400, parameter='size',
                  text="Size parameter would result in zero size result image (%d,%d)." % (w, h))
          # Below would be test for scaling up image size, this is allowed by spec
          # if ( w>self.width or h>self.height ):
          #      raise IIIFError(code=400,parameter='size',
          # text="Size requests scaling up image to larger than orginal.")
          if (w == self.width and h == self.height):
              return(None, None)
          return(w, h)