'Saves this image under the given filename.  If no format is
specified, the format to use is determined from the filename
extension, if possible.
Keyword options can be used to provide additional instructions
to the writer. If a writer doesn\'t recognise an option, it is
silently ignored. The available options are described in the
:doc:`image format documentation
<../handbook/image-file-formats>` for each writer.
You can use a file object instead of a filename. In this case,
you must always specify the format. The file object must
implement the ``seek``, ``tell``, and ``write``
methods, and be opened in binary mode.
:param fp: A filename (string), pathlib.Path object or file object.
:param format: Optional format override.  If omitted, the
format to use is determined from the filename extension.
If a file object was used instead of a filename, this
parameter should always be used.
:param options: Extra parameters to the image writer.
:returns: None
:exception KeyError: If the output format could not be determined
from the file name.  Use the format option to solve this.
:exception IOError: If the file could not be written.  The file
may have been created, and may contain partial data.'

def save(self, fp, format=None, **params):

    filename = ''
    open_fp = False
    if isPath(fp):
        filename = fp
        open_fp = True
    elif (sys.version_info >= (3, 4)):
        from pathlib import Path
        if isinstance(fp, Path):
            filename = str(fp)
            open_fp = True
    if ((not filename) and hasattr(fp, 'name') and isPath(fp.name)):
        filename = fp.name
    self.load()
    save_all = False
    if ('save_all' in params):
        save_all = params.pop('save_all')
    self.encoderinfo = params
    self.encoderconfig = ()
    preinit()
    ext = os.path.splitext(filename)[1].lower()
    if (not format):
        if (ext not in EXTENSION):
            init()
        try:
            format = EXTENSION[ext]
        except KeyError:
            raise ValueError('unknown    file    extension:    {}'.format(ext))
    if (format.upper() not in SAVE):
        init()
    if save_all:
        save_handler = SAVE_ALL[format.upper()]
    else:
        save_handler = SAVE[format.upper()]
    if open_fp:
        fp = builtins.open(filename, 'w+b')
    try:
        save_handler(self, fp, filename)
    finally:
        if open_fp:
            fp.close()
