{
    "file_diffs": [
        {
            "old_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# base class for image file handlers\n#\n# history:\n# 1995-09-09 fl   Created\n# 1996-03-11 fl   Fixed load mechanism.\n# 1996-04-15 fl   Added pcx/xbm decoders.\n# 1996-04-30 fl   Added encoders.\n# 1996-12-14 fl   Added load helpers\n# 1997-01-11 fl   Use encode_to_file where possible\n# 1997-08-27 fl   Flush output in _save\n# 1998-03-05 fl   Use memory mapping for some modes\n# 1999-02-04 fl   Use memory mapping also for \"I;16\" and \"I;16B\"\n# 1999-05-31 fl   Added image parser\n# 2000-10-12 fl   Set readonly flag on memory-mapped images\n# 2002-03-20 fl   Use better messages for common decoder errors\n# 2003-04-21 fl   Fall back on mmap/map_buffer if map is not available\n# 2003-10-30 fl   Added StubImageFile class\n# 2004-02-25 fl   Made incremental parser more robust\n#\n# Copyright (c) 1997-2004 by Secret Labs AB\n# Copyright (c) 1995-2004 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nfrom PIL import Image\nfrom PIL._util import isPath\nimport traceback, os, sys\nimport io\n\nMAXBLOCK = 65536\n\nSAFEBLOCK = 1024*1024\n\nLOAD_TRUNCATED_IMAGES = False\n\nERRORS = {\n    -1: \"image buffer overrun error\",\n    -2: \"decoding error\",\n    -3: \"unknown error\",\n    -8: \"bad configuration\",\n    -9: \"out of memory error\"\n}\n\ndef raise_ioerror(error):\n    try:\n        message = Image.core.getcodecstatus(error)\n    except AttributeError:\n        message = ERRORS.get(error)\n    if not message:\n        message = \"decoder error %d\" % error\n    raise IOError(message + \" when reading image file\")\n\n#\n# --------------------------------------------------------------------\n# Helpers\n\ndef _tilesort(t):\n    # sort on offset\n    return t[2]\n\n#\n# --------------------------------------------------------------------\n# ImageFile base class\n\nclass ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass\n\n    # may be defined for contained formats\n    # def load_seek(self, pos):\n    #     pass\n\n    # may be defined for blocked formats (e.g. PNG)\n    # def load_read(self, bytes):\n    #     pass\n\n\nclass StubImageFile(ImageFile):\n    \"\"\"\n    Base class for stub image loaders.\n\n    A stub loader is an image loader that can identify files of a\n    certain format, but relies on external code to load the file.\n    \"\"\"\n\n    def _open(self):\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _open\"\n            )\n\n    def load(self):\n        loader = self._load()\n        if loader is None:\n            raise IOError(\"cannot find loader for this %s file\" % self.format)\n        image = loader.load(self)\n        assert image is not None\n        # become the other object (!)\n        self.__class__ = image.__class__\n        self.__dict__ = image.__dict__\n\n    def _load(self):\n        \"(Hook) Find actual image loader.\"\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _load\"\n            )\n\n\nclass Parser:\n    \"\"\"\n    Incremental image parser.  This class implements the standard\n    feed/close consumer interface.\n\n    In Python 2.x, this is an old-style class.\n    \"\"\"\n    incremental = None\n    image = None\n    data = None\n    decoder = None\n    finished = 0\n\n    def reset(self):\n        \"\"\"\n        (Consumer) Reset the parser.  Note that you can only call this\n        method immediately after you've created a parser; parser\n        instances cannot be reused.\n        \"\"\"\n        assert self.data is None, \"cannot reuse parsers\"\n\n    def feed(self, data):\n        \"\"\"\n        (Consumer) Feed data to the parser.\n\n        :param data: A string buffer.\n        :exception IOError: If the parser failed to parse the image file.\n        \"\"\"\n        # collect data\n\n        if self.finished:\n            return\n\n        if self.data is None:\n            self.data = data\n        else:\n            self.data = self.data + data\n\n        # parse what we have\n        if self.decoder:\n\n            if self.offset > 0:\n                # skip header\n                skip = min(len(self.data), self.offset)\n                self.data = self.data[skip:]\n                self.offset = self.offset - skip\n                if self.offset > 0 or not self.data:\n                    return\n\n            n, e = self.decoder.decode(self.data)\n\n            if n < 0:\n                # end of stream\n                self.data = None\n                self.finished = 1\n                if e < 0:\n                    # decoding error\n                    self.image = None\n                    raise_ioerror(e)\n                else:\n                    # end of image\n                    return\n            self.data = self.data[n:]\n\n        elif self.image:\n\n            # if we end up here with no decoder, this file cannot\n            # be incrementally parsed.  wait until we've gotten all\n            # available data\n            pass\n\n        else:\n\n            # attempt to open this file\n            try:\n                try:\n                    fp = io.BytesIO(self.data)\n                    im = Image.open(fp)\n                finally:\n                    fp.close() # explicitly close the virtual file\n            except IOError:\n                # traceback.print_exc()\n                pass # not enough data\n            else:\n                flag = hasattr(im, \"load_seek\") or hasattr(im, \"load_read\")\n                if flag or len(im.tile) != 1:\n                    # custom load code, or multiple tiles\n                    self.decode = None\n                else:\n                    # initialize decoder\n                    im.load_prepare()\n                    d, e, o, a = im.tile[0]\n                    im.tile = []\n                    self.decoder = Image._getdecoder(\n                        im.mode, d, a, im.decoderconfig\n                        )\n                    self.decoder.setimage(im.im, e)\n\n                    # calculate decoder offset\n                    self.offset = o\n                    if self.offset <= len(self.data):\n                        self.data = self.data[self.offset:]\n                        self.offset = 0\n\n                self.image = im\n\n    def close(self):\n        \"\"\"\n        (Consumer) Close the stream.\n\n        :returns: An image object.\n        :exception IOError: If the parser failed to parse the image file either\n                            because it cannot be identified or cannot be\n                            decoded.\n        \"\"\"\n        # finish decoding\n        if self.decoder:\n            # get rid of what's left in the buffers\n            self.feed(b\"\")\n            self.data = self.decoder = None\n            if not self.finished:\n                raise IOError(\"image was incomplete\")\n        if not self.image:\n            raise IOError(\"cannot parse this image\")\n        if self.data:\n            # incremental parsing not possible; reopen the file\n            # not that we have all data\n            try:\n                fp = io.BytesIO(self.data)\n                self.image = Image.open(fp)\n            finally:\n                self.image.load()\n                fp.close() # explicitly close the virtual file\n        return self.image\n\n# --------------------------------------------------------------------\n\ndef _save(im, fp, tile, bufsize=0):\n    \"\"\"Helper to save image based on tile list\n\n    :param im: Image object.\n    :param fp: File object.\n    :param tile: Tile list.\n    :param bufsize: Optional buffer size\n    \"\"\"\n\n    im.load()\n    if not hasattr(im, \"encoderconfig\"):\n        im.encoderconfig = ()\n    tile.sort(key=_tilesort)\n    # FIXME: make MAXBLOCK a configuration parameter\n    # It would be great if we could have the encoder specifiy what it needs\n    # But, it would need at least the image size in most cases. RawEncode is\n    # a tricky case.\n    bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c\n    try:\n        fh = fp.fileno()\n        fp.flush()\n    except (AttributeError, io.UnsupportedOperation):\n        # compress to Python file-compatible object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            while True:\n                l, s, d = e.encode(bufsize)\n                fp.write(d)\n                if s:\n                    break\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    else:\n        # slight speedup: compress to real file object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            s = e.encode_to_file(fh, bufsize)\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    try:\n        fp.flush()\n    except: pass\n\n\ndef _safe_read(fp, size):\n    \"\"\"\n    Reads large blocks in a safe way.  Unlike fp.read(n), this function\n    doesn't trust the user.  If the requested size is larger than\n    SAFEBLOCK, the file is read block by block.\n\n    :param fp: File handle.  Must implement a <b>read</b> method.\n    :param size: Number of bytes to read.\n    :returns: A string containing up to <i>size</i> bytes of data.\n    \"\"\"\n    if size <= 0:\n        return b\"\"\n    if size <= SAFEBLOCK:\n        return fp.read(size)\n    data = []\n    while size > 0:\n        block = fp.read(min(size, SAFEBLOCK))\n        if not block:\n            break\n        data.append(block)\n        size -= len(block)\n    return b\"\".join(data)\n",
            "new_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# base class for image file handlers\n#\n# history:\n# 1995-09-09 fl   Created\n# 1996-03-11 fl   Fixed load mechanism.\n# 1996-04-15 fl   Added pcx/xbm decoders.\n# 1996-04-30 fl   Added encoders.\n# 1996-12-14 fl   Added load helpers\n# 1997-01-11 fl   Use encode_to_file where possible\n# 1997-08-27 fl   Flush output in _save\n# 1998-03-05 fl   Use memory mapping for some modes\n# 1999-02-04 fl   Use memory mapping also for \"I;16\" and \"I;16B\"\n# 1999-05-31 fl   Added image parser\n# 2000-10-12 fl   Set readonly flag on memory-mapped images\n# 2002-03-20 fl   Use better messages for common decoder errors\n# 2003-04-21 fl   Fall back on mmap/map_buffer if map is not available\n# 2003-10-30 fl   Added StubImageFile class\n# 2004-02-25 fl   Made incremental parser more robust\n#\n# Copyright (c) 1997-2004 by Secret Labs AB\n# Copyright (c) 1995-2004 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nfrom PIL import Image\nfrom PIL._util import isPath\nimport traceback, os, sys\nimport io\n\nMAXBLOCK = 65536\n\nSAFEBLOCK = 1024*1024\n\nLOAD_TRUNCATED_IMAGES = False\n\nERRORS = {\n    -1: \"image buffer overrun error\",\n    -2: \"decoding error\",\n    -3: \"unknown error\",\n    -8: \"bad configuration\",\n    -9: \"out of memory error\"\n}\n\ndef raise_ioerror(error):\n    try:\n        message = Image.core.getcodecstatus(error)\n    except AttributeError:\n        message = ERRORS.get(error)\n    if not message:\n        message = \"decoder error %d\" % error\n    raise IOError(message + \" when reading image file\")\n\n#\n# --------------------------------------------------------------------\n# Helpers\n\ndef _tilesort(t):\n    # sort on offset\n    return t[2]\n\n#\n# --------------------------------------------------------------------\n# ImageFile base class\n\nclass ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n        use_mmap = self.filename and len(self.tile) == 1\n        # As of pypy 2.1.0, memory mapping was failing here.\n        use_mmap = use_mmap and not hasattr(sys, 'pypy_version_info') \n        \n        readonly = 0\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n            # don't use mmap if there are custom read/seek functions\n            use_mmap = False\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n            use_mmap = False\n        except AttributeError:\n            seek = self.fp.seek\n\n        if use_mmap:\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        if not self.map:\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass\n\n    # may be defined for contained formats\n    # def load_seek(self, pos):\n    #     pass\n\n    # may be defined for blocked formats (e.g. PNG)\n    # def load_read(self, bytes):\n    #     pass\n\n\nclass StubImageFile(ImageFile):\n    \"\"\"\n    Base class for stub image loaders.\n\n    A stub loader is an image loader that can identify files of a\n    certain format, but relies on external code to load the file.\n    \"\"\"\n\n    def _open(self):\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _open\"\n            )\n\n    def load(self):\n        loader = self._load()\n        if loader is None:\n            raise IOError(\"cannot find loader for this %s file\" % self.format)\n        image = loader.load(self)\n        assert image is not None\n        # become the other object (!)\n        self.__class__ = image.__class__\n        self.__dict__ = image.__dict__\n\n    def _load(self):\n        \"(Hook) Find actual image loader.\"\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _load\"\n            )\n\n\nclass Parser:\n    \"\"\"\n    Incremental image parser.  This class implements the standard\n    feed/close consumer interface.\n\n    In Python 2.x, this is an old-style class.\n    \"\"\"\n    incremental = None\n    image = None\n    data = None\n    decoder = None\n    finished = 0\n\n    def reset(self):\n        \"\"\"\n        (Consumer) Reset the parser.  Note that you can only call this\n        method immediately after you've created a parser; parser\n        instances cannot be reused.\n        \"\"\"\n        assert self.data is None, \"cannot reuse parsers\"\n\n    def feed(self, data):\n        \"\"\"\n        (Consumer) Feed data to the parser.\n\n        :param data: A string buffer.\n        :exception IOError: If the parser failed to parse the image file.\n        \"\"\"\n        # collect data\n\n        if self.finished:\n            return\n\n        if self.data is None:\n            self.data = data\n        else:\n            self.data = self.data + data\n\n        # parse what we have\n        if self.decoder:\n\n            if self.offset > 0:\n                # skip header\n                skip = min(len(self.data), self.offset)\n                self.data = self.data[skip:]\n                self.offset = self.offset - skip\n                if self.offset > 0 or not self.data:\n                    return\n\n            n, e = self.decoder.decode(self.data)\n\n            if n < 0:\n                # end of stream\n                self.data = None\n                self.finished = 1\n                if e < 0:\n                    # decoding error\n                    self.image = None\n                    raise_ioerror(e)\n                else:\n                    # end of image\n                    return\n            self.data = self.data[n:]\n\n        elif self.image:\n\n            # if we end up here with no decoder, this file cannot\n            # be incrementally parsed.  wait until we've gotten all\n            # available data\n            pass\n\n        else:\n\n            # attempt to open this file\n            try:\n                try:\n                    fp = io.BytesIO(self.data)\n                    im = Image.open(fp)\n                finally:\n                    fp.close() # explicitly close the virtual file\n            except IOError:\n                # traceback.print_exc()\n                pass # not enough data\n            else:\n                flag = hasattr(im, \"load_seek\") or hasattr(im, \"load_read\")\n                if flag or len(im.tile) != 1:\n                    # custom load code, or multiple tiles\n                    self.decode = None\n                else:\n                    # initialize decoder\n                    im.load_prepare()\n                    d, e, o, a = im.tile[0]\n                    im.tile = []\n                    self.decoder = Image._getdecoder(\n                        im.mode, d, a, im.decoderconfig\n                        )\n                    self.decoder.setimage(im.im, e)\n\n                    # calculate decoder offset\n                    self.offset = o\n                    if self.offset <= len(self.data):\n                        self.data = self.data[self.offset:]\n                        self.offset = 0\n\n                self.image = im\n\n    def close(self):\n        \"\"\"\n        (Consumer) Close the stream.\n\n        :returns: An image object.\n        :exception IOError: If the parser failed to parse the image file either\n                            because it cannot be identified or cannot be\n                            decoded.\n        \"\"\"\n        # finish decoding\n        if self.decoder:\n            # get rid of what's left in the buffers\n            self.feed(b\"\")\n            self.data = self.decoder = None\n            if not self.finished:\n                raise IOError(\"image was incomplete\")\n        if not self.image:\n            raise IOError(\"cannot parse this image\")\n        if self.data:\n            # incremental parsing not possible; reopen the file\n            # not that we have all data\n            try:\n                fp = io.BytesIO(self.data)\n                self.image = Image.open(fp)\n            finally:\n                self.image.load()\n                fp.close() # explicitly close the virtual file\n        return self.image\n\n# --------------------------------------------------------------------\n\ndef _save(im, fp, tile, bufsize=0):\n    \"\"\"Helper to save image based on tile list\n\n    :param im: Image object.\n    :param fp: File object.\n    :param tile: Tile list.\n    :param bufsize: Optional buffer size\n    \"\"\"\n\n    im.load()\n    if not hasattr(im, \"encoderconfig\"):\n        im.encoderconfig = ()\n    tile.sort(key=_tilesort)\n    # FIXME: make MAXBLOCK a configuration parameter\n    # It would be great if we could have the encoder specifiy what it needs\n    # But, it would need at least the image size in most cases. RawEncode is\n    # a tricky case.\n    bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c\n    try:\n        fh = fp.fileno()\n        fp.flush()\n    except (AttributeError, io.UnsupportedOperation):\n        # compress to Python file-compatible object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            while True:\n                l, s, d = e.encode(bufsize)\n                fp.write(d)\n                if s:\n                    break\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    else:\n        # slight speedup: compress to real file object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            s = e.encode_to_file(fh, bufsize)\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    try:\n        fp.flush()\n    except: pass\n\n\ndef _safe_read(fp, size):\n    \"\"\"\n    Reads large blocks in a safe way.  Unlike fp.read(n), this function\n    doesn't trust the user.  If the requested size is larger than\n    SAFEBLOCK, the file is read block by block.\n\n    :param fp: File handle.  Must implement a <b>read</b> method.\n    :param size: Number of bytes to read.\n    :returns: A string containing up to <i>size</i> bytes of data.\n    \"\"\"\n    if size <= 0:\n        return b\"\"\n    if size <= SAFEBLOCK:\n        return fp.read(size)\n    data = []\n    while size > 0:\n        block = fp.read(min(size, SAFEBLOCK))\n        if not block:\n            break\n        data.append(block)\n        size -= len(block)\n    return b\"\".join(data)\n",
            "header": {
                "file": {
                    "path": "PIL/ImageFile.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "adb27f2bd",
                "new_commit_hash": "5e4745d76",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/PIL/ImageFile.py"
            },
            "plus_file": {
                "path": "b/PIL/ImageFile.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 133,
                            "length": 11
                        },
                        "new_range": {
                            "start": 133,
                            "length": 27
                        },
                        "section": "class ImageFile(Image.Image):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            return pixel",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        self.map = None",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "        use_mmap = self.filename and len(self.tile) == 1",
                                "type": "added"
                            },
                            {
                                "content": "        # As of pypy 2.1.0, memory mapping was failing here.",
                                "type": "added"
                            },
                            {
                                "content": "        use_mmap = use_mmap and not hasattr(sys, 'pypy_version_info') ",
                                "type": "added"
                            },
                            {
                                "content": "        ",
                                "type": "added"
                            },
                            {
                                "content": "        readonly = 0",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):",
                                "type": "deleted"
                            },
                            {
                                "content": "            # As of pypy 2.1.0, memory mapping was failing here.",
                                "type": "deleted"
                            },
                            {
                                "content": "        # look for read/seek overrides",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "added"
                            },
                            {
                                "content": "            read = self.load_read",
                                "type": "added"
                            },
                            {
                                "content": "            # don't use mmap if there are custom read/seek functions",
                                "type": "added"
                            },
                            {
                                "content": "            use_mmap = False",
                                "type": "added"
                            },
                            {
                                "content": "        except AttributeError:",
                                "type": "added"
                            },
                            {
                                "content": "            read = self.fp.read",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        try:",
                                "type": "added"
                            },
                            {
                                "content": "            seek = self.load_seek",
                                "type": "added"
                            },
                            {
                                "content": "            use_mmap = False",
                                "type": "added"
                            },
                            {
                                "content": "        except AttributeError:",
                                "type": "added"
                            },
                            {
                                "content": "            seek = self.fp.seek",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        if use_mmap:",
                                "type": "added"
                            },
                            {
                                "content": "            # try memory mapping",
                                "type": "context"
                            },
                            {
                                "content": "            d, e, o, a = self.tile[0]",
                                "type": "context"
                            },
                            {
                                "content": "            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "PIL/ImageFile.py",
                            "type": "class",
                            "name": "ImageFile",
                            "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 70,
                            "end_lineno": 257,
                            "parent": null
                        },
                        {
                            "file_name": "PIL/ImageFile.py",
                            "type": "method",
                            "name": "ImageFile.load",
                            "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 125,
                            "end_lineno": 244,
                            "parent": {
                                "file_name": "PIL/ImageFile.py",
                                "type": "class",
                                "name": "ImageFile",
                                "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 70,
                                "end_lineno": 257,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 165,
                            "length": 19
                        },
                        "new_range": {
                            "start": 181,
                            "length": 7
                        },
                        "section": "class ImageFile(Image.Image):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        self.load_prepare()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        # look for read/seek overrides",
                                "type": "deleted"
                            },
                            {
                                "content": "        try:",
                                "type": "deleted"
                            },
                            {
                                "content": "            read = self.load_read",
                                "type": "deleted"
                            },
                            {
                                "content": "        except AttributeError:",
                                "type": "deleted"
                            },
                            {
                                "content": "            read = self.fp.read",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "        try:",
                                "type": "deleted"
                            },
                            {
                                "content": "            seek = self.load_seek",
                                "type": "deleted"
                            },
                            {
                                "content": "        except AttributeError:",
                                "type": "deleted"
                            },
                            {
                                "content": "            seek = self.fp.seek",
                                "type": "deleted"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "        if not self.map:",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "deleted"
                            },
                            {
                                "content": "            # sort tiles in file order",
                                "type": "context"
                            },
                            {
                                "content": "            self.tile.sort(key=_tilesort)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "PIL/ImageFile.py",
                            "type": "class",
                            "name": "ImageFile",
                            "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 70,
                            "end_lineno": 257,
                            "parent": null
                        },
                        {
                            "file_name": "PIL/ImageFile.py",
                            "type": "method",
                            "name": "ImageFile.load",
                            "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 125,
                            "end_lineno": 244,
                            "parent": {
                                "file_name": "PIL/ImageFile.py",
                                "type": "class",
                                "name": "ImageFile",
                                "content": "class ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 70,
                                "end_lineno": 257,
                                "parent": null
                            }
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# XPM File handling\n#\n# History:\n# 1996-12-29 fl   Created\n# 2001-02-17 fl   Use 're' instead of 'regex' (Python 2.1) (0.7)\n#\n# Copyright (c) Secret Labs AB 1997-2001.\n# Copyright (c) Fredrik Lundh 1996-2001.\n#\n# See the README file for information on usage and redistribution.\n#\n\n\n__version__ = \"0.2\"\n\n\nimport re\nfrom PIL import Image, ImageFile, ImagePalette\nfrom PIL._binary import i8, o8\n\n# XPM header\nxpm_head = re.compile(b\"\\\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)\")\n\n\ndef _accept(prefix):\n    return prefix[:9] == b\"/* XPM */\"\n\n##\n# Image plugin for X11 pixel maps.\n\nclass XpmImageFile(ImageFile.ImageFile):\n\n    format = \"XPM\"\n    format_description = \"X11 Pixel Map\"\n\n    def _open(self):\n\n        if not _accept(self.fp.read(9)):\n            raise SyntaxError(\"not an XPM file\")\n\n        # skip forward to next string\n        while True:\n            s = self.fp.readline()\n            if not s:\n                raise SyntaxError(\"broken XPM file\")\n            m = xpm_head.match(s)\n            if m:\n                break\n\n        self.size = int(m.group(1)), int(m.group(2))\n\n        pal = int(m.group(3))\n        bpp = int(m.group(4))\n\n        if pal > 256 or bpp != 1:\n            raise ValueError(\"cannot read this XPM file\")\n\n        #\n        # load palette description\n\n        palette = [b\"\\0\\0\\0\"] * 256\n\n        for i in range(pal):\n\n            s = self.fp.readline()\n            if s[-2:] == b'\\r\\n':\n                s = s[:-2]\n            elif s[-1:] in b'\\r\\n':\n                s = s[:-1]\n\n            c = i8(s[1])\n            s = s[2:-2].split()\n\n            for i in range(0, len(s), 2):\n\n                if s[i] == b\"c\":\n\n                    # process colour key\n                    rgb = s[i+1]\n                    if rgb == b\"None\":\n                        self.info[\"transparency\"] = c\n                    elif rgb[0:1] == b\"#\":\n                        # FIXME: handle colour names (see ImagePalette.py)\n                        rgb = int(rgb[1:], 16)\n                        palette[c] = o8((rgb >> 16) & 255) +\\\n                                     o8((rgb >> 8) & 255) +\\\n                                     o8(rgb & 255)\n                    else:\n                        # unknown colour\n                        raise ValueError(\"cannot read this XPM file\")\n                    break\n\n            else:\n\n                # missing colour key\n                raise ValueError(\"cannot read this XPM file\")\n\n        self.mode = \"P\"\n        self.palette = ImagePalette.raw(\"RGB\", b\"\".join(palette))\n\n        self.tile = [(\"raw\", (0, 0)+self.size, self.fp.tell(), (\"P\", 0, 1))]\n\n    def load_read(self, bytes):\n\n        #\n        # load all image data in one chunk\n\n        xsize, ysize = self.size\n\n        s = [None] * ysize\n\n        for i in range(ysize):\n            s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)\n\n        self.fp = None\n\n        return b\"\".join(s)\n\n#\n# Registry\n\nImage.register_open(\"XPM\", XpmImageFile, _accept)\n\nImage.register_extension(\"XPM\", \".xpm\")\n\nImage.register_mime(\"XPM\", \"image/xpm\")\n",
            "new_file_content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# XPM File handling\n#\n# History:\n# 1996-12-29 fl   Created\n# 2001-02-17 fl   Use 're' instead of 'regex' (Python 2.1) (0.7)\n#\n# Copyright (c) Secret Labs AB 1997-2001.\n# Copyright (c) Fredrik Lundh 1996-2001.\n#\n# See the README file for information on usage and redistribution.\n#\n\n\n__version__ = \"0.2\"\n\n\nimport re\nfrom PIL import Image, ImageFile, ImagePalette\nfrom PIL._binary import i8, o8\n\n# XPM header\nxpm_head = re.compile(b\"\\\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)\")\n\n\ndef _accept(prefix):\n    return prefix[:9] == b\"/* XPM */\"\n\n\n##\n# Image plugin for X11 pixel maps.\n\nclass XpmImageFile(ImageFile.ImageFile):\n\n    format = \"XPM\"\n    format_description = \"X11 Pixel Map\"\n\n    def _open(self):\n\n        if not _accept(self.fp.read(9)):\n            raise SyntaxError(\"not an XPM file\")\n\n        # skip forward to next string\n        while True:\n            s = self.fp.readline()\n            if not s:\n                raise SyntaxError(\"broken XPM file\")\n            m = xpm_head.match(s)\n            if m:\n                break\n\n        self.size = int(m.group(1)), int(m.group(2))\n\n        pal = int(m.group(3))\n        bpp = int(m.group(4))\n\n        if pal > 256 or bpp != 1:\n            raise ValueError(\"cannot read this XPM file\")\n\n        #\n        # load palette description\n\n        palette = [b\"\\0\\0\\0\"] * 256\n\n        for i in range(pal):\n\n            s = self.fp.readline()\n            if s[-2:] == b'\\r\\n':\n                s = s[:-2]\n            elif s[-1:] in b'\\r\\n':\n                s = s[:-1]\n\n            c = i8(s[1])\n            s = s[2:-2].split()\n\n            for i in range(0, len(s), 2):\n\n                if s[i] == b\"c\":\n\n                    # process colour key\n                    rgb = s[i+1]\n                    if rgb == b\"None\":\n                        self.info[\"transparency\"] = c\n                    elif rgb[0:1] == b\"#\":\n                        # FIXME: handle colour names (see ImagePalette.py)\n                        rgb = int(rgb[1:], 16)\n                        palette[c] = (o8((rgb >> 16) & 255) +\n                                      o8((rgb >> 8) & 255) +\n                                      o8(rgb & 255))\n                    else:\n                        # unknown colour\n                        raise ValueError(\"cannot read this XPM file\")\n                    break\n\n            else:\n\n                # missing colour key\n                raise ValueError(\"cannot read this XPM file\")\n\n        self.mode = \"P\"\n        self.palette = ImagePalette.raw(\"RGB\", b\"\".join(palette))\n\n        self.tile = [(\"raw\", (0, 0)+self.size, self.fp.tell(), (\"P\", 0, 1))]\n\n    def load_read(self, bytes):\n\n        #\n        # load all image data in one chunk\n\n        xsize, ysize = self.size\n\n        s = [None] * ysize\n\n        for i in range(ysize):\n            s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)\n\n        self.fp = None\n\n        return b\"\".join(s)\n\n#\n# Registry\n\nImage.register_open(\"XPM\", XpmImageFile, _accept)\n\nImage.register_extension(\"XPM\", \".xpm\")\n\nImage.register_mime(\"XPM\", \"image/xpm\")\n",
            "header": {
                "file": {
                    "path": "PIL/XpmImagePlugin.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "701a23b64",
                "new_commit_hash": "517580895",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/PIL/XpmImagePlugin.py"
            },
            "plus_file": {
                "path": "b/PIL/XpmImagePlugin.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 29,
                            "length": 6
                        },
                        "new_range": {
                            "start": 29,
                            "length": 7
                        },
                        "section": "xpm_head = re.compile(b\"\\\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)\")"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "def _accept(prefix):",
                                "type": "context"
                            },
                            {
                                "content": "    return prefix[:9] == b\"/* XPM */\"",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "##",
                                "type": "context"
                            },
                            {
                                "content": "# Image plugin for X11 pixel maps.",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 86,
                            "length": 9
                        },
                        "new_range": {
                            "start": 87,
                            "length": 9
                        },
                        "section": "class XpmImageFile(ImageFile.ImageFile):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                    elif rgb[0:1] == b\"#\":",
                                "type": "context"
                            },
                            {
                                "content": "                        # FIXME: handle colour names (see ImagePalette.py)",
                                "type": "context"
                            },
                            {
                                "content": "                        rgb = int(rgb[1:], 16)",
                                "type": "context"
                            },
                            {
                                "content": "                        palette[c] = o8((rgb >> 16) & 255) +\\",
                                "type": "deleted"
                            },
                            {
                                "content": "                                     o8((rgb >> 8) & 255) +\\",
                                "type": "deleted"
                            },
                            {
                                "content": "                                     o8(rgb & 255)",
                                "type": "deleted"
                            },
                            {
                                "content": "                        palette[c] = (o8((rgb >> 16) & 255) +",
                                "type": "added"
                            },
                            {
                                "content": "                                      o8((rgb >> 8) & 255) +",
                                "type": "added"
                            },
                            {
                                "content": "                                      o8(rgb & 255))",
                                "type": "added"
                            },
                            {
                                "content": "                    else:",
                                "type": "context"
                            },
                            {
                                "content": "                        # unknown colour",
                                "type": "context"
                            },
                            {
                                "content": "                        raise ValueError(\"cannot read this XPM file\")",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "PIL/XpmImagePlugin.py",
                            "type": "method",
                            "name": "XpmImageFile._open",
                            "content": "class XpmImageFile(ImageFile.ImageFile):\n\n    format = \"XPM\"\n    format_description = \"X11 Pixel Map\"\n\n    def _open(self):\n\n        if not _accept(self.fp.read(9)):\n            raise SyntaxError(\"not an XPM file\")\n\n        # skip forward to next string\n        while True:\n            s = self.fp.readline()\n            if not s:\n                raise SyntaxError(\"broken XPM file\")\n            m = xpm_head.match(s)\n            if m:\n                break\n\n        self.size = int(m.group(1)), int(m.group(2))\n\n        pal = int(m.group(3))\n        bpp = int(m.group(4))\n\n        if pal > 256 or bpp != 1:\n            raise ValueError(\"cannot read this XPM file\")\n\n        #\n        # load palette description\n\n        palette = [b\"\\0\\0\\0\"] * 256\n\n        for i in range(pal):\n\n            s = self.fp.readline()\n            if s[-2:] == b'\\r\\n':\n                s = s[:-2]\n            elif s[-1:] in b'\\r\\n':\n                s = s[:-1]\n\n            c = i8(s[1])\n            s = s[2:-2].split()\n\n            for i in range(0, len(s), 2):\n\n                if s[i] == b\"c\":\n\n                    # process colour key\n                    rgb = s[i+1]\n                    if rgb == b\"None\":\n                        self.info[\"transparency\"] = c\n                    elif rgb[0:1] == b\"#\":\n                        # FIXME: handle colour names (see ImagePalette.py)\n                        rgb = int(rgb[1:], 16)\n                        palette[c] = o8((rgb >> 16) & 255) +\\\n                                     o8((rgb >> 8) & 255) +\\\n                                     o8(rgb & 255)\n                    else:\n                        # unknown colour\n                        raise ValueError(\"cannot read this XPM file\")\n                    break\n\n            else:\n\n                # missing colour key\n                raise ValueError(\"cannot read this XPM file\")\n\n        self.mode = \"P\"\n        self.palette = ImagePalette.raw(\"RGB\", b\"\".join(palette))\n\n        self.tile = [(\"raw\", (0, 0)+self.size, self.fp.tell(), (\"P\", 0, 1))]\n\n    def load_read(self, bytes):\n\n        #\n        # load all image data in one chunk\n\n        xsize, ysize = self.size\n\n        s = [None] * ysize\n\n        for i in range(ysize):\n            s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)\n\n        self.fp = None\n\n        return b\"\".join(s)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 40,
                            "end_lineno": 105,
                            "parent": {
                                "file_name": "PIL/XpmImagePlugin.py",
                                "type": "class",
                                "name": "XpmImageFile",
                                "content": "class XpmImageFile(ImageFile.ImageFile):\n\n    format = \"XPM\"\n    format_description = \"X11 Pixel Map\"\n\n    def _open(self):\n\n        if not _accept(self.fp.read(9)):\n            raise SyntaxError(\"not an XPM file\")\n\n        # skip forward to next string\n        while True:\n            s = self.fp.readline()\n            if not s:\n                raise SyntaxError(\"broken XPM file\")\n            m = xpm_head.match(s)\n            if m:\n                break\n\n        self.size = int(m.group(1)), int(m.group(2))\n\n        pal = int(m.group(3))\n        bpp = int(m.group(4))\n\n        if pal > 256 or bpp != 1:\n            raise ValueError(\"cannot read this XPM file\")\n\n        #\n        # load palette description\n\n        palette = [b\"\\0\\0\\0\"] * 256\n\n        for i in range(pal):\n\n            s = self.fp.readline()\n            if s[-2:] == b'\\r\\n':\n                s = s[:-2]\n            elif s[-1:] in b'\\r\\n':\n                s = s[:-1]\n\n            c = i8(s[1])\n            s = s[2:-2].split()\n\n            for i in range(0, len(s), 2):\n\n                if s[i] == b\"c\":\n\n                    # process colour key\n                    rgb = s[i+1]\n                    if rgb == b\"None\":\n                        self.info[\"transparency\"] = c\n                    elif rgb[0:1] == b\"#\":\n                        # FIXME: handle colour names (see ImagePalette.py)\n                        rgb = int(rgb[1:], 16)\n                        palette[c] = o8((rgb >> 16) & 255) +\\\n                                     o8((rgb >> 8) & 255) +\\\n                                     o8(rgb & 255)\n                    else:\n                        # unknown colour\n                        raise ValueError(\"cannot read this XPM file\")\n                    break\n\n            else:\n\n                # missing colour key\n                raise ValueError(\"cannot read this XPM file\")\n\n        self.mode = \"P\"\n        self.palette = ImagePalette.raw(\"RGB\", b\"\".join(palette))\n\n        self.tile = [(\"raw\", (0, 0)+self.size, self.fp.tell(), (\"P\", 0, 1))]\n\n    def load_read(self, bytes):\n\n        #\n        # load all image data in one chunk\n\n        xsize, ysize = self.size\n\n        s = [None] * ysize\n\n        for i in range(ysize):\n            s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)\n\n        self.fp = None\n\n        return b\"\".join(s)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 35,
                                "end_lineno": 121,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "PIL/XpmImagePlugin.py",
                            "type": "class",
                            "name": "XpmImageFile",
                            "content": "class XpmImageFile(ImageFile.ImageFile):\n\n    format = \"XPM\"\n    format_description = \"X11 Pixel Map\"\n\n    def _open(self):\n\n        if not _accept(self.fp.read(9)):\n            raise SyntaxError(\"not an XPM file\")\n\n        # skip forward to next string\n        while True:\n            s = self.fp.readline()\n            if not s:\n                raise SyntaxError(\"broken XPM file\")\n            m = xpm_head.match(s)\n            if m:\n                break\n\n        self.size = int(m.group(1)), int(m.group(2))\n\n        pal = int(m.group(3))\n        bpp = int(m.group(4))\n\n        if pal > 256 or bpp != 1:\n            raise ValueError(\"cannot read this XPM file\")\n\n        #\n        # load palette description\n\n        palette = [b\"\\0\\0\\0\"] * 256\n\n        for i in range(pal):\n\n            s = self.fp.readline()\n            if s[-2:] == b'\\r\\n':\n                s = s[:-2]\n            elif s[-1:] in b'\\r\\n':\n                s = s[:-1]\n\n            c = i8(s[1])\n            s = s[2:-2].split()\n\n            for i in range(0, len(s), 2):\n\n                if s[i] == b\"c\":\n\n                    # process colour key\n                    rgb = s[i+1]\n                    if rgb == b\"None\":\n                        self.info[\"transparency\"] = c\n                    elif rgb[0:1] == b\"#\":\n                        # FIXME: handle colour names (see ImagePalette.py)\n                        rgb = int(rgb[1:], 16)\n                        palette[c] = o8((rgb >> 16) & 255) +\\\n                                     o8((rgb >> 8) & 255) +\\\n                                     o8(rgb & 255)\n                    else:\n                        # unknown colour\n                        raise ValueError(\"cannot read this XPM file\")\n                    break\n\n            else:\n\n                # missing colour key\n                raise ValueError(\"cannot read this XPM file\")\n\n        self.mode = \"P\"\n        self.palette = ImagePalette.raw(\"RGB\", b\"\".join(palette))\n\n        self.tile = [(\"raw\", (0, 0)+self.size, self.fp.tell(), (\"P\", 0, 1))]\n\n    def load_read(self, bytes):\n\n        #\n        # load all image data in one chunk\n\n        xsize, ysize = self.size\n\n        s = [None] * ysize\n\n        for i in range(ysize):\n            s[i] = self.fp.readline()[1:xsize+1].ljust(xsize)\n\n        self.fp = None\n\n        return b\"\".join(s)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 35,
                            "end_lineno": 121,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from helper import unittest, PillowTestCase\n\nfrom PIL import Image\n\n# sample ppm stream\nfile = \"Tests/images/lena.xpm\"\ndata = open(file, \"rb\").read()\n\n\nclass TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(file)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n# End of file\n",
            "new_file_content": "from helper import unittest, PillowTestCase, lena\n\nfrom PIL import Image\n\n# sample ppm stream\nTEST_FILE = \"Tests/images/lena.xpm\"\n\n\nclass TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(TEST_FILE)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")\n\n        #large error due to quantization->44 colors.\n        self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60) \n\n    def test_load_read(self):\n        # Arrange\n        im = Image.open(TEST_FILE)\n        dummy_bytes = 1\n\n        # Act\n        data = im.load_read(dummy_bytes)\n\n        # Assert\n        self.assertEqual(len(data), 16384)\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n# End of file\n",
            "header": {
                "file": {
                    "path": "Tests/test_file_xpm.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "d79f5fbda",
                "new_commit_hash": "4fc393808",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/Tests/test_file_xpm.py"
            },
            "plus_file": {
                "path": "b/Tests/test_file_xpm.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1,
                            "length": 21
                        },
                        "new_range": {
                            "start": 1,
                            "length": 34
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "from helper import unittest, PillowTestCase",
                                "type": "deleted"
                            },
                            {
                                "content": "from helper import unittest, PillowTestCase, lena",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "from PIL import Image",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "# sample ppm stream",
                                "type": "context"
                            },
                            {
                                "content": "file = \"Tests/images/lena.xpm\"",
                                "type": "deleted"
                            },
                            {
                                "content": "data = open(file, \"rb\").read()",
                                "type": "deleted"
                            },
                            {
                                "content": "TEST_FILE = \"Tests/images/lena.xpm\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "class TestFileXpm(PillowTestCase):",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_sanity(self):",
                                "type": "context"
                            },
                            {
                                "content": "        im = Image.open(file)",
                                "type": "deleted"
                            },
                            {
                                "content": "        im = Image.open(TEST_FILE)",
                                "type": "added"
                            },
                            {
                                "content": "        im.load()",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(im.mode, \"P\")",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(im.size, (128, 128))",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(im.format, \"XPM\")",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        #large error due to quantization->44 colors.",
                                "type": "added"
                            },
                            {
                                "content": "        self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60) ",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def test_load_read(self):",
                                "type": "added"
                            },
                            {
                                "content": "        # Arrange",
                                "type": "added"
                            },
                            {
                                "content": "        im = Image.open(TEST_FILE)",
                                "type": "added"
                            },
                            {
                                "content": "        dummy_bytes = 1",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Act",
                                "type": "added"
                            },
                            {
                                "content": "        data = im.load_read(dummy_bytes)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        # Assert",
                                "type": "added"
                            },
                            {
                                "content": "        self.assertEqual(len(data), 16384)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "if __name__ == '__main__':",
                                "type": "context"
                            },
                            {
                                "content": "    unittest.main()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "method",
                            "name": "TestFileXpm.test_sanity",
                            "content": "class TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(file)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 12,
                            "end_lineno": 17,
                            "parent": {
                                "file_name": "Tests/test_file_xpm.py",
                                "type": "class",
                                "name": "TestFileXpm",
                                "content": "class TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(file)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 10,
                                "end_lineno": 17,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "class",
                            "name": "TestFileXpm",
                            "content": "class TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(file)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 10,
                            "end_lineno": 17,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "statement",
                            "name": "",
                            "content": "from helper import unittest, PillowTestCase, lena",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 1,
                            "end_lineno": 1,
                            "parent": null
                        },
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "statement",
                            "name": "",
                            "content": "TEST_FILE = \"Tests/images/lena.xpm\"",
                            "ast_type_str": "Assign",
                            "start_lineno": 6,
                            "end_lineno": 6,
                            "parent": null
                        },
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "method",
                            "name": "TestFileXpm.test_load_read",
                            "content": "class TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(TEST_FILE)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")\n\n        #large error due to quantization->44 colors.\n        self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60) \n\n    def test_load_read(self):\n        # Arrange\n        im = Image.open(TEST_FILE)\n        dummy_bytes = 1\n\n        # Act\n        data = im.load_read(dummy_bytes)\n\n        # Assert\n        self.assertEqual(len(data), 16384)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 21,
                            "end_lineno": 30,
                            "parent": {
                                "file_name": "Tests/test_file_xpm.py",
                                "type": "class",
                                "name": "TestFileXpm",
                                "content": "class TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(TEST_FILE)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")\n\n        #large error due to quantization->44 colors.\n        self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60) \n\n    def test_load_read(self):\n        # Arrange\n        im = Image.open(TEST_FILE)\n        dummy_bytes = 1\n\n        # Act\n        data = im.load_read(dummy_bytes)\n\n        # Assert\n        self.assertEqual(len(data), 16384)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 9,
                                "end_lineno": 30,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "statement",
                            "name": "",
                            "content": "data = open(file, \"rb\").read()",
                            "ast_type_str": "Assign",
                            "start_lineno": 7,
                            "end_lineno": 7,
                            "parent": null
                        },
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "statement",
                            "name": "",
                            "content": "file = \"Tests/images/lena.xpm\"",
                            "ast_type_str": "Assign",
                            "start_lineno": 6,
                            "end_lineno": 6,
                            "parent": null
                        },
                        {
                            "file_name": "Tests/test_file_xpm.py",
                            "type": "statement",
                            "name": "",
                            "content": "from helper import unittest, PillowTestCase",
                            "ast_type_str": "ImportFrom",
                            "start_lineno": 1,
                            "end_lineno": 1,
                            "parent": null
                        }
                    ]
                }
            ]
        }
    ],
    "old_commit_hash": "eb4f669b34ab822163be19325170f1948bdc5301^",
    "new_commit_hash": "eb4f669b34ab822163be19325170f1948bdc5301",
    "commit_message": "Merge pull request #808 from wiredfool/xpm_load_image\n\nFix Scrambled XPM",
    "commit_date": "2014-07-19T00:28:02+03:00",
    "metadata": {}
}
{
    "repo_name": "pillow",
    "new_commit_hash": "eb4f669b34ab822163be19325170f1948bdc5301",
    "test_file_codes": [
        "from helper import unittest, PillowTestCase, lena\n\nfrom PIL import Image\n\n# sample ppm stream\nTEST_FILE = \"Tests/images/lena.xpm\"\n\n\nclass TestFileXpm(PillowTestCase):\n\n    def test_sanity(self):\n        im = Image.open(TEST_FILE)\n        im.load()\n        self.assertEqual(im.mode, \"P\")\n        self.assertEqual(im.size, (128, 128))\n        self.assertEqual(im.format, \"XPM\")\n\n        #large error due to quantization->44 colors.\n        self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60) \n\n    def test_load_read(self):\n        # Arrange\n        im = Image.open(TEST_FILE)\n        dummy_bytes = 1\n\n        # Act\n        data = im.load_read(dummy_bytes)\n\n        # Assert\n        self.assertEqual(len(data), 16384)\n\n\nif __name__ == '__main__':\n    unittest.main()\n\n# End of file\n",
        "#!/usr/bin/env python\nimport unittest\nimport sys\nimport time\nimport traceback\nimport platform\nimport os\n\n\nclass PytestLikeResult(unittest.TestResult):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.start_time = None\n        # Store (test, outcome, info) for each test:\n        #   outcome ∈ { \"passed\", \"failed\", \"error\", \"skipped\" }\n        #   info can hold the exception or skip reason, etc.\n        self.results = []\n\n    def startTestRun(self):\n        \"\"\"Called once before all tests.\"\"\"\n        self.start_time = time.time()\n        # Print a header similar to pytest\n        print(\"=\" * 29 + \" test session starts \" + \"=\" * 29)\n        # You can customize the platform/versions/paths as you like:\n        print(\n            f\"platform {platform.system().lower()} -- Python {platform.python_version()}\"\n        )\n        print(f\"rootdir: {os.path.abspath(os.curdir)}\")\n\n    def stopTestRun(self):\n        \"\"\"Called once after all tests are done.\"\"\"\n        elapsed = time.time() - self.start_time\n        print()  # blank line after final dot\n\n        # Summarize\n        ntests = len(self.results)\n        print(f\"collected {ntests} items\")\n\n        # Show details of failures/errors\n        failures = [r for r in self.results if r[1] == \"failed\"]\n        errors = [r for r in self.results if r[1] == \"error\"]\n\n        if failures:\n            print(\"\\n\" + \"=\" * 35 + \" FAILURES \" + \"=\" * 35)\n            for test, outcome, err_info in failures:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n        if errors:\n            print(\"\\n\" + \"=\" * 35 + \" ERRORS \" + \"=\" * 37)\n            for test, outcome, err_info in errors:\n                test = test.split(\"::\")\n                if len(test) == 3:\n                    test = f\"{test[1]}.{test[2]}\"\n                else:\n                    test = f\"{test[1]}\"\n                print(f\"__________ {test} __________\")\n                self._print_traceback(err_info)\n\n        # Optional short summary lines for passes/fails/skips\n        print(\"\\n==================== short test summary info ====================\")\n        for test, outcome, info in self.results:\n            if outcome in (\"passed\", \"failed\", \"error\", \"skipped\"):\n                print(f\"{outcome.upper()} {test}\")\n\n        # Final one-line summary: “1 failed, 1 errors, 10 passed in 2.04s”\n        passed_count = sum(1 for r in self.results if r[1] == \"passed\")\n        failed_count = len(failures)\n        error_count = len(errors)\n        skipped_count = sum(1 for r in self.results if r[1] == \"skipped\")\n\n        summary_bits = []\n        if failed_count:\n            summary_bits.append(f\"{failed_count} failed\")\n        if error_count:\n            summary_bits.append(f\"{error_count} error{'s' if error_count != 1 else ''}\")\n        if passed_count:\n            summary_bits.append(f\"{passed_count} passed\")\n        if skipped_count:\n            summary_bits.append(f\"{skipped_count} skipped\")\n\n        summary_str = \", \".join(summary_bits) if summary_bits else \"no tests run\"\n        print(\n            f\"=================== {summary_str} in {elapsed:.2f}s ===================\"\n        )\n\n    def startTest(self, test):\n        \"\"\"Called right before each test method.\"\"\"\n        super().startTest(test)\n        # Print a dot or some indicator\n        print(\".\", end=\"\", flush=True)\n\n    def addSuccess(self, test):\n        super().addSuccess(test)\n        self.results.append((self._test_id(test), \"passed\", None))\n\n    def addFailure(self, test, err):\n        super().addFailure(test, err)\n        self.results.append((self._test_id(test), \"failed\", err))\n\n    def addError(self, test, err):\n        super().addError(test, err)\n        self.results.append((self._test_id(test), \"error\", err))\n\n    def addSkip(self, test, reason):\n        super().addSkip(test, reason)\n        self.results.append((self._test_id(test), \"skipped\", reason))\n\n    def _print_traceback(self, err_info):\n        \"\"\"Helper to print the traceback like pytest does.\"\"\"\n        if isinstance(err_info, tuple) and len(err_info) == 3:\n            exc_type, exc_value, tb = err_info\n            traceback.print_exception(exc_type, exc_value, tb, file=sys.stdout)\n        else:\n            print(str(err_info))\n\n    def _test_id(self, test):\n        try:\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}::{test._testMethodName}\"\n        except AttributeError:\n            # Fallback for _ErrorHolder objects\n            return f\"{test.__class__.__module__}::{test.__class__.__name__}\"\n\n\nclass PytestLikeRunner(unittest.TextTestRunner):\n    \"\"\"A custom TextTestRunner that uses the PytestLikeResult.\"\"\"\n\n    resultclass = PytestLikeResult\n\n    def run(self, test):\n        result = self._makeResult()\n        # Overriding run to ensure we call startTestRun/stopTestRun\n        result.startTestRun()\n        test(result)\n        result.stopTestRun()\n        return result\n\n\ndef main():\n    loader = unittest.TestLoader()\n    suite = loader.discover(\"r2e_tests\")  # discover tests in r2e_tests/\n    runner = PytestLikeRunner(verbosity=0)\n    result = runner.run(suite)\n    # Exit with code 0 if all tests passed/skipped, 1 if there were fails/errors\n    sys.exit(not result.wasSuccessful())\n\n\nif __name__ == \"__main__\":\n    main()\n"
    ],
    "test_file_names": [
        "test_1.py",
        "unittest_custom_runner.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "Starting Pillow installation attempts...\nVerifying Pillow installation...\n✅ Pillow installation successful!\nSuccessfully installed Pillow\n",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 12 packages in 13ms\nInstalled 12 packages in 106ms\n + coverage==7.6.10\n + exceptiongroup==1.2.2\n + iniconfig==2.0.0\n + packaging==24.2\n + pluggy==1.5.0\n + pyqt5==5.15.11\n + pyqt5-qt5==5.15.16\n + pyqt5-sip==12.16.1\n + pytest==8.3.4\n + pytest-cov==6.0.0\n + setuptools==75.8.0\n + tomli==2.2.1\nResolved 1 package in 1.24s\nPrepared 1 package in 11.45s\nInstalled 1 package in 2ms\n + pillow==2.5.0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_eb4f669b34ab822163be19325170f1948bdc5301)\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_eb4f669b34ab822163be19325170f1948bdc5301\n..\ncollected 2 items\n\n==================== short test summary info ====================\nPASSED test_1::TestFileXpm::test_load_read\nPASSED test_1::TestFileXpm::test_sanity\n=================== 2 passed in 0.14s ===================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts =============================\nplatform linux -- Python 3.9.21\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_eb4f669b34ab822163be19325170f1948bdc5301\n..\ncollected 2 items\n\n=================================== FAILURES ===================================\n__________ TestFileXpm.test_sanity __________\nTraceback (most recent call last):\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 59, in testPartExecutor\n    yield\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 592, in run\n    self._callTestMethod(testMethod)\n  File \"/home/gcpuser/.local/share/uv/python/cpython-3.9.21-linux-x86_64-gnu/lib/python3.9/unittest/case.py\", line 550, in _callTestMethod\n    method()\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_eb4f669b34ab822163be19325170f1948bdc5301/r2e_tests/test_1.py\", line 19, in test_sanity\n    self.assert_image_similar(im.convert('RGB'), lena('RGB'), 60)\n  File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pillow_eb4f669b34ab822163be19325170f1948bdc5301/r2e_tests/helper.py\", line 97, in assert_image_similar\n    self.assertGreaterEqual(\nAssertionError: 60.0 not greater than or equal to 161.458984375 : average pixel value difference 161.4590 > epsilon 60.0000\n\n==================== short test summary info ====================\nPASSED test_1::TestFileXpm::test_load_read\nFAILED test_1::TestFileXpm::test_sanity\n=================== 1 failed, 1 passed in 0.05s ===================\n",
    "old_commit_res_stderr": ""
}
PIL/ImageFile.py PIL/XpmImagePlugin.py Tests/test_file_xpm.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** XPM Image Loading Results in Scrambled Pixels and High Pixel Difference

**Description:**
When loading XPM images using the Pillow library, the resulting image appears scrambled, leading to significant discrepancies compared to the expected image data.

**Example Buggy Code:**
```python
from PIL import Image

# Attempt to load the XPM image
im = Image.open("Tests/images/lena.xpm")
im.load()

# Convert to RGB and compare with the expected image
converted_im = im.convert('RGB')
expected_im = Image.open("Tests/images/lena_expected.png")

# Calculate average pixel difference
# (Assume calculate_average_pixel_difference is a defined function)
difference = calculate_average_pixel_difference(converted_im, expected_im)
print(f"Average pixel difference: {difference}")
```

**Expected Behavior:**
The XPM image should load correctly, matching the expected RGB image with minimal average pixel difference, indicating accurate image rendering.

**Actual Behavior:**
The loaded XPM image has scrambled pixels, resulting in a high average pixel difference compared to the expected image. This suggests that the image loading process is not handling XPM files properly, leading to corrupted image data.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### PIL/ImageFile.py
#
# The Python Imaging Library.
# $Id$
#
# base class for image file handlers
#
# history:
# 1995-09-09 fl   Created
# 1996-03-11 fl   Fixed load mechanism.
# 1996-04-15 fl   Added pcx/xbm decoders.
# 1996-04-30 fl   Added encoders.
# 1996-12-14 fl   Added load helpers
# 1997-01-11 fl   Use encode_to_file where possible
# 1997-08-27 fl   Flush output in _save
# 1998-03-05 fl   Use memory mapping for some modes
# 1999-02-04 fl   Use memory mapping also for "I;16" and "I;16B"
# 1999-05-31 fl   Added image parser
# 2000-10-12 fl   Set readonly flag on memory-mapped images
# 2002-03-20 fl   Use better messages for common decoder errors
# 2003-04-21 fl   Fall back on mmap/map_buffer if map is not available
# 2003-10-30 fl   Added StubImageFile class
# 2004-02-25 fl   Made incremental parser more robust
#
# Copyright (c) 1997-2004 by Secret Labs AB
# Copyright (c) 1995-2004 by Fredrik Lundh
#
# See the README file for information on usage and redistribution.
#

from PIL import Image
from PIL._util import isPath
import traceback, os, sys
import io

MAXBLOCK = 65536

SAFEBLOCK = 1024*1024

LOAD_TRUNCATED_IMAGES = False

ERRORS = {
    -1: "image buffer overrun error",
    -2: "decoding error",
    -3: "unknown error",
    -8: "bad configuration",
    -9: "out of memory error"
}

def raise_ioerror(error):
    try:
        message = Image.core.getcodecstatus(error)
    except AttributeError:
        message = ERRORS.get(error)
    if not message:
        message = "decoder error %d" % error
    raise IOError(message + " when reading image file")

#
# --------------------------------------------------------------------
# Helpers

def _tilesort(t):
    # sort on offset
    return t[2]

#
# --------------------------------------------------------------------
# ImageFile base class

class ImageFile(Image.Image):
    "Base class for image file format handlers."

    def __init__(self, fp=None, filename=None):
        Image.Image.__init__(self)

        self.tile = None
        self.readonly = 1 # until we know better

        self.decoderconfig = ()
        self.decodermaxblock = MAXBLOCK

        if isPath(fp):
            # filename
            self.fp = open(fp, "rb")
            self.filename = fp
        else:
            # stream
            self.fp = fp
            self.filename = filename

        try:
            self._open()
        except IndexError as v: # end of data
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except TypeError as v: # end of data (ord)
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except KeyError as v: # unsupported mode
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except EOFError as v: # got header but not the first frame
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)

        if not self.mode or self.size[0] <= 0:
            raise SyntaxError("not identified by this driver")

    def draft(self, mode, size):
        "Set draft mode"

        pass

    def verify(self):
        "Check file integrity"

        # raise exception if something's wrong.  must be called
        # directly after open, and closes file when finished.
        self.fp = None

    def load(self):
        "Load image data based on tile list"

        pixel = Image.Image.load(self)

        if self.tile is None:
            raise IOError("cannot load this image")
        if not self.tile:
            return pixel

        self.map = None

        readonly = 0

        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):
            # As of pypy 2.1.0, memory mapping was failing here.
            # try memory mapping
            d, e, o, a = self.tile[0]
            if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
                try:
                    if hasattr(Image.core, "map"):
                        # use built-in mapper
                        self.map = Image.core.map(self.filename)
                        self.map.seek(o)
                        self.im = self.map.readimage(
                            self.mode, self.size, a[1], a[2]
                            )
                    else:
                        # use mmap, if possible
                        import mmap
                        file = open(self.filename, "r+")
                        size = os.path.getsize(self.filename)
                        # FIXME: on Unix, use PROT_READ etc
                        self.map = mmap.mmap(file.fileno(), size)
                        self.im = Image.core.map_buffer(
                            self.map, self.size, d, e, o, a
                            )
                    readonly = 1
                except (AttributeError, EnvironmentError, ImportError):
                    self.map = None

        self.load_prepare()

        # look for read/seek overrides
        try:
            read = self.load_read
        except AttributeError:
            read = self.fp.read

        try:
            seek = self.load_seek
        except AttributeError:
            seek = self.fp.seek

        if not self.map:

            # sort tiles in file order
            self.tile.sort(key=_tilesort)

            try:
                # FIXME: This is a hack to handle TIFF's JpegTables tag.
                prefix = self.tile_prefix
            except AttributeError:
                prefix = b""

            for d, e, o, a in self.tile:
                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
                seek(o)
                try:
                    d.setimage(self.im, e)
                except ValueError:
                    continue
                b = prefix
                t = len(b)
                while True:
                    try:
                        s = read(self.decodermaxblock)
                    except IndexError as ie: # truncated png/gif
                        if LOAD_TRUNCATED_IMAGES:
                            break
                        else:
                            raise IndexError(ie)

                    if not s and not d.handles_eof: # truncated jpeg
                        self.tile = []

                        # JpegDecode needs to clean things up here either way
                        # If we don't destroy the decompressor, we have a memory leak.
                        d.cleanup()

                        if LOAD_TRUNCATED_IMAGES:
                            break
                        else:
                            raise IOError("image file is truncated (%d bytes not processed)" % len(b))

                    b = b + s
                    n, e = d.decode(b)
                    if n < 0:
                        break
                    b = b[n:]
                    t = t + n

        self.tile = []
        self.readonly = readonly

        self.fp = None # might be shared

        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:
            # still raised if decoder fails to return anything
            raise_ioerror(e)

        # post processing
        if hasattr(self, "tile_post_rotate"):
            # FIXME: This is a hack to handle rotated PCD's
            self.im = self.im.rotate(self.tile_post_rotate)
            self.size = self.im.size

        self.load_end()

        return Image.Image.load(self)

    def load_prepare(self):
        # create image memory if necessary
        if not self.im or\
           self.im.mode != self.mode or self.im.size != self.size:
            self.im = Image.core.new(self.mode, self.size)
        # create palette (optional)
        if self.mode == "P":
            Image.Image.load(self)

    def load_end(self):
        # may be overridden
        pass

    # may be defined for contained formats
    # def load_seek(self, pos):
    #     pass

    # may be defined for blocked formats (e.g. PNG)
    # def load_read(self, bytes):
    #     pass


