prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Error: fromstring() in core/image/img_pil.py
  Platform: Linux (OpenSuse, Ubuntu)
  
  [INFO   ] [Kivy        ] v1.9.1
  [INFO   ] [Python      ] v2.7.12 (default, Jul 01 2016, 15:36:53) [GCC]
  
  Error:
    File "/usr/lib64/python2.7/site-packages/kivy/core/image/img_pil.py", line 105, in save
      image = PILImage.fromstring(fmt.upper(), (width, height), pixels)
    File "/usr/lib64/python2.7/site-packages/PIL/Image.py", line 2063, in fromstring
      "Please call frombytes() instead.")
  Exception: fromstring() has been removed. Please call frombytes() instead.
  
  
  In File "/usr/lib64/python2.7/site-packages/kivy/core/image/img_pil.py"
  Line 105:
  image = PILImage.fromstring(fmt.upper(), (width, height), pixels)
  
  use...
  
  image = PILImage.frombytes(fmt.upper(), (width, height), pixels)
  
  </issue>
  <code>
  [start of kivy/core/image/img_pil.py]
  1 '''
  2 PIL: PIL image loader
  3 '''
  4 
  5 __all__ = ('ImageLoaderPIL', )
  6 
  7 try:
  8     from PIL import Image as PILImage
  9 except:
  10     import Image as PILImage
  11 
  12 from kivy.logger import Logger
  13 from kivy.core.image import ImageLoaderBase, ImageData, ImageLoader
  14 
  15 
  16 class ImageLoaderPIL(ImageLoaderBase):
  17     '''Image loader based on the PIL library.
  18 
  19     .. versionadded:: 1.0.8
  20 
  21     Support for GIF animation added.
  22 
  23     Gif animation has a lot of issues(transparency/color depths... etc).
  24     In order to keep it simple, what is implemented here is what is
  25     natively supported by the PIL library.
  26 
  27     As a general rule, try to use gifs that have no transparency.
  28     Gif's with transparency will work but be prepared for some
  29     artifacts until transparency support is improved.
  30 
  31     '''
  32 
  33     @staticmethod
  34     def can_save():
  35         return True
  36 
  37     @staticmethod
  38     def can_load_memory():
  39         return True
  40 
  41     @staticmethod
  42     def extensions():
  43         '''Return accepted extensions for this loader'''
  44         # See http://www.pythonware.com/library/pil/handbook/index.htm
  45         return ('bmp', 'bufr', 'cur', 'dcx', 'fits', 'fl', 'fpx', 'gbr',
  46                 'gd', 'gif', 'grib', 'hdf5', 'ico', 'im', 'imt', 'iptc',
  47                 'jpeg', 'jpg', 'jpe', 'mcidas', 'mic', 'mpeg', 'msp',
  48                 'pcd', 'pcx', 'pixar', 'png', 'ppm', 'psd', 'sgi',
  49                 'spider', 'tga', 'tiff', 'wal', 'wmf', 'xbm', 'xpm',
  50                 'xv')
  51 
  52     def _img_correct(self, _img_tmp):
  53         '''Convert image to the correct format and orientation.
  54         '''
  55         # image loader work only with rgb/rgba image
  56         if _img_tmp.mode.lower() not in ('rgb', 'rgba'):
  57             try:
  58                 imc = _img_tmp.convert('RGBA')
  59             except:
  60                 Logger.warning(
  61                     'Image: Unable to convert image to rgba (was %s)' %
  62                     (_img_tmp.mode.lower()))
  63                 raise
  64             _img_tmp = imc
  65 
  66         return _img_tmp
  67 
  68     def _img_read(self, im):
  69         '''Read images from an animated file.
  70         '''
  71         im.seek(0)
  72 
  73         # Read all images inside
  74         try:
  75             img_ol = None
  76             while True:
  77                 img_tmp = im
  78                 img_tmp = self._img_correct(img_tmp)
  79                 if img_ol and (hasattr(im, 'dispose') and not im.dispose):
  80                     # paste new frame over old so as to handle
  81                     # transparency properly
  82                     img_ol.paste(img_tmp, (0, 0), img_tmp)
  83                     img_tmp = img_ol
  84                 img_ol = img_tmp
  85                 yield ImageData(img_tmp.size[0], img_tmp.size[1],
  86                                 img_tmp.mode.lower(), img_tmp.tobytes())
  87                 im.seek(im.tell() + 1)
  88         except EOFError:
  89             pass
  90 
  91     def load(self, filename):
  92         try:
  93             im = PILImage.open(filename)
  94         except:
  95             Logger.warning('Image: Unable to load image <%s>' % filename)
  96             raise
  97         # update internals
  98         if not self._inline:
  99             self.filename = filename
  100         # returns an array of type ImageData len 1 if not a sequence image
  101         return list(self._img_read(im))
  102 
  103     @staticmethod
  104     def save(filename, width, height, fmt, pixels, flipped=False):
  105         image = PILImage.fromstring(fmt.upper(), (width, height), pixels)
  106         if flipped:
  107             image = image.transpose(PILImage.FLIP_TOP_BOTTOM)
  108         image.save(filename)
  109         return True
  110 
  111 
  112 # register
  113 ImageLoader.register(ImageLoaderPIL)
  114
  [end of kivy/core/image/img_pil.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/kivy/core/image/img_pil.py b/kivy/core/image/img_pil.py
  --- a/kivy/core/image/img_pil.py
  +++ b/kivy/core/image/img_pil.py
  @@ -102,7 +102,8 @@
   
       @staticmethod
       def save(filename, width, height, fmt, pixels, flipped=False):
  -        image = PILImage.fromstring(fmt.upper(), (width, height), pixels)
  +        image = PILImage.frombytes(fmt.upper(), (width, height), pixels)
  +
           if flipped:
               image = image.transpose(PILImage.FLIP_TOP_BOTTOM)
           image.save(filename)
  
verification_info: {"golden_diff": "diff --git a/kivy/core/image/img_pil.py b/kivy/core/image/img_pil.py\n--- a/kivy/core/image/img_pil.py\n+++ b/kivy/core/image/img_pil.py\n@@ -102,7 +102,8 @@\n \n     @staticmethod\n     def save(filename, width, height, fmt, pixels, flipped=False):\n-        image = PILImage.fromstring(fmt.upper(), (width, height), pixels)\n+        image = PILImage.frombytes(fmt.upper(), (width, height), pixels)\n+\n         if flipped:\n             image = image.transpose(PILImage.FLIP_TOP_BOTTOM)\n         image.save(filename)\n", "issue": "Error: fromstring() in core/image/img_pil.py\nPlatform: Linux (OpenSuse, Ubuntu)\r\n\r\n[INFO   ] [Kivy        ] v1.9.1\r\n[INFO   ] [Python      ] v2.7.12 (default, Jul 01 2016, 15:36:53) [GCC]\r\n\r\nError:\r\n  File \"/usr/lib64/python2.7/site-packages/kivy/core/image/img_pil.py\", line 105, in save\r\n    image = PILImage.fromstring(fmt.upper(), (width, height), pixels)\r\n  File \"/usr/lib64/python2.7/site-packages/PIL/Image.py\", line 2063, in fromstring\r\n    \"Please call frombytes() instead.\")\r\nException: fromstring() has been removed. Please call frombytes() instead.\r\n\r\n\r\nIn File \"/usr/lib64/python2.7/site-packages/kivy/core/image/img_pil.py\"\r\nLine 105:\r\nimage = PILImage.fromstring(fmt.upper(), (width, height), pixels)\r\n\r\nuse...\r\n\r\nimage = PILImage.frombytes(fmt.upper(), (width, height), pixels)\n", "before_files": [{"content": "'''\nPIL: PIL image loader\n'''\n\n__all__ = ('ImageLoaderPIL', )\n\ntry:\n    from PIL import Image as PILImage\nexcept:\n    import Image as PILImage\n\nfrom kivy.logger import Logger\nfrom kivy.core.image import ImageLoaderBase, ImageData, ImageLoader\n\n\nclass ImageLoaderPIL(ImageLoaderBase):\n    '''Image loader based on the PIL library.\n\n    .. versionadded:: 1.0.8\n\n    Support for GIF animation added.\n\n    Gif animation has a lot of issues(transparency/color depths... etc).\n    In order to keep it simple, what is implemented here is what is\n    natively supported by the PIL library.\n\n    As a general rule, try to use gifs that have no transparency.\n    Gif's with transparency will work but be prepared for some\n    artifacts until transparency support is improved.\n\n    '''\n\n    @staticmethod\n    def can_save():\n        return True\n\n    @staticmethod\n    def can_load_memory():\n        return True\n\n    @staticmethod\n    def extensions():\n        '''Return accepted extensions for this loader'''\n        # See http://www.pythonware.com/library/pil/handbook/index.htm\n        return ('bmp', 'bufr', 'cur', 'dcx', 'fits', 'fl', 'fpx', 'gbr',\n                'gd', 'gif', 'grib', 'hdf5', 'ico', 'im', 'imt', 'iptc',\n                'jpeg', 'jpg', 'jpe', 'mcidas', 'mic', 'mpeg', 'msp',\n                'pcd', 'pcx', 'pixar', 'png', 'ppm', 'psd', 'sgi',\n                'spider', 'tga', 'tiff', 'wal', 'wmf', 'xbm', 'xpm',\n                'xv')\n\n    def _img_correct(self, _img_tmp):\n        '''Convert image to the correct format and orientation.\n        '''\n        # image loader work only with rgb/rgba image\n        if _img_tmp.mode.lower() not in ('rgb', 'rgba'):\n            try:\n                imc = _img_tmp.convert('RGBA')\n            except:\n                Logger.warning(\n                    'Image: Unable to convert image to rgba (was %s)' %\n                    (_img_tmp.mode.lower()))\n                raise\n            _img_tmp = imc\n\n        return _img_tmp\n\n    def _img_read(self, im):\n        '''Read images from an animated file.\n        '''\n        im.seek(0)\n\n        # Read all images inside\n        try:\n            img_ol = None\n            while True:\n                img_tmp = im\n                img_tmp = self._img_correct(img_tmp)\n                if img_ol and (hasattr(im, 'dispose') and not im.dispose):\n                    # paste new frame over old so as to handle\n                    # transparency properly\n                    img_ol.paste(img_tmp, (0, 0), img_tmp)\n                    img_tmp = img_ol\n                img_ol = img_tmp\n                yield ImageData(img_tmp.size[0], img_tmp.size[1],\n                                img_tmp.mode.lower(), img_tmp.tobytes())\n                im.seek(im.tell() + 1)\n        except EOFError:\n            pass\n\n    def load(self, filename):\n        try:\n            im = PILImage.open(filename)\n        except:\n            Logger.warning('Image: Unable to load image <%s>' % filename)\n            raise\n        # update internals\n        if not self._inline:\n            self.filename = filename\n        # returns an array of type ImageData len 1 if not a sequence image\n        return list(self._img_read(im))\n\n    @staticmethod\n    def save(filename, width, height, fmt, pixels, flipped=False):\n        image = PILImage.fromstring(fmt.upper(), (width, height), pixels)\n        if flipped:\n            image = image.transpose(PILImage.FLIP_TOP_BOTTOM)\n        image.save(filename)\n        return True\n\n\n# register\nImageLoader.register(ImageLoaderPIL)\n", "path": "kivy/core/image/img_pil.py"}]}