class_docstr: Abstract image class with interface for loading/saving images from disk.
  
  The class doesn't define any image properties.
  
  It has:
  
  attributes:
  
     * extra
  
  properties:
  
     * header
  
  methods:
  
     * to_filename(fname) - writes data to filename(s) derived from
       ``fname``, where the derivation may differ between formats.
     * to_file_map() - save image to files with which the image is already
       associated.
  
  classmethods:
  
     * from_filename(fname) - make instance by loading from filename
     * from_file_map(fmap) - make instance from file map
     * instance_to_filename(img, fname) - save ``img`` instance to
       filename ``fname``.
  
  It also has a ``header`` - some standard set of meta-data that is specific
  to the image format, and ``extra`` - a dictionary container for any other
  metadata.
  
  You cannot slice an image, and trying to slice an image generates an
  informative TypeError.
  
  **There are several ways of writing data**
  
  There is the usual way, which is the default::
  
      img.to_filename(fname)
  
  and that is, to take the data encapsulated by the image and cast it to
  the datatype the header expects, setting any available header scaling
  into the header to help the data match.
  
  You can load the data into an image from file with::
  
     img.from_filename(fname)
  
  The image stores its associated files in its ``file_map`` attribute.  In
  order to just save an image, for which you know there is an associated
  filename, or other storage, you can do::
  
     img.to_file_map()
  
  **Files interface**
  
  The image has an attribute ``file_map``.  This is a mapping, that has keys
  corresponding to the file types that an image needs for storage.  For
  example, the Analyze data format needs an ``image`` and a ``header``
  file type for storage:
  
     >>> import numpy as np
     >>> import nibabel as nib
     >>> data = np.arange(24, dtype='f4').reshape((2,3,4))
     >>> img = nib.AnalyzeImage(data, np.eye(4))
     >>> sorted(img.file_map)
     ['header', 'image']
  
  The values of ``file_map`` are not in fact files but objects with
  attributes ``filename``, ``fileobj`` and ``pos``.
  
  The reason for this interface, is that the contents of files has to
  contain enough information so that an existing image instance can save
  itself back to the files pointed to in ``file_map``.  When a file holder
  holds active file-like objects, then these may be affected by the
  initial file read; in this case, the file-like objects need to
  carry the position at which a write (with ``to_file_map``) should place the
  data.  The ``file_map`` contents should therefore be such, that this will
  work.
docstr: Return True if `filename` may be image matching this class
  
  Parameters
  ----------
  filename : str or os.PathLike
      Filename for an image, or an image header (metadata) file.
      If `filename` points to an image data file, and the image type has
      a separate "header" file, we work out the name of the header file,
      and read from that instead of `filename`.
  sniff : None or (bytes, filename), optional
      Bytes content read from a previous call to this method, on another
      class, with metadata filename.  This allows us to read metadata
      bytes once from the image or header, and pass this read set of
      bytes to other image classes, therefore saving a repeat read of the
      metadata.  `filename` is used to validate that metadata would be
      read from the same file, re-reading if not.  None forces this
      method to read the metadata.
  sniff_max : int, optional
      The maximum number of bytes to read from the metadata.  If the
      metadata file is long enough, we read this many bytes from the
      file, otherwise we read to the end of the file.  Longer values
      sniff more of the metadata / image file, making it more likely that
      the returned sniff will be useful for later calls to
      ``path_maybe_image`` for other image classes.
  
  Returns
  -------
  maybe_image : bool
      True if `filename` may be valid for an image of this class.
  sniff : None or (bytes, filename)
      Read bytes content from found metadata.  May be None if the file
      does not appear to have useful metadata.