class StubImageFile(ImageFile):
    """
    Base class for stub image loaders.

    A stub loader is an image loader that can identify files of a
    certain format, but relies on external code to load the file.
    """

    def _open(self):
        raise NotImplementedError(
            "StubImageFile subclass must implement _open"
            )

    def load(self):
        loader = self._load()
        if loader is None:
            raise IOError("cannot find loader for this %s file" % self.format)
        image = loader.load(self)
        assert image is not None
        # become the other object (!)
        self.__class__ = image.__class__
        self.__dict__ = image.__dict__

    def _load(self):
        "(Hook) Find actual image loader."
        raise NotImplementedError(
            "StubImageFile subclass must implement _load"
            )


class Parser:
    """
    Incremental image parser.  This class implements the standard
    feed/close consumer interface.

    In Python 2.x, this is an old-style class.
    """
    incremental = None
    image = None
    data = None
    decoder = None
    finished = 0

    def reset(self):
        """
        (Consumer) Reset the parser.  Note that you can only call this
        method immediately after you've created a parser; parser
        instances cannot be reused.
        """
        assert self.data is None, "cannot reuse parsers"

    def feed(self, data):
        """
        (Consumer) Feed data to the parser.

        :param data: A string buffer.
        :exception IOError: If the parser failed to parse the image file.
        """
        # collect data

        if self.finished:
            return

        if self.data is None:
            self.data = data
        else:
            self.data = self.data + data

        # parse what we have
        if self.decoder:

            if self.offset > 0:
                # skip header
                skip = min(len(self.data), self.offset)
                self.data = self.data[skip:]
                self.offset = self.offset - skip
                if self.offset > 0 or not self.data:
                    return

            n, e = self.decoder.decode(self.data)

            if n < 0:
                # end of stream
                self.data = None
                self.finished = 1
                if e < 0:
                    # decoding error
                    self.image = None
                    raise_ioerror(e)
                else:
                    # end of image
                    return
            self.data = self.data[n:]

        elif self.image:

            # if we end up here with no decoder, this file cannot
            # be incrementally parsed.  wait until we've gotten all
            # available data
            pass

        else:

            # attempt to open this file
            try:
                try:
                    fp = io.BytesIO(self.data)
                    im = Image.open(fp)
                finally:
                    fp.close() # explicitly close the virtual file
            except IOError:
                # traceback.print_exc()
                pass # not enough data
            else:
                flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
                if flag or len(im.tile) != 1:
                    # custom load code, or multiple tiles
                    self.decode = None
                else:
                    # initialize decoder
                    im.load_prepare()
                    d, e, o, a = im.tile[0]
                    im.tile = []
                    self.decoder = Image._getdecoder(
                        im.mode, d, a, im.decoderconfig
                        )
                    self.decoder.setimage(im.im, e)

                    # calculate decoder offset
                    self.offset = o
                    if self.offset <= len(self.data):
                        self.data = self.data[self.offset:]
                        self.offset = 0

                self.image = im

    def close(self):
        """
        (Consumer) Close the stream.

        :returns: An image object.
        :exception IOError: If the parser failed to parse the image file either
                            because it cannot be identified or cannot be
                            decoded.
        """
        # finish decoding
        if self.decoder:
            # get rid of what's left in the buffers
            self.feed(b"")
            self.data = self.decoder = None
            if not self.finished:
                raise IOError("image was incomplete")
        if not self.image:
            raise IOError("cannot parse this image")
        if self.data:
            # incremental parsing not possible; reopen the file
            # not that we have all data
            try:
                fp = io.BytesIO(self.data)
                self.image = Image.open(fp)
            finally:
                self.image.load()
                fp.close() # explicitly close the virtual file
        return self.image

