code: def _open(self):
      if self.fp.read(8) != _MAGIC:
          raise SyntaxError("not a PNG file")
  
      #
      # Parse headers up to the first IDAT chunk
  
      self.png = PngStream(self.fp)
  
      while True:
          #
          # get next chunk
  
          cid, pos, length = self.png.read()
  
          try:
              s = self.png.call(cid, pos, length)
          except EOFError:
              break
          except AttributeError:
              logger.debug("%r %s %s (unknown)", cid, pos, length)
              s = ImageFile._safe_read(self.fp, length)
  
          self.png.crc(cid, s)
  
      #
      # Copy relevant attributes from the PngStream.  An alternative
      # would be to let the PngStream class modify these attributes
      # directly, but that introduces circular references which are
      # difficult to break if things go wrong in the decoder...
      # (believe me, I've tried ;-)
  
      self.mode = self.png.im_mode
      self._size = self.png.im_size
      self.info = self.png.im_info
      self._text = None
      self.tile = self.png.im_tile
      self.custom_mimetype = self.png.im_custom_mimetype
  
      if self.png.im_palette:
          rawmode, data = self.png.im_palette
          self.palette = ImagePalette.raw(rawmode, data)
  
      self.__prepare_idat = length
  
imports: import logging
  import re
  import struct
  import zlib
  from .None import Image, ImageFile, ImagePalette
  from ._binary import i8, i16be, i32be, o16be, o32be
  from ._util import py3
label_desc: Use image node_id 1 for calling the PngImageFile obj's underlying member method code with example usage: obj._open() without return types