docs: def watermark(img, mark, position=(0, 0), opacity=1, scale=1.0, tile=False,
                greyscale=False, rotation=0, return_name=False, **kwargs):
      """Adds a watermark to an image"""
  
      if opacity < 1:
          mark = reduce_opacity(mark, opacity)
  
      if not isinstance(scale, tuple):
          scale = determine_scale(scale, img, mark)
  
      mark = mark.resize(scale, resample=Image.ANTIALIAS)
  
      if greyscale and mark.mode != 'LA':
          mark = mark.convert('LA')
  
      rotation = determine_rotation(rotation, mark)
      if rotation != 0:
          # give some leeway for rotation overlapping
          new_w = int(mark.size[0] * 1.5)
          new_h = int(mark.size[1] * 1.5)
  
          new_mark = Image.new('RGBA', (new_w, new_h), (0,0,0,0))
  
          # center the watermark in the newly resized image
          new_l = int((new_w - mark.size[0]) / 2)
          new_t = int((new_h - mark.size[1]) / 2)
          new_mark.paste(mark, (new_l, new_t))
  
          mark = new_mark.rotate(rotation)
  
      position = determine_position(position, img, mark)
  
      if img.mode != 'RGBA':
          img = img.convert('RGBA')
  
      # make sure we have a tuple for a position now
      assert isinstance(position, tuple), 'Invalid position "%s"!' % position
  
      # create a transparent layer the size of the image and draw the
      # watermark in that layer.
      layer = Image.new('RGBA', img.size, (0,0,0,0))
      if tile:
          first_y = int(position[1] % mark.size[1] - mark.size[1])
          first_x = int(position[0] % mark.size[0] - mark.size[0])
  
          for y in range(first_y, img.size[1], mark.size[1]):
              for x in range(first_x, img.size[0], mark.size[0]):
                  layer.paste(mark, (x, y))
      else:
          layer.paste(mark, position)
  
      # composite the watermark with the layer
      return Image.composite(layer, img, layer)