We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
No n_frames, or bad value for n_frames
When I feed the test file  flower2.jpg  into this code (from #1630)

```python
im = Image.open( fn )
imgcnt = im.n_frames
colors = im.getcolors( im.width * im.height )
if args.hist:
    for cnt, col in colors:
        allcolors[ col ] += cnt
    for iz in range( 1, imgcnt ):
        im = Image.open( fn ) # does getcolors implicitly close????
                              # without the open, get "seek of closed
                              # file" error on line below.
        im.seek( iz )
        colors = im.getcolors( im.width * im.height )
        for cnt, col in colors:
            allcolors[ col ] += cnt
```

I get "AttributeError: n_frames"

But other .jpg files do not get that error... this one: http://nevcal.com/temporary/20151110-105826gl.jpg has no problem with the attribute error on that line, but it gets a value of 2, apparently handles the seek OK, but dies in the second call to getcolors, with "OSError: image file is truncated (0 bytes not processed)".


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/PIL/MpoImagePlugin.py`
Content:
```
1 #
2 # The Python Imaging Library.
3 # $Id$
4 #
5 # MPO file handling
6 #
7 # See "Multi-Picture Format" (CIPA DC-007-Translation 2009, Standard of the
8 # Camera & Imaging Products Association)
9 #
10 # The multi-picture object combines multiple JPEG images (with a modified EXIF
11 # data format) into a single file. While it can theoretically be used much like
12 # a GIF animation, it is commonly used to represent 3D photographs and is (as
13 # of this writing) the most commonly used format by 3D cameras.
14 #
15 # History:
16 # 2014-03-13 Feneric   Created
17 #
18 # See the README file for information on usage and redistribution.
19 #
20 
21 from . import Image, JpegImagePlugin
22 
23 # __version__ is deprecated and will be removed in a future version. Use
24 # PIL.__version__ instead.
25 __version__ = "0.1"
26 
27 
28 def _accept(prefix):
29     return JpegImagePlugin._accept(prefix)
30 
31 
32 def _save(im, fp, filename):
33     # Note that we can only save the current frame at present
34     return JpegImagePlugin._save(im, fp, filename)
35 
36 
37 ##
38 # Image plugin for MPO images.
39 
40 class MpoImageFile(JpegImagePlugin.JpegImageFile):
41 
42     format = "MPO"
43     format_description = "MPO (CIPA DC-007)"
44     _close_exclusive_fp_after_loading = False
45 
46     def _open(self):
47         self.fp.seek(0)  # prep the fp in order to pass the JPEG test
48         JpegImagePlugin.JpegImageFile._open(self)
49         self.mpinfo = self._getmp()
50         self.__framecount = self.mpinfo[0xB001]
51         self.__mpoffsets = [mpent['DataOffset'] + self.info['mpoffset']
52                             for mpent in self.mpinfo[0xB002]]
53         self.__mpoffsets[0] = 0
54         # Note that the following assertion will only be invalid if something
55         # gets broken within JpegImagePlugin.
56         assert self.__framecount == len(self.__mpoffsets)
57         del self.info['mpoffset']  # no longer needed
58         self.__fp = self.fp  # FIXME: hack
59         self.__fp.seek(self.__mpoffsets[0])  # get ready to read first frame
60         self.__frame = 0
61         self.offset = 0
62         # for now we can only handle reading and individual frame extraction
63         self.readonly = 1
64 
65     def load_seek(self, pos):
66         self.__fp.seek(pos)
67 
68     @property
69     def n_frames(self):
70         return self.__framecount
71 
72     @property
73     def is_animated(self):
74         return self.__framecount > 1
75 
76     def seek(self, frame):
77         if not self._seek_check(frame):
78             return
79         self.fp = self.__fp
80         self.offset = self.__mpoffsets[frame]
81         self.tile = [
82             ("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))
83         ]
84         self.__frame = frame
85 
86     def tell(self):
87         return self.__frame
88 
89     def _close__fp(self):
90         try:
91             if self.__fp != self.fp:
92                 self.__fp.close()
93         except AttributeError:
94             pass
95         finally:
96             self.__fp = None
97 
98 
99 # ---------------------------------------------------------------------
100 # Registry stuff
101 
102 # Note that since MPO shares a factory with JPEG, we do not need to do a
103 # separate registration for it here.
104 # Image.register_open(MpoImageFile.format,
105 #                     JpegImagePlugin.jpeg_factory, _accept)
106 Image.register_save(MpoImageFile.format, _save)
107 
108 Image.register_extension(MpoImageFile.format, ".mpo")
109 
110 Image.register_mime(MpoImageFile.format, "image/mpo")
111
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py
--- a/src/PIL/MpoImagePlugin.py
+++ b/src/PIL/MpoImagePlugin.py
@@ -18,7 +18,8 @@
 # See the README file for information on usage and redistribution.
 #
 
-from . import Image, JpegImagePlugin
+from . import Image, ImageFile, JpegImagePlugin
+from ._binary import i16be as i16
 
 # __version__ is deprecated and will be removed in a future version. Use
 # PIL.__version__ instead.
@@ -78,6 +79,20 @@
             return
         self.fp = self.__fp
         self.offset = self.__mpoffsets[frame]
+
+        self.fp.seek(self.offset + 2)  # skip SOI marker
+        if "parsed_exif" in self.info:
+            del self.info["parsed_exif"]
+        if i16(self.fp.read(2)) == 0xFFE1:  # APP1
+            n = i16(self.fp.read(2))-2
+            self.info["exif"] = ImageFile._safe_read(self.fp, n)
+
+            exif = self._getexif()
+            if 40962 in exif and 40963 in exif:
+                self._size = (exif[40962], exif[40963])
+        elif "exif" in self.info:
+            del self.info["exif"]
+
         self.tile = [
             ("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))
         ]

{"golden_diff": "diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py\n--- a/src/PIL/MpoImagePlugin.py\n+++ b/src/PIL/MpoImagePlugin.py\n@@ -18,7 +18,8 @@\n # See the README file for information on usage and redistribution.\n #\n \n-from . import Image, JpegImagePlugin\n+from . import Image, ImageFile, JpegImagePlugin\n+from ._binary import i16be as i16\n \n # __version__ is deprecated and will be removed in a future version. Use\n # PIL.__version__ instead.\n@@ -78,6 +79,20 @@\n             return\n         self.fp = self.__fp\n         self.offset = self.__mpoffsets[frame]\n+\n+        self.fp.seek(self.offset + 2)  # skip SOI marker\n+        if \"parsed_exif\" in self.info:\n+            del self.info[\"parsed_exif\"]\n+        if i16(self.fp.read(2)) == 0xFFE1:  # APP1\n+            n = i16(self.fp.read(2))-2\n+            self.info[\"exif\"] = ImageFile._safe_read(self.fp, n)\n+\n+            exif = self._getexif()\n+            if 40962 in exif and 40963 in exif:\n+                self._size = (exif[40962], exif[40963])\n+        elif \"exif\" in self.info:\n+            del self.info[\"exif\"]\n+\n         self.tile = [\n             (\"jpeg\", (0, 0) + self.size, self.offset, (self.mode, \"\"))\n         ]\n", "issue": "No n_frames, or bad value for n_frames\nWhen I feed the test file  flower2.jpg  into this code (from #1630)\r\n\r\n```python\r\nim = Image.open( fn )\r\nimgcnt = im.n_frames\r\ncolors = im.getcolors( im.width * im.height )\r\nif args.hist:\r\n    for cnt, col in colors:\r\n        allcolors[ col ] += cnt\r\n    for iz in range( 1, imgcnt ):\r\n        im = Image.open( fn ) # does getcolors implicitly close????\r\n                              # without the open, get \"seek of closed\r\n                              # file\" error on line below.\r\n        im.seek( iz )\r\n        colors = im.getcolors( im.width * im.height )\r\n        for cnt, col in colors:\r\n            allcolors[ col ] += cnt\r\n```\r\n\r\nI get \"AttributeError: n_frames\"\r\n\r\nBut other .jpg files do not get that error... this one: http://nevcal.com/temporary/20151110-105826gl.jpg has no problem with the attribute error on that line, but it gets a value of 2, apparently handles the seek OK, but dies in the second call to getcolors, with \"OSError: image file is truncated (0 bytes not processed)\".\r\n\n", "before_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# MPO file handling\n#\n# See \"Multi-Picture Format\" (CIPA DC-007-Translation 2009, Standard of the\n# Camera & Imaging Products Association)\n#\n# The multi-picture object combines multiple JPEG images (with a modified EXIF\n# data format) into a single file. While it can theoretically be used much like\n# a GIF animation, it is commonly used to represent 3D photographs and is (as\n# of this writing) the most commonly used format by 3D cameras.\n#\n# History:\n# 2014-03-13 Feneric   Created\n#\n# See the README file for information on usage and redistribution.\n#\n\nfrom . import Image, JpegImagePlugin\n\n# __version__ is deprecated and will be removed in a future version. Use\n# PIL.__version__ instead.\n__version__ = \"0.1\"\n\n\ndef _accept(prefix):\n    return JpegImagePlugin._accept(prefix)\n\n\ndef _save(im, fp, filename):\n    # Note that we can only save the current frame at present\n    return JpegImagePlugin._save(im, fp, filename)\n\n\n##\n# Image plugin for MPO images.\n\nclass MpoImageFile(JpegImagePlugin.JpegImageFile):\n\n    format = \"MPO\"\n    format_description = \"MPO (CIPA DC-007)\"\n    _close_exclusive_fp_after_loading = False\n\n    def _open(self):\n        self.fp.seek(0)  # prep the fp in order to pass the JPEG test\n        JpegImagePlugin.JpegImageFile._open(self)\n        self.mpinfo = self._getmp()\n        self.__framecount = self.mpinfo[0xB001]\n        self.__mpoffsets = [mpent['DataOffset'] + self.info['mpoffset']\n                            for mpent in self.mpinfo[0xB002]]\n        self.__mpoffsets[0] = 0\n        # Note that the following assertion will only be invalid if something\n        # gets broken within JpegImagePlugin.\n        assert self.__framecount == len(self.__mpoffsets)\n        del self.info['mpoffset']  # no longer needed\n        self.__fp = self.fp  # FIXME: hack\n        self.__fp.seek(self.__mpoffsets[0])  # get ready to read first frame\n        self.__frame = 0\n        self.offset = 0\n        # for now we can only handle reading and individual frame extraction\n        self.readonly = 1\n\n    def load_seek(self, pos):\n        self.__fp.seek(pos)\n\n    @property\n    def n_frames(self):\n        return self.__framecount\n\n    @property\n    def is_animated(self):\n        return self.__framecount > 1\n\n    def seek(self, frame):\n        if not self._seek_check(frame):\n            return\n        self.fp = self.__fp\n        self.offset = self.__mpoffsets[frame]\n        self.tile = [\n            (\"jpeg\", (0, 0) + self.size, self.offset, (self.mode, \"\"))\n        ]\n        self.__frame = frame\n\n    def tell(self):\n        return self.__frame\n\n    def _close__fp(self):\n        try:\n            if self.__fp != self.fp:\n                self.__fp.close()\n        except AttributeError:\n            pass\n        finally:\n            self.__fp = None\n\n\n# ---------------------------------------------------------------------\n# Registry stuff\n\n# Note that since MPO shares a factory with JPEG, we do not need to do a\n# separate registration for it here.\n# Image.register_open(MpoImageFile.format,\n#                     JpegImagePlugin.jpeg_factory, _accept)\nImage.register_save(MpoImageFile.format, _save)\n\nImage.register_extension(MpoImageFile.format, \".mpo\")\n\nImage.register_mime(MpoImageFile.format, \"image/mpo\")\n", "path": "src/PIL/MpoImagePlugin.py"}], "after_files": [{"content": "#\n# The Python Imaging Library.\n# $Id$\n#\n# MPO file handling\n#\n# See \"Multi-Picture Format\" (CIPA DC-007-Translation 2009, Standard of the\n# Camera & Imaging Products Association)\n#\n# The multi-picture object combines multiple JPEG images (with a modified EXIF\n# data format) into a single file. While it can theoretically be used much like\n# a GIF animation, it is commonly used to represent 3D photographs and is (as\n# of this writing) the most commonly used format by 3D cameras.\n#\n# History:\n# 2014-03-13 Feneric   Created\n#\n# See the README file for information on usage and redistribution.\n#\n\nfrom . import Image, ImageFile, JpegImagePlugin\nfrom ._binary import i16be as i16\n\n# __version__ is deprecated and will be removed in a future version. Use\n# PIL.__version__ instead.\n__version__ = \"0.1\"\n\n\ndef _accept(prefix):\n    return JpegImagePlugin._accept(prefix)\n\n\ndef _save(im, fp, filename):\n    # Note that we can only save the current frame at present\n    return JpegImagePlugin._save(im, fp, filename)\n\n\n##\n# Image plugin for MPO images.\n\nclass MpoImageFile(JpegImagePlugin.JpegImageFile):\n\n    format = \"MPO\"\n    format_description = \"MPO (CIPA DC-007)\"\n    _close_exclusive_fp_after_loading = False\n\n    def _open(self):\n        self.fp.seek(0)  # prep the fp in order to pass the JPEG test\n        JpegImagePlugin.JpegImageFile._open(self)\n        self.mpinfo = self._getmp()\n        self.__framecount = self.mpinfo[0xB001]\n        self.__mpoffsets = [mpent['DataOffset'] + self.info['mpoffset']\n                            for mpent in self.mpinfo[0xB002]]\n        self.__mpoffsets[0] = 0\n        # Note that the following assertion will only be invalid if something\n        # gets broken within JpegImagePlugin.\n        assert self.__framecount == len(self.__mpoffsets)\n        del self.info['mpoffset']  # no longer needed\n        self.__fp = self.fp  # FIXME: hack\n        self.__fp.seek(self.__mpoffsets[0])  # get ready to read first frame\n        self.__frame = 0\n        self.offset = 0\n        # for now we can only handle reading and individual frame extraction\n        self.readonly = 1\n\n    def load_seek(self, pos):\n        self.__fp.seek(pos)\n\n    @property\n    def n_frames(self):\n        return self.__framecount\n\n    @property\n    def is_animated(self):\n        return self.__framecount > 1\n\n    def seek(self, frame):\n        if not self._seek_check(frame):\n            return\n        self.fp = self.__fp\n        self.offset = self.__mpoffsets[frame]\n\n        self.fp.seek(self.offset + 2)  # skip SOI marker\n        if \"parsed_exif\" in self.info:\n            del self.info[\"parsed_exif\"]\n        if i16(self.fp.read(2)) == 0xFFE1:  # APP1\n            n = i16(self.fp.read(2))-2\n            self.info[\"exif\"] = ImageFile._safe_read(self.fp, n)\n\n            exif = self._getexif()\n            if 40962 in exif and 40963 in exif:\n                self._size = (exif[40962], exif[40963])\n        elif \"exif\" in self.info:\n            del self.info[\"exif\"]\n\n        self.tile = [\n            (\"jpeg\", (0, 0) + self.size, self.offset, (self.mode, \"\"))\n        ]\n        self.__frame = frame\n\n    def tell(self):\n        return self.__frame\n\n    def _close__fp(self):\n        try:\n            if self.__fp != self.fp:\n                self.__fp.close()\n        except AttributeError:\n            pass\n        finally:\n            self.__fp = None\n\n\n# ---------------------------------------------------------------------\n# Registry stuff\n\n# Note that since MPO shares a factory with JPEG, we do not need to do a\n# separate registration for it here.\n# Image.register_open(MpoImageFile.format,\n#                     JpegImagePlugin.jpeg_factory, _accept)\nImage.register_save(MpoImageFile.format, _save)\n\nImage.register_extension(MpoImageFile.format, \".mpo\")\n\nImage.register_mime(MpoImageFile.format, \"image/mpo\")\n", "path": "src/PIL/MpoImagePlugin.py"}]}