docstr_tok: ["Return","True","if","`","filename","`","may","be","image","matching","this","class","Parameters","--","--","--","--","--","filename",":","str","or","os.PathLike","Filename","for","an","image",",","or","an","image","header","(","metadata",")","file",".","If","`","filename","`","points","to","an","image","data","file",",","and","the","image","type","has","a","separate","``","header","''","file",",","we","work","out","the","name","of","the","header","file",",","and","read","from","that","instead","of","`","filename","`",".","sniff",":","None","or","(","bytes",",","filename",")",",","optional","Bytes","content","read","from","a","previous","call","to","this","method",",","on","another","class",",","with","metadata","filename",".","This","allows","us","to","read","metadata","bytes","once","from","the","image","or","header",",","and","pass","this","read","set","of","bytes","to","other","image","classes",",","therefore","saving","a","repeat","read","of","the","metadata",".","`","filename","`","is","used","to","validate","that","metadata","would","be","read","from","the","same","file",",","re-reading","if","not",".","None","forces","this","method","to","read","the","metadata",".","sniff_max",":","int",",","optional","The","maximum","number","of","bytes","to","read","from","the","metadata",".","If","the","metadata","file","is","long","enough",",","we","read","this","many","bytes","from","the","file",",","otherwise","we","read","to","the","end","of","the","file",".","Longer","values","sniff","more","of","the","metadata","\/","image","file",",","making","it","more","likely","that","the","returned","sniff","will","be","useful","for","later","calls","to","``","path_maybe_image","``","for","other","image","classes",".","Returns","--","--","--","-","maybe_image",":","bool","True","if","`","filename","`","may","be","valid","for","an","image","of","this","class",".","sniff",":","None","or","(","bytes",",","filename",")","Read","bytes","content","from","found","metadata",".","May","be","None","if","the","file","does","not","appear","to","have","useful","metadata","."]
code: def path_maybe_image(
      klass,
      filename: FileSpec,
      sniff: FileSniff | None = None,
      sniff_max: int = 1024,
  ) -> tuple[bool, FileSniff | None]:
      """Return True if `filename` may be image matching this class
  
      Parameters
      ----------
      filename : str or os.PathLike
          Filename for an image, or an image header (metadata) file.
          If `filename` points to an image data file, and the image type has
          a separate "header" file, we work out the name of the header file,
          and read from that instead of `filename`.
      sniff : None or (bytes, filename), optional
          Bytes content read from a previous call to this method, on another
          class, with metadata filename.  This allows us to read metadata
          bytes once from the image or header, and pass this read set of
          bytes to other image classes, therefore saving a repeat read of the
          metadata.  `filename` is used to validate that metadata would be
          read from the same file, re-reading if not.  None forces this
          method to read the metadata.
      sniff_max : int, optional
          The maximum number of bytes to read from the metadata.  If the
          metadata file is long enough, we read this many bytes from the
          file, otherwise we read to the end of the file.  Longer values
          sniff more of the metadata / image file, making it more likely that
          the returned sniff will be useful for later calls to
          ``path_maybe_image`` for other image classes.
  
      Returns
      -------
      maybe_image : bool
          True if `filename` may be valid for an image of this class.
      sniff : None or (bytes, filename)
          Read bytes content from found metadata.  May be None if the file
          does not appear to have useful metadata.
      """
      froot, ext, trailing = splitext_addext(
          filename, klass._compressed_suffixes
      )
      if ext.lower() not in klass.valid_exts:
          return False, sniff
      if not hasattr(klass.header_class, "may_contain_header"):
          return True, sniff
  
      # Force re-sniff on too-short sniff
      if sniff is not None and len(sniff[0]) < klass._meta_sniff_len:
          sniff = None
      sniff = klass._sniff_meta_for(
          filename, max(klass._meta_sniff_len, sniff_max), sniff
      )
      if sniff is None or len(sniff[0]) < klass._meta_sniff_len:
          return False, sniff
      return klass.header_class.may_contain_header(sniff[0]), sniff
  
imports: from __future__ import annotations
  import io
  import typing
  from copy import deepcopy
  from urllib import request
  from ._compression import COMPRESSION_ERRORS
  from .fileholders import FileHolder, FileMap
  from .filename_parser import TypesFilenamesError, _stringify_path, splitext_addext, types_filenames
  from .openers import ImageOpener
label_desc: Use image node_id 15 for calling the FileBasedImage obj's underlying member method code with example usage: obj.path_maybe_image(klass, filename, sniff, sniff_max) and returns: klass,  sniff, False,  sniff, True,  sniff, False,  sniff