docs: def read(self, lenient=False):
          """
          Read the PNG file and decode it.
  
          Returns (`width`, `height`, `pixels`, `metadata`).
  
          May use excessive memory.
  
          `pixels` are returned in boxed row flat pixel format.
  
          If the optional `lenient` argument evaluates to True,
          checksum failures will raise warnings rather than exceptions.
          """
          self.preamble(lenient=lenient)
          raw = self.idatdecomp(lenient)
  
          if self.interlace:
              raw = bytearray(itertools.chain(*raw))
              arraycode = 'BH'[self.bitdepth > 8]
              # Like :meth:`group` but producing an array.array object for
              # each row.
              pixels = map(lambda *row: array(arraycode, row),
                         *[iter(self.deinterlace(raw))]*self.width*self.planes)
          else:
              pixels = self.iterboxed(self.iterstraight(raw))
          meta = dict()
          for attr in 'greyscale alpha planes bitdepth interlace'.split():
              meta[attr] = getattr(self, attr)
          meta['size'] = (self.width, self.height)
          for attr in ('gamma', 'transparent', 'background', 'last_mod_time',
                       'icc_profile', 'resolution', 'text',
                       'rendering_intent', 'white_point', 'rgb_points'):
              a = getattr(self, attr, None)
              if a is not None:
                  meta[attr] = a
          if self.plte:
              meta['palette'] = self.palette()
          return self.width, self.height, pixels, meta