# --------------------------------------------------------------------

def _save(im, fp, tile, bufsize=0):
    """Helper to save image based on tile list

    :param im: Image object.
    :param fp: File object.
    :param tile: Tile list.
    :param bufsize: Optional buffer size
    """

    im.load()
    if not hasattr(im, "encoderconfig"):
        im.encoderconfig = ()
    tile.sort(key=_tilesort)
    # FIXME: make MAXBLOCK a configuration parameter
    # It would be great if we could have the encoder specifiy what it needs
    # But, it would need at least the image size in most cases. RawEncode is
    # a tricky case.
    bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c
    try:
        fh = fp.fileno()
        fp.flush()
    except (AttributeError, io.UnsupportedOperation):
        # compress to Python file-compatible object
        for e, b, o, a in tile:
            e = Image._getencoder(im.mode, e, a, im.encoderconfig)
            if o > 0:
                fp.seek(o, 0)
            e.setimage(im.im, b)
            while True:
                l, s, d = e.encode(bufsize)
                fp.write(d)
                if s:
                    break
            if s < 0:
                raise IOError("encoder error %d when writing image file" % s)
    else:
        # slight speedup: compress to real file object
        for e, b, o, a in tile:
            e = Image._getencoder(im.mode, e, a, im.encoderconfig)
            if o > 0:
                fp.seek(o, 0)
            e.setimage(im.im, b)
            s = e.encode_to_file(fh, bufsize)
            if s < 0:
                raise IOError("encoder error %d when writing image file" % s)
    try:
        fp.flush()
    except: pass


