docs: def deinterlace(self, raw):
          """
          Read raw pixel data, undo filters, deinterlace, and flatten.
  
          Return in flat row flat pixel format.
          """
          # Values per row (of the target image)
          vpr = self.width * self.planes
  
          # Make a result array, and make it big enough.  Interleaving
          # writes to the output array randomly (well, not quite), so the
          # entire output array must be in memory.
          if self.bitdepth > 8:
              a = newHarray(vpr * self.height)
          else:
              a = newBarray(vpr * self.height)
          source_offset = 0
          filt = Filter(self.bitdepth * self.planes)
          for xstart, ystart, xstep, ystep in _adam7:
              if xstart >= self.width:
                  continue
              # The previous (reconstructed) scanline.  None at the
              # beginning of a pass to indicate that there is no previous
              # line.
              filt.prev = None
              # Pixels per row (reduced pass image)
              ppr = int(math.ceil((self.width-xstart)/float(xstep)))
              # Row size in bytes for this pass.
              row_size = int(math.ceil(self.psize * ppr))
              for y in range(ystart, self.height, ystep):
                  filter_type = raw[source_offset]
                  scanline = raw[source_offset + 1:source_offset + row_size + 1]
                  source_offset += (row_size + 1)
                  if filter_type not in (0, 1, 2, 3, 4):
                      raise FormatError('Invalid PNG Filter Type.'
                  '  See http://www.w3.org/TR/2003/REC-PNG-20031110/#9Filters .')
                  filt.undo_filter(filter_type, scanline)
                  # Convert so that there is one element per pixel value
                  flat = self.serialtoflat(scanline, ppr)
                  end_offset = (y + 1) * vpr
                  if xstep == 1:
                      # Last pass (0, 1, 1, 2))
                      assert xstart == 0
                      offset = y * vpr
                      a[offset:end_offset] = flat
                  else:
                      offset = y * vpr + xstart * self.planes
                      for i in range(self.planes):
                          a[offset + i:end_offset:self.planes * xstep] = \
                              flat[i::self.planes]
          return a