code: def handle_sub_rectangles(self, images, sub_rectangles):
          
          image_info = [im.info for im in images]
          if isinstance(sub_rectangles, (tuple, list)):
              # xy given directly
  
              # Check xy
              xy = sub_rectangles
              if xy is None:
                  xy = (0, 0)
              if hasattr(xy, '__len__'):
                  if len(xy) == len(images):
                      xy = [xxyy for xxyy in xy]
                  else:
                      raise ValueError("len(xy) doesn't match amount of images.")
              else:
                  xy = [xy for im in images]
              xy[0] = (0, 0)
  
          else:
              # Calculate xy using some basic image processing
  
              # Check Numpy
              if np is None:
                  raise RuntimeError("Need Numpy to use auto-sub_rectangles.")
  
              # First make numpy arrays if required
              for i in range(len(images)):
                  im = images[i]
                  if isinstance(im, Image.Image):
                      tmp = im.convert()  # Make without palette
                      a = np.asarray(tmp)
                      if len(a.shape) == 0:
                          raise MemoryError("Too little memory to convert PIL image to array")
                      images[i] = a
  
              # Determine the sub rectangles
              images, xy = self.get_sub_rectangles(images)
  
          # Done
          return images, xy, image_info
docs: handle_sub_rectangles(images)
  
          Handle the sub-rectangle stuff. If the rectangles are given by the
          user, the values are checked. Otherwise the subrectangles are
          calculated automatically.