def _safe_read(fp, size):
    """
    Reads large blocks in a safe way.  Unlike fp.read(n), this function
    doesn't trust the user.  If the requested size is larger than
    SAFEBLOCK, the file is read block by block.

    :param fp: File handle.  Must implement a <b>read</b> method.
    :param size: Number of bytes to read.
    :returns: A string containing up to <i>size</i> bytes of data.
    """
    if size <= 0:
        return b""
    if size <= SAFEBLOCK:
        return fp.read(size)
    data = []
    while size > 0:
        block = fp.read(min(size, SAFEBLOCK))
        if not block:
            break
        data.append(block)
        size -= len(block)
    return b"".join(data)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]
**Title:** XPM Image Loading Results in Scrambled Pixels and High Pixel Difference

**Description:**
When loading XPM images using the Pillow library, the resulting image appears scrambled, leading to significant discrepancies compared to the expected image data.

**Example Buggy Code:**
```python
from PIL import Image

# Attempt to load the XPM image
im = Image.open("Tests/images/lena.xpm")
im.load()

# Convert to RGB and compare with the expected image
converted_im = im.convert('RGB')
expected_im = Image.open("Tests/images/lena_expected.png")

# Calculate average pixel difference
# (Assume calculate_average_pixel_difference is a defined function)
difference = calculate_average_pixel_difference(converted_im, expected_im)
print(f"Average pixel difference: {difference}")
```

