prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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)".
  
  
  </issue>
  <code>
  [start of src/PIL/MpoImagePlugin.py]
  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 of src/PIL/MpoImagePlugin.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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, ""))
           ]
  
verification_info: {"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"}]}