code: def autocontrast(
      image, cutoff=0, ignore=None, mask=None, preserve_tone=False
  ):
      """
      Maximize (normalize) image contrast. This function calculates a
      histogram of the input image (or mask region), removes ``cutoff`` percent of the
      lightest and darkest pixels from the histogram, and remaps the image
      so that the darkest pixel becomes black (0), and the lightest
      becomes white (255).
  
      :param image: The image to process.
      :param cutoff: The percent to cut off from the histogram on the low and
                     high ends. Either a tuple of (low, high), or a single
                     number for both.
      :param ignore: The background pixel value (use None for no background).
      :param mask: Histogram used in contrast operation is computed using pixels
                   within the mask. If no mask is given the entire image is used
                   for histogram computation.
      :param preserve_tone: Preserve image tone in Photoshop-like style autocontrast.
  
                            .. versionadded:: 8.2.0
  
      :return: An image.
      """
      if preserve_tone:
          histogram = image.convert("L").histogram(mask)
      else:
          histogram = image.histogram(mask)
  
      lut = []
      for layer in range(0, len(histogram), 256):
          h = histogram[layer : layer + 256]
          if ignore is not None:
              # get rid of outliers
              try:
                  h[ignore] = 0
              except TypeError:
                  # assume sequence
                  for ix in ignore:
                      h[ix] = 0
          if cutoff:
              # cut off pixels from both ends of the histogram
              if not isinstance(cutoff, tuple):
                  cutoff = (cutoff, cutoff)
              # get number of pixels
              n = 0
              for ix in range(256):
                  n = n + h[ix]
              # remove cutoff% pixels from the low end
              cut = n * cutoff[0] // 100
              for lo in range(256):
                  if cut > h[lo]:
                      cut = cut - h[lo]
                      h[lo] = 0
                  else:
                      h[lo] -= cut
                      cut = 0
                  if cut <= 0:
                      break
              # remove cutoff% samples from the high end
              cut = n * cutoff[1] // 100
              for hi in range(255, -1, -1):
                  if cut > h[hi]:
                      cut = cut - h[hi]
                      h[hi] = 0
                  else:
                      h[hi] -= cut
                      cut = 0
                  if cut <= 0:
                      break
          # find lowest/highest samples after preprocessing
          for lo in range(256):
              if h[lo]:
                  break
          for hi in range(255, -1, -1):
              if h[hi]:
                  break
          if hi <= lo:
              # don't bother
              lut.extend(list(range(256)))
          else:
              scale = 255.0 / (hi - lo)
              offset = -lo * scale
              for ix in range(256):
                  ix = int(ix * scale + offset)
                  if ix < 0:
                      ix = 0
                  elif ix > 255:
                      ix = 255
                  lut.append(ix)
      return _lut(image, lut)
  
imports: from __future__ import annotations
  import functools
  import operator
  import re
  from .None import ExifTags, Image, ImagePalette
label_desc: Use image node_id 4 for calling a global function with example usage: autocontrast(image, cutoff, ignore, mask, preserve_tone) and returns: _lut