**Expected Behavior:**
The XPM image should load correctly, matching the expected RGB image with minimal average pixel difference, indicating accurate image rendering.

**Actual Behavior:**
The loaded XPM image has scrambled pixels, resulting in a high average pixel difference compared to the expected image. This suggests that the image loading process is not handling XPM files properly, leading to corrupted image data.
[/ISSUE]
{
    "TestFileXpm.test_load_read": "PASSED",
    "TestFileXpm.test_sanity": "PASSED"
}
diff --git a/PIL/ImageFile.py b/PIL/ImageFile.py
index adb27f2bd..5e4745d76 100644
--- a/PIL/ImageFile.py
+++ b/PIL/ImageFile.py
@@ -133,11 +133,27 @@ class ImageFile(Image.Image):
             return pixel
 
         self.map = None
-
+        use_mmap = self.filename and len(self.tile) == 1
+        # As of pypy 2.1.0, memory mapping was failing here.
+        use_mmap = use_mmap and not hasattr(sys, 'pypy_version_info') 
+        
         readonly = 0
 
-        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):
-            # As of pypy 2.1.0, memory mapping was failing here.
+        # look for read/seek overrides
+        try:
+            read = self.load_read
+            # don't use mmap if there are custom read/seek functions
+            use_mmap = False
+        except AttributeError:
+            read = self.fp.read
+
+        try:
+            seek = self.load_seek
+            use_mmap = False
+        except AttributeError:
+            seek = self.fp.seek
+
+        if use_mmap:
             # try memory mapping
             d, e, o, a = self.tile[0]
             if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
@@ -165,19 +181,7 @@ class ImageFile(Image.Image):
 
         self.load_prepare()
 
-        # look for read/seek overrides
-        try:
-            read = self.load_read
-        except AttributeError:
-            read = self.fp.read
-
-        try:
-            seek = self.load_seek
-        except AttributeError:
-            seek = self.fp.seek
-
         if not self.map:
-
             # sort tiles in file order
             self.tile.sort(key=_tilesort)
 
diff --git a/PIL/XpmImagePlugin.py b/PIL/XpmImagePlugin.py
index 701a23b64..517580895 100644
--- a/PIL/XpmImagePlugin.py
+++ b/PIL/XpmImagePlugin.py
@@ -29,6 +29,7 @@ xpm_head = re.compile(b"\"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)")
 def _accept(prefix):
     return prefix[:9] == b"/* XPM */"
 
+
 ##
 # Image plugin for X11 pixel maps.
 
@@ -86,9 +87,9 @@ class XpmImageFile(ImageFile.ImageFile):
                     elif rgb[0:1] == b"#":
                         # FIXME: handle colour names (see ImagePalette.py)
                         rgb = int(rgb[1:], 16)
-                        palette[c] = o8((rgb >> 16) & 255) +\
-                                     o8((rgb >> 8) & 255) +\
-                                     o8(rgb & 255)
+                        palette[c] = (o8((rgb >> 16) & 255) +
+                                      o8((rgb >> 8) & 255) +
+                                      o8(rgb & 255))
                     else:
                         # unknown colour
                         raise ValueError("cannot read this XPM file")

{"PIL/ImageFile.py": "#\n# The Python Imaging Library.\n# $Id$\n#\n# base class for image file handlers\n#\n# history:\n# 1995-09-09 fl   Created\n# 1996-03-11 fl   Fixed load mechanism.\n# 1996-04-15 fl   Added pcx/xbm decoders.\n# 1996-04-30 fl   Added encoders.\n# 1996-12-14 fl   Added load helpers\n# 1997-01-11 fl   Use encode_to_file where possible\n# 1997-08-27 fl   Flush output in _save\n# 1998-03-05 fl   Use memory mapping for some modes\n# 1999-02-04 fl   Use memory mapping also for \"I;16\" and \"I;16B\"\n# 1999-05-31 fl   Added image parser\n# 2000-10-12 fl   Set readonly flag on memory-mapped images\n# 2002-03-20 fl   Use better messages for common decoder errors\n# 2003-04-21 fl   Fall back on mmap/map_buffer if map is not available\n# 2003-10-30 fl   Added StubImageFile class\n# 2004-02-25 fl   Made incremental parser more robust\n#\n# Copyright (c) 1997-2004 by Secret Labs AB\n# Copyright (c) 1995-2004 by Fredrik Lundh\n#\n# See the README file for information on usage and redistribution.\n#\n\nfrom PIL import Image\nfrom PIL._util import isPath\nimport traceback, os, sys\nimport io\n\nMAXBLOCK = 65536\n\nSAFEBLOCK = 1024*1024\n\nLOAD_TRUNCATED_IMAGES = False\n\nERRORS = {\n    -1: \"image buffer overrun error\",\n    -2: \"decoding error\",\n    -3: \"unknown error\",\n    -8: \"bad configuration\",\n    -9: \"out of memory error\"\n}\n\ndef raise_ioerror(error):\n    try:\n        message = Image.core.getcodecstatus(error)\n    except AttributeError:\n        message = ERRORS.get(error)\n    if not message:\n        message = \"decoder error %d\" % error\n    raise IOError(message + \" when reading image file\")\n\n#\n# --------------------------------------------------------------------\n# Helpers\n\ndef _tilesort(t):\n    # sort on offset\n    return t[2]\n\n#\n# --------------------------------------------------------------------\n# ImageFile base class\n\nclass ImageFile(Image.Image):\n    \"Base class for image file format handlers.\"\n\n    def __init__(self, fp=None, filename=None):\n        Image.Image.__init__(self)\n\n        self.tile = None\n        self.readonly = 1 # until we know better\n\n        self.decoderconfig = ()\n        self.decodermaxblock = MAXBLOCK\n\n        if isPath(fp):\n            # filename\n            self.fp = open(fp, \"rb\")\n            self.filename = fp\n        else:\n            # stream\n            self.fp = fp\n            self.filename = filename\n\n        try:\n            self._open()\n        except IndexError as v: # end of data\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except TypeError as v: # end of data (ord)\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except KeyError as v: # unsupported mode\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n        except EOFError as v: # got header but not the first frame\n            if Image.DEBUG > 1:\n                traceback.print_exc()\n            raise SyntaxError(v)\n\n        if not self.mode or self.size[0] <= 0:\n            raise SyntaxError(\"not identified by this driver\")\n\n    def draft(self, mode, size):\n        \"Set draft mode\"\n\n        pass\n\n    def verify(self):\n        \"Check file integrity\"\n\n        # raise exception if something's wrong.  must be called\n        # directly after open, and closes file when finished.\n        self.fp = None\n\n    def load(self):\n        \"Load image data based on tile list\"\n\n        pixel = Image.Image.load(self)\n\n        if self.tile is None:\n            raise IOError(\"cannot load this image\")\n        if not self.tile:\n            return pixel\n\n        self.map = None\n\n        readonly = 0\n\n        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):\n            # As of pypy 2.1.0, memory mapping was failing here.\n            # try memory mapping\n            d, e, o, a = self.tile[0]\n            if d == \"raw\" and a[0] == self.mode and a[0] in Image._MAPMODES:\n                try:\n                    if hasattr(Image.core, \"map\"):\n                        # use built-in mapper\n                        self.map = Image.core.map(self.filename)\n                        self.map.seek(o)\n                        self.im = self.map.readimage(\n                            self.mode, self.size, a[1], a[2]\n                            )\n                    else:\n                        # use mmap, if possible\n                        import mmap\n                        file = open(self.filename, \"r+\")\n                        size = os.path.getsize(self.filename)\n                        # FIXME: on Unix, use PROT_READ etc\n                        self.map = mmap.mmap(file.fileno(), size)\n                        self.im = Image.core.map_buffer(\n                            self.map, self.size, d, e, o, a\n                            )\n                    readonly = 1\n                except (AttributeError, EnvironmentError, ImportError):\n                    self.map = None\n\n        self.load_prepare()\n\n        # look for read/seek overrides\n        try:\n            read = self.load_read\n        except AttributeError:\n            read = self.fp.read\n\n        try:\n            seek = self.load_seek\n        except AttributeError:\n            seek = self.fp.seek\n\n        if not self.map:\n\n            # sort tiles in file order\n            self.tile.sort(key=_tilesort)\n\n            try:\n                # FIXME: This is a hack to handle TIFF's JpegTables tag.\n                prefix = self.tile_prefix\n            except AttributeError:\n                prefix = b\"\"\n\n            for d, e, o, a in self.tile:\n                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)\n                seek(o)\n                try:\n                    d.setimage(self.im, e)\n                except ValueError:\n                    continue\n                b = prefix\n                t = len(b)\n                while True:\n                    try:\n                        s = read(self.decodermaxblock)\n                    except IndexError as ie: # truncated png/gif\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IndexError(ie)\n\n                    if not s and not d.handles_eof: # truncated jpeg\n                        self.tile = []\n\n                        # JpegDecode needs to clean things up here either way\n                        # If we don't destroy the decompressor, we have a memory leak.\n                        d.cleanup()\n\n                        if LOAD_TRUNCATED_IMAGES:\n                            break\n                        else:\n                            raise IOError(\"image file is truncated (%d bytes not processed)\" % len(b))\n\n                    b = b + s\n                    n, e = d.decode(b)\n                    if n < 0:\n                        break\n                    b = b[n:]\n                    t = t + n\n\n        self.tile = []\n        self.readonly = readonly\n\n        self.fp = None # might be shared\n\n        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:\n            # still raised if decoder fails to return anything\n            raise_ioerror(e)\n\n        # post processing\n        if hasattr(self, \"tile_post_rotate\"):\n            # FIXME: This is a hack to handle rotated PCD's\n            self.im = self.im.rotate(self.tile_post_rotate)\n            self.size = self.im.size\n\n        self.load_end()\n\n        return Image.Image.load(self)\n\n    def load_prepare(self):\n        # create image memory if necessary\n        if not self.im or\\\n           self.im.mode != self.mode or self.im.size != self.size:\n            self.im = Image.core.new(self.mode, self.size)\n        # create palette (optional)\n        if self.mode == \"P\":\n            Image.Image.load(self)\n\n    def load_end(self):\n        # may be overridden\n        pass\n\n    # may be defined for contained formats\n    # def load_seek(self, pos):\n    #     pass\n\n    # may be defined for blocked formats (e.g. PNG)\n    # def load_read(self, bytes):\n    #     pass\n\n\nclass StubImageFile(ImageFile):\n    \"\"\"\n    Base class for stub image loaders.\n\n    A stub loader is an image loader that can identify files of a\n    certain format, but relies on external code to load the file.\n    \"\"\"\n\n    def _open(self):\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _open\"\n            )\n\n    def load(self):\n        loader = self._load()\n        if loader is None:\n            raise IOError(\"cannot find loader for this %s file\" % self.format)\n        image = loader.load(self)\n        assert image is not None\n        # become the other object (!)\n        self.__class__ = image.__class__\n        self.__dict__ = image.__dict__\n\n    def _load(self):\n        \"(Hook) Find actual image loader.\"\n        raise NotImplementedError(\n            \"StubImageFile subclass must implement _load\"\n            )\n\n\nclass Parser:\n    \"\"\"\n    Incremental image parser.  This class implements the standard\n    feed/close consumer interface.\n\n    In Python 2.x, this is an old-style class.\n    \"\"\"\n    incremental = None\n    image = None\n    data = None\n    decoder = None\n    finished = 0\n\n    def reset(self):\n        \"\"\"\n        (Consumer) Reset the parser.  Note that you can only call this\n        method immediately after you've created a parser; parser\n        instances cannot be reused.\n        \"\"\"\n        assert self.data is None, \"cannot reuse parsers\"\n\n    def feed(self, data):\n        \"\"\"\n        (Consumer) Feed data to the parser.\n\n        :param data: A string buffer.\n        :exception IOError: If the parser failed to parse the image file.\n        \"\"\"\n        # collect data\n\n        if self.finished:\n            return\n\n        if self.data is None:\n            self.data = data\n        else:\n            self.data = self.data + data\n\n        # parse what we have\n        if self.decoder:\n\n            if self.offset > 0:\n                # skip header\n                skip = min(len(self.data), self.offset)\n                self.data = self.data[skip:]\n                self.offset = self.offset - skip\n                if self.offset > 0 or not self.data:\n                    return\n\n            n, e = self.decoder.decode(self.data)\n\n            if n < 0:\n                # end of stream\n                self.data = None\n                self.finished = 1\n                if e < 0:\n                    # decoding error\n                    self.image = None\n                    raise_ioerror(e)\n                else:\n                    # end of image\n                    return\n            self.data = self.data[n:]\n\n        elif self.image:\n\n            # if we end up here with no decoder, this file cannot\n            # be incrementally parsed.  wait until we've gotten all\n            # available data\n            pass\n\n        else:\n\n            # attempt to open this file\n            try:\n                try:\n                    fp = io.BytesIO(self.data)\n                    im = Image.open(fp)\n                finally:\n                    fp.close() # explicitly close the virtual file\n            except IOError:\n                # traceback.print_exc()\n                pass # not enough data\n            else:\n                flag = hasattr(im, \"load_seek\") or hasattr(im, \"load_read\")\n                if flag or len(im.tile) != 1:\n                    # custom load code, or multiple tiles\n                    self.decode = None\n                else:\n                    # initialize decoder\n                    im.load_prepare()\n                    d, e, o, a = im.tile[0]\n                    im.tile = []\n                    self.decoder = Image._getdecoder(\n                        im.mode, d, a, im.decoderconfig\n                        )\n                    self.decoder.setimage(im.im, e)\n\n                    # calculate decoder offset\n                    self.offset = o\n                    if self.offset <= len(self.data):\n                        self.data = self.data[self.offset:]\n                        self.offset = 0\n\n                self.image = im\n\n    def close(self):\n        \"\"\"\n        (Consumer) Close the stream.\n\n        :returns: An image object.\n        :exception IOError: If the parser failed to parse the image file either\n                            because it cannot be identified or cannot be\n                            decoded.\n        \"\"\"\n        # finish decoding\n        if self.decoder:\n            # get rid of what's left in the buffers\n            self.feed(b\"\")\n            self.data = self.decoder = None\n            if not self.finished:\n                raise IOError(\"image was incomplete\")\n        if not self.image:\n            raise IOError(\"cannot parse this image\")\n        if self.data:\n            # incremental parsing not possible; reopen the file\n            # not that we have all data\n            try:\n                fp = io.BytesIO(self.data)\n                self.image = Image.open(fp)\n            finally:\n                self.image.load()\n                fp.close() # explicitly close the virtual file\n        return self.image\n\n# --------------------------------------------------------------------\n\ndef _save(im, fp, tile, bufsize=0):\n    \"\"\"Helper to save image based on tile list\n\n    :param im: Image object.\n    :param fp: File object.\n    :param tile: Tile list.\n    :param bufsize: Optional buffer size\n    \"\"\"\n\n    im.load()\n    if not hasattr(im, \"encoderconfig\"):\n        im.encoderconfig = ()\n    tile.sort(key=_tilesort)\n    # FIXME: make MAXBLOCK a configuration parameter\n    # It would be great if we could have the encoder specifiy what it needs\n    # But, it would need at least the image size in most cases. RawEncode is\n    # a tricky case.\n    bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c\n    try:\n        fh = fp.fileno()\n        fp.flush()\n    except (AttributeError, io.UnsupportedOperation):\n        # compress to Python file-compatible object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            while True:\n                l, s, d = e.encode(bufsize)\n                fp.write(d)\n                if s:\n                    break\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    else:\n        # slight speedup: compress to real file object\n        for e, b, o, a in tile:\n            e = Image._getencoder(im.mode, e, a, im.encoderconfig)\n            if o > 0:\n                fp.seek(o, 0)\n            e.setimage(im.im, b)\n            s = e.encode_to_file(fh, bufsize)\n            if s < 0:\n                raise IOError(\"encoder error %d when writing image file\" % s)\n    try:\n        fp.flush()\n    except: pass\n\n\ndef _safe_read(fp, size):\n    \"\"\"\n    Reads large blocks in a safe way.  Unlike fp.read(n), this function\n    doesn't trust the user.  If the requested size is larger than\n    SAFEBLOCK, the file is read block by block.\n\n    :param fp: File handle.  Must implement a <b>read</b> method.\n    :param size: Number of bytes to read.\n    :returns: A string containing up to <i>size</i> bytes of data.\n    \"\"\"\n    if size <= 0:\n        return b\"\"\n    if size <= SAFEBLOCK:\n        return fp.read(size)\n    data = []\n    while size > 0:\n        block = fp.read(min(size, SAFEBLOCK))\n        if not block:\n            break\n        data.append(block)\n        size -= len(block)\n    return b\"\".join(data)\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** XPM Image Loading Results in Scrambled Pixels and High Pixel Difference

**Description:**
When loading XPM images using the Pillow library, the resulting image appears scrambled, leading to significant discrepancies compared to the expected image data.

**Example Buggy Code:**
```python
from PIL import Image

# Attempt to load the XPM image
im = Image.open("Tests/images/lena.xpm")
im.load()

# Convert to RGB and compare with the expected image
converted_im = im.convert('RGB')
expected_im = Image.open("Tests/images/lena_expected.png")

# Calculate average pixel difference
# (Assume calculate_average_pixel_difference is a defined function)
difference = calculate_average_pixel_difference(converted_im, expected_im)
print(f"Average pixel difference: {difference}")
```

**Expected Behavior:**
The XPM image should load correctly, matching the expected RGB image with minimal average pixel difference, indicating accurate image rendering.

**Actual Behavior:**
The loaded XPM image has scrambled pixels, resulting in a high average pixel difference compared to the expected image. This suggests that the image loading process is not handling XPM files properly, leading to corrupted image data.
[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### PIL/ImageFile.py
#
# The Python Imaging Library.
# $Id$
#
# base class for image file handlers
#
# history:
# 1995-09-09 fl   Created
# 1996-03-11 fl   Fixed load mechanism.
# 1996-04-15 fl   Added pcx/xbm decoders.
# 1996-04-30 fl   Added encoders.
# 1996-12-14 fl   Added load helpers
# 1997-01-11 fl   Use encode_to_file where possible
# 1997-08-27 fl   Flush output in _save
# 1998-03-05 fl   Use memory mapping for some modes
# 1999-02-04 fl   Use memory mapping also for "I;16" and "I;16B"
# 1999-05-31 fl   Added image parser
# 2000-10-12 fl   Set readonly flag on memory-mapped images
# 2002-03-20 fl   Use better messages for common decoder errors
# 2003-04-21 fl   Fall back on mmap/map_buffer if map is not available
# 2003-10-30 fl   Added StubImageFile class
# 2004-02-25 fl   Made incremental parser more robust
#
# Copyright (c) 1997-2004 by Secret Labs AB
# Copyright (c) 1995-2004 by Fredrik Lundh
#
# See the README file for information on usage and redistribution.
#

from PIL import Image
from PIL._util import isPath
import traceback, os, sys
import io

MAXBLOCK = 65536

SAFEBLOCK = 1024*1024

LOAD_TRUNCATED_IMAGES = False

ERRORS = {
    -1: "image buffer overrun error",
    -2: "decoding error",
    -3: "unknown error",
    -8: "bad configuration",
    -9: "out of memory error"
}

def raise_ioerror(error):
    try:
        message = Image.core.getcodecstatus(error)
    except AttributeError:
        message = ERRORS.get(error)
    if not message:
        message = "decoder error %d" % error
    raise IOError(message + " when reading image file")

#
# --------------------------------------------------------------------
# Helpers

def _tilesort(t):
    # sort on offset
    return t[2]

#
# --------------------------------------------------------------------
# ImageFile base class

class ImageFile(Image.Image):
    "Base class for image file format handlers."

    def __init__(self, fp=None, filename=None):
        Image.Image.__init__(self)

        self.tile = None
        self.readonly = 1 # until we know better

        self.decoderconfig = ()
        self.decodermaxblock = MAXBLOCK

        if isPath(fp):
            # filename
            self.fp = open(fp, "rb")
            self.filename = fp
        else:
            # stream
            self.fp = fp
            self.filename = filename

        try:
            self._open()
        except IndexError as v: # end of data
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except TypeError as v: # end of data (ord)
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except KeyError as v: # unsupported mode
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)
        except EOFError as v: # got header but not the first frame
            if Image.DEBUG > 1:
                traceback.print_exc()
            raise SyntaxError(v)

        if not self.mode or self.size[0] <= 0:
            raise SyntaxError("not identified by this driver")

    def draft(self, mode, size):
        "Set draft mode"

        pass

    def verify(self):
        "Check file integrity"

        # raise exception if something's wrong.  must be called
        # directly after open, and closes file when finished.
        self.fp = None

    def load(self):
        "Load image data based on tile list"

        pixel = Image.Image.load(self)

        if self.tile is None:
            raise IOError("cannot load this image")
        if not self.tile:
            return pixel

        self.map = None

        readonly = 0

        if self.filename and len(self.tile) == 1 and not hasattr(sys, 'pypy_version_info'):
            # As of pypy 2.1.0, memory mapping was failing here.
            # try memory mapping
            d, e, o, a = self.tile[0]
            if d == "raw" and a[0] == self.mode and a[0] in Image._MAPMODES:
                try:
                    if hasattr(Image.core, "map"):
                        # use built-in mapper
                        self.map = Image.core.map(self.filename)
                        self.map.seek(o)
                        self.im = self.map.readimage(
                            self.mode, self.size, a[1], a[2]
                            )
                    else:
                        # use mmap, if possible
                        import mmap
                        file = open(self.filename, "r+")
                        size = os.path.getsize(self.filename)
                        # FIXME: on Unix, use PROT_READ etc
                        self.map = mmap.mmap(file.fileno(), size)
                        self.im = Image.core.map_buffer(
                            self.map, self.size, d, e, o, a
                            )
                    readonly = 1
                except (AttributeError, EnvironmentError, ImportError):
                    self.map = None

        self.load_prepare()

        # look for read/seek overrides
        try:
            read = self.load_read
        except AttributeError:
            read = self.fp.read

        try:
            seek = self.load_seek
        except AttributeError:
            seek = self.fp.seek

        if not self.map:

            # sort tiles in file order
            self.tile.sort(key=_tilesort)

            try:
                # FIXME: This is a hack to handle TIFF's JpegTables tag.
                prefix = self.tile_prefix
            except AttributeError:
                prefix = b""

            for d, e, o, a in self.tile:
                d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
                seek(o)
                try:
                    d.setimage(self.im, e)
                except ValueError:
                    continue
                b = prefix
                t = len(b)
                while True:
                    try:
                        s = read(self.decodermaxblock)
                    except IndexError as ie: # truncated png/gif
                        if LOAD_TRUNCATED_IMAGES:
                            break
                        else:
                            raise IndexError(ie)

                    if not s and not d.handles_eof: # truncated jpeg
                        self.tile = []

                        # JpegDecode needs to clean things up here either way
                        # If we don't destroy the decompressor, we have a memory leak.
                        d.cleanup()

                        if LOAD_TRUNCATED_IMAGES:
                            break
                        else:
                            raise IOError("image file is truncated (%d bytes not processed)" % len(b))

                    b = b + s
                    n, e = d.decode(b)
                    if n < 0:
                        break
                    b = b[n:]
                    t = t + n

        self.tile = []
        self.readonly = readonly

        self.fp = None # might be shared

        if not self.map and (not LOAD_TRUNCATED_IMAGES or t == 0) and e < 0:
            # still raised if decoder fails to return anything
            raise_ioerror(e)

        # post processing
        if hasattr(self, "tile_post_rotate"):
            # FIXME: This is a hack to handle rotated PCD's
            self.im = self.im.rotate(self.tile_post_rotate)
            self.size = self.im.size

        self.load_end()

        return Image.Image.load(self)

    def load_prepare(self):
        # create image memory if necessary
        if not self.im or\
           self.im.mode != self.mode or self.im.size != self.size:
            self.im = Image.core.new(self.mode, self.size)
        # create palette (optional)
        if self.mode == "P":
            Image.Image.load(self)

    def load_end(self):
        # may be overridden
        pass

    # may be defined for contained formats
    # def load_seek(self, pos):
    #     pass

    # may be defined for blocked formats (e.g. PNG)
    # def load_read(self, bytes):
    #     pass


class StubImageFile(ImageFile):
    """
    Base class for stub image loaders.

    A stub loader is an image loader that can identify files of a
    certain format, but relies on external code to load the file.
    """

    def _open(self):
        raise NotImplementedError(
            "StubImageFile subclass must implement _open"
            )

    def load(self):
        loader = self._load()
        if loader is None:
            raise IOError("cannot find loader for this %s file" % self.format)
        image = loader.load(self)
        assert image is not None
        # become the other object (!)
        self.__class__ = image.__class__
        self.__dict__ = image.__dict__

    def _load(self):
        "(Hook) Find actual image loader."
        raise NotImplementedError(
            "StubImageFile subclass must implement _load"
            )


class Parser:
    """
    Incremental image parser.  This class implements the standard
    feed/close consumer interface.

    In Python 2.x, this is an old-style class.
    """
    incremental = None
    image = None
    data = None
    decoder = None
    finished = 0

    def reset(self):
        """
        (Consumer) Reset the parser.  Note that you can only call this
        method immediately after you've created a parser; parser
        instances cannot be reused.
        """
        assert self.data is None, "cannot reuse parsers"

    def feed(self, data):
        """
        (Consumer) Feed data to the parser.

        :param data: A string buffer.
        :exception IOError: If the parser failed to parse the image file.
        """
        # collect data

        if self.finished:
            return

        if self.data is None:
            self.data = data
        else:
            self.data = self.data + data

        # parse what we have
        if self.decoder:

            if self.offset > 0:
                # skip header
                skip = min(len(self.data), self.offset)
                self.data = self.data[skip:]
                self.offset = self.offset - skip
                if self.offset > 0 or not self.data:
                    return

            n, e = self.decoder.decode(self.data)

            if n < 0:
                # end of stream
                self.data = None
                self.finished = 1
                if e < 0:
                    # decoding error
                    self.image = None
                    raise_ioerror(e)
                else:
                    # end of image
                    return
            self.data = self.data[n:]

        elif self.image:

            # if we end up here with no decoder, this file cannot
            # be incrementally parsed.  wait until we've gotten all
            # available data
            pass

        else:

            # attempt to open this file
            try:
                try:
                    fp = io.BytesIO(self.data)
                    im = Image.open(fp)
                finally:
                    fp.close() # explicitly close the virtual file
            except IOError:
                # traceback.print_exc()
                pass # not enough data
            else:
                flag = hasattr(im, "load_seek") or hasattr(im, "load_read")
                if flag or len(im.tile) != 1:
                    # custom load code, or multiple tiles
                    self.decode = None
                else:
                    # initialize decoder
                    im.load_prepare()
                    d, e, o, a = im.tile[0]
                    im.tile = []
                    self.decoder = Image._getdecoder(
                        im.mode, d, a, im.decoderconfig
                        )
                    self.decoder.setimage(im.im, e)

                    # calculate decoder offset
                    self.offset = o
                    if self.offset <= len(self.data):
                        self.data = self.data[self.offset:]
                        self.offset = 0

                self.image = im

    def close(self):
        """
        (Consumer) Close the stream.

        :returns: An image object.
        :exception IOError: If the parser failed to parse the image file either
                            because it cannot be identified or cannot be
                            decoded.
        """
        # finish decoding
        if self.decoder:
            # get rid of what's left in the buffers
            self.feed(b"")
            self.data = self.decoder = None
            if not self.finished:
                raise IOError("image was incomplete")
        if not self.image:
            raise IOError("cannot parse this image")
        if self.data:
            # incremental parsing not possible; reopen the file
            # not that we have all data
            try:
                fp = io.BytesIO(self.data)
                self.image = Image.open(fp)
            finally:
                self.image.load()
                fp.close() # explicitly close the virtual file
        return self.image

# --------------------------------------------------------------------

def _save(im, fp, tile, bufsize=0):
    """Helper to save image based on tile list

    :param im: Image object.
    :param fp: File object.
    :param tile: Tile list.
    :param bufsize: Optional buffer size
    """

    im.load()
    if not hasattr(im, "encoderconfig"):
        im.encoderconfig = ()
    tile.sort(key=_tilesort)
    # FIXME: make MAXBLOCK a configuration parameter
    # It would be great if we could have the encoder specifiy what it needs
    # But, it would need at least the image size in most cases. RawEncode is
    # a tricky case.
    bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c
    try:
        fh = fp.fileno()
        fp.flush()
    except (AttributeError, io.UnsupportedOperation):
        # compress to Python file-compatible object
        for e, b, o, a in tile:
            e = Image._getencoder(im.mode, e, a, im.encoderconfig)
            if o > 0:
                fp.seek(o, 0)
            e.setimage(im.im, b)
            while True:
                l, s, d = e.encode(bufsize)
                fp.write(d)
                if s:
                    break
            if s < 0:
                raise IOError("encoder error %d when writing image file" % s)
    else:
        # slight speedup: compress to real file object
        for e, b, o, a in tile:
            e = Image._getencoder(im.mode, e, a, im.encoderconfig)
            if o > 0:
                fp.seek(o, 0)
            e.setimage(im.im, b)
            s = e.encode_to_file(fh, bufsize)
            if s < 0:
                raise IOError("encoder error %d when writing image file" % s)
    try:
        fp.flush()
    except: pass


def _safe_read(fp, size):
    """
    Reads large blocks in a safe way.  Unlike fp.read(n), this function
    doesn't trust the user.  If the requested size is larger than
    SAFEBLOCK, the file is read block by block.

    :param fp: File handle.  Must implement a <b>read</b> method.
    :param size: Number of bytes to read.
    :returns: A string containing up to <i>size</i> bytes of data.
    """
    if size <= 0:
        return b""
    if size <= SAFEBLOCK:
        return fp.read(size)
    data = []
    while size > 0:
        block = fp.read(min(size, SAFEBLOCK))
        if not block:
            break
        data.append(block)
        size -= len(block)
    return b"".join(data)

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user