We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Image not scaling dynamically
#### ALL software version info

```
Python 3.9.0

bokeh==2.2.3
notebook==5.7.9
panel==0.10.1

macOS Catalina 10.15.7

Chrome 85.0.4183.121
```

#### Description of expected behavior and the observed behavior

##### Expected

I should be able to scale image up and down dynamically in Jupyter Notebook and using the standalone server.

##### Observed

In the notebook, I'm able to scale up and down <= 300 width. I can't make the image larger than 300 pixels wide.

Using the standalone server, it looks like it scales just once (either up or down) and then gets stuck.

#### Complete, minimal, self-contained example code that reproduces the issue

```python
import panel as pn

def panel_logo(width=300):
    # also happens with .jpg
    return pn.panel("https://panel.holoviz.org/_static/logo_stacked.png", width=width)

pn.interact(panel_logo)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `panel/pane/image.py`
Content:
```
1 """
2 Contains Image panes including renderers for PNG, SVG, GIF and JPG
3 file types.
4 """
5 from __future__ import absolute_import, division, unicode_literals
6 
7 import base64
8 
9 from io import BytesIO
10 from six import string_types
11 
12 import param
13 
14 from .markup import escape, DivPaneBase
15 from ..util import isfile, isurl
16 
17 
18 class ImageBase(DivPaneBase):
19     """
20     Encodes an image as base64 and wraps it in a Bokeh Div model.
21     This is an abstract base class that needs the image type
22     to be specified and specific code for determining the image shape.
23 
24     The imgtype determines the filetype, extension, and MIME type for
25     this image. Each image type (png,jpg,gif) has a base class that
26     supports anything with a `_repr_X_` method (where X is `png`,
27     `gif`, etc.), a local file with the given file extension, or a
28     HTTP(S) url with the given extension.  Subclasses of each type can
29     provide their own way of obtaining or generating a PNG.
30     """
31 
32     alt_text = param.String(default=None, doc="""
33         alt text to add to the image tag. The alt text is shown when a
34         user cannot load or display the image.""")
35 
36     link_url = param.String(default=None, doc="""
37         A link URL to make the image clickable and link to some other
38         website.""")
39 
40     embed = param.Boolean(default=True, doc="""
41         Whether to embed the image as base64.""")
42 
43     imgtype = 'None'
44 
45     _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']
46 
47     _target_transforms = {'object': """'<img src="' + value + '"></img>'"""}
48 
49     __abstract = True
50 
51     @classmethod
52     def applies(cls, obj):
53         imgtype = cls.imgtype
54         if hasattr(obj, '_repr_{}_'.format(imgtype)):
55             return True
56         if isinstance(obj, string_types):
57             if isfile(obj) and obj.endswith('.'+imgtype):
58                 return True
59             if isurl(obj, [cls.imgtype]):
60                 return True
61             elif isurl(obj, None):
62                 return 0
63         if hasattr(obj, 'read'):  # Check for file like object
64             return True
65         return False
66 
67     def _type_error(self, object):
68         if isinstance(object, string_types):
69             raise ValueError("%s pane cannot parse string that is not a filename "
70                              "or URL." % type(self).__name__)
71         super(ImageBase, self)._type_error(object)
72 
73     def _img(self):
74         if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):
75             return getattr(self.object, '_repr_' + self.imgtype + '_')()
76         if isinstance(self.object, string_types):
77             if isfile(self.object):
78                 with open(self.object, 'rb') as f:
79                     return f.read()
80         if hasattr(self.object, 'read'):
81             if hasattr(self.object, 'seek'):
82                 self.object.seek(0)
83             return self.object.read()
84         if isurl(self.object, None):
85             import requests
86             r = requests.request(url=self.object, method='GET')
87             return r.content
88 
89     def _b64(self):
90         data = self._img()
91         if not isinstance(data, bytes):
92             data = data.encode('utf-8')
93         b64 = base64.b64encode(data).decode("utf-8")
94         return "data:image/"+self.imgtype+f";base64,{b64}"
95 
96     def _imgshape(self, data):
97         """Calculate and return image width,height"""
98         raise NotImplementedError
99 
100     def _get_properties(self):
101         p = super(ImageBase, self)._get_properties()
102         if self.object is None:
103             return dict(p, text='<img></img>')
104         data = self._img()
105         if not isinstance(data, bytes):
106             data = base64.b64decode(data)
107         width, height = self._imgshape(data)
108         if self.width is not None:
109             if self.height is None:
110                 height = int((self.width/width)*height)
111             else:
112                 height = self.height
113             width = self.width
114         elif self.height is not None:
115             width = int((self.height/height)*width)
116             height = self.height
117         if not self.embed:
118             src = self.object
119         else:
120             b64 = base64.b64encode(data).decode("utf-8")
121             src = "data:image/"+self.imgtype+";base64,{b64}".format(b64=b64)
122 
123         smode = self.sizing_mode
124         if smode in ['fixed', None]:
125             w, h = '%spx' % width, '%spx' % height
126         elif smode == 'stretch_both':
127             w, h = '100%', '100%'
128         elif smode == 'stretch_width':
129             w, h = '%spx' % width, '100%'
130         elif smode == 'stretch_height':
131             w, h = '100%', '%spx' % height
132         elif smode == 'scale_height':
133             w, h = 'auto', '100%'
134         else:
135             w, h = '100%', 'auto'
136 
137         html = '<img src="{src}" width="{width}" height="{height}" alt="{alt}"></img>'.format(
138             src=src, width=w, height=h, alt=self.alt_text or '')
139 
140         if self.link_url:
141             html = '<a href="{url}" target="_blank">{html}</a>'.format(
142                 url=self.link_url, html=html)
143 
144         return dict(p, width=width, height=height, text=escape(html))
145 
146 
147 class PNG(ImageBase):
148 
149     imgtype = 'png'
150 
151     @classmethod
152     def _imgshape(cls, data):
153         import struct
154         w, h = struct.unpack('>LL', data[16:24])
155         return int(w), int(h)
156 
157 
158 class GIF(ImageBase):
159 
160     imgtype = 'gif'
161 
162     @classmethod
163     def _imgshape(cls, data):
164         import struct
165         w, h = struct.unpack("<HH", data[6:10])
166         return int(w), int(h)
167 
168 
169 class JPG(ImageBase):
170 
171     imgtype = 'jpg'
172 
173     @classmethod
174     def _imgshape(cls, data):
175         import struct
176         b = BytesIO(data)
177         b.read(2)
178         c = b.read(1)
179         while (c and ord(c) != 0xDA):
180             while (ord(c) != 0xFF): c = b.read(1)
181             while (ord(c) == 0xFF): c = b.read(1)
182             if (ord(c) >= 0xC0 and ord(c) <= 0xC3):
183                 b.read(3)
184                 h, w = struct.unpack(">HH", b.read(4))
185                 break
186             else:
187                 b.read(int(struct.unpack(">H", b.read(2))[0])-2)
188             c = b.read(1)
189         return int(w), int(h)
190 
191 
192 class SVG(ImageBase):
193 
194     encode = param.Boolean(default=False, doc="""
195         Whether to enable base64 encoding of the SVG, base64 encoded
196         SVGs do not support links.""")
197 
198     imgtype = 'svg'
199 
200     _rerender_params = ImageBase._rerender_params + ['encode']
201 
202     @classmethod
203     def applies(cls, obj):
204         return (super(SVG, cls).applies(obj) or
205                 (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))
206 
207     def _type_error(self, object):
208         if isinstance(object, string_types):
209             raise ValueError("%s pane cannot parse string that is not a filename, "
210                              "URL or a SVG XML contents." % type(self).__name__)
211         super(SVG, self)._type_error(object)
212 
213     def _img(self):
214         if (isinstance(self.object, string_types) and
215             self.object.lstrip().startswith('<svg')):
216             return self.object
217         return super(SVG, self)._img()
218 
219     def _b64(self):
220         data = self._img()
221         if not isinstance(data, bytes):
222             data = data.encode('utf-8')
223         b64 = base64.b64encode(data).decode("utf-8")
224         return f"data:image/svg+xml;base64,{b64}"
225 
226     def _imgshape(self, data):
227         return (self.width, self.height)
228 
229     def _get_properties(self):
230         p = super(ImageBase, self)._get_properties()
231         if self.object is None:
232             return dict(p, text='<img></img>')
233         data = self._img()
234         width, height = self._imgshape(data)
235         if not isinstance(data, bytes):
236             data = data.encode('utf-8')
237 
238         if self.encode:
239             b64 = base64.b64encode(data).decode("utf-8")
240             src = "data:image/svg+xml;base64,{b64}".format(b64=b64)
241             html = "<img src='{src}' width={width} height={height}></img>".format(
242                 src=src, width=width, height=height
243             )
244         else:
245             html = data.decode("utf-8")
246         return dict(p, width=width, height=height, text=escape(html))
247
```
--- 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/panel/pane/image.py b/panel/pane/image.py
--- a/panel/pane/image.py
+++ b/panel/pane/image.py
@@ -42,7 +42,7 @@
 
     imgtype = 'None'
 
-    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']
+    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style', 'width', 'height']
 
     _target_transforms = {'object': """'<img src="' + value + '"></img>'"""}

{"golden_diff": "diff --git a/panel/pane/image.py b/panel/pane/image.py\n--- a/panel/pane/image.py\n+++ b/panel/pane/image.py\n@@ -42,7 +42,7 @@\n \n     imgtype = 'None'\n \n-    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']\n+    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style', 'width', 'height']\n \n     _target_transforms = {'object': \"\"\"'<img src=\"' + value + '\"></img>'\"\"\"}\n", "issue": "Image not scaling dynamically\n#### ALL software version info\r\n\r\n```\r\nPython 3.9.0\r\n\r\nbokeh==2.2.3\r\nnotebook==5.7.9\r\npanel==0.10.1\r\n\r\nmacOS Catalina 10.15.7\r\n\r\nChrome 85.0.4183.121\r\n```\r\n\r\n#### Description of expected behavior and the observed behavior\r\n\r\n##### Expected\r\n\r\nI should be able to scale image up and down dynamically in Jupyter Notebook and using the standalone server.\r\n\r\n##### Observed\r\n\r\nIn the notebook, I'm able to scale up and down <= 300 width. I can't make the image larger than 300 pixels wide.\r\n\r\nUsing the standalone server, it looks like it scales just once (either up or down) and then gets stuck.\r\n\r\n#### Complete, minimal, self-contained example code that reproduces the issue\r\n\r\n```python\r\nimport panel as pn\r\n\r\ndef panel_logo(width=300):\r\n    # also happens with .jpg\r\n    return pn.panel(\"https://panel.holoviz.org/_static/logo_stacked.png\", width=width)\r\n\r\npn.interact(panel_logo)\r\n```\n", "before_files": [{"content": "\"\"\"\nContains Image panes including renderers for PNG, SVG, GIF and JPG\nfile types.\n\"\"\"\nfrom __future__ import absolute_import, division, unicode_literals\n\nimport base64\n\nfrom io import BytesIO\nfrom six import string_types\n\nimport param\n\nfrom .markup import escape, DivPaneBase\nfrom ..util import isfile, isurl\n\n\nclass ImageBase(DivPaneBase):\n    \"\"\"\n    Encodes an image as base64 and wraps it in a Bokeh Div model.\n    This is an abstract base class that needs the image type\n    to be specified and specific code for determining the image shape.\n\n    The imgtype determines the filetype, extension, and MIME type for\n    this image. Each image type (png,jpg,gif) has a base class that\n    supports anything with a `_repr_X_` method (where X is `png`,\n    `gif`, etc.), a local file with the given file extension, or a\n    HTTP(S) url with the given extension.  Subclasses of each type can\n    provide their own way of obtaining or generating a PNG.\n    \"\"\"\n\n    alt_text = param.String(default=None, doc=\"\"\"\n        alt text to add to the image tag. The alt text is shown when a\n        user cannot load or display the image.\"\"\")\n\n    link_url = param.String(default=None, doc=\"\"\"\n        A link URL to make the image clickable and link to some other\n        website.\"\"\")\n\n    embed = param.Boolean(default=True, doc=\"\"\"\n        Whether to embed the image as base64.\"\"\")\n\n    imgtype = 'None'\n\n    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style']\n\n    _target_transforms = {'object': \"\"\"'<img src=\"' + value + '\"></img>'\"\"\"}\n\n    __abstract = True\n\n    @classmethod\n    def applies(cls, obj):\n        imgtype = cls.imgtype\n        if hasattr(obj, '_repr_{}_'.format(imgtype)):\n            return True\n        if isinstance(obj, string_types):\n            if isfile(obj) and obj.endswith('.'+imgtype):\n                return True\n            if isurl(obj, [cls.imgtype]):\n                return True\n            elif isurl(obj, None):\n                return 0\n        if hasattr(obj, 'read'):  # Check for file like object\n            return True\n        return False\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename \"\n                             \"or URL.\" % type(self).__name__)\n        super(ImageBase, self)._type_error(object)\n\n    def _img(self):\n        if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):\n            return getattr(self.object, '_repr_' + self.imgtype + '_')()\n        if isinstance(self.object, string_types):\n            if isfile(self.object):\n                with open(self.object, 'rb') as f:\n                    return f.read()\n        if hasattr(self.object, 'read'):\n            if hasattr(self.object, 'seek'):\n                self.object.seek(0)\n            return self.object.read()\n        if isurl(self.object, None):\n            import requests\n            r = requests.request(url=self.object, method='GET')\n            return r.content\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return \"data:image/\"+self.imgtype+f\";base64,{b64}\"\n\n    def _imgshape(self, data):\n        \"\"\"Calculate and return image width,height\"\"\"\n        raise NotImplementedError\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = base64.b64decode(data)\n        width, height = self._imgshape(data)\n        if self.width is not None:\n            if self.height is None:\n                height = int((self.width/width)*height)\n            else:\n                height = self.height\n            width = self.width\n        elif self.height is not None:\n            width = int((self.height/height)*width)\n            height = self.height\n        if not self.embed:\n            src = self.object\n        else:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/\"+self.imgtype+\";base64,{b64}\".format(b64=b64)\n\n        smode = self.sizing_mode\n        if smode in ['fixed', None]:\n            w, h = '%spx' % width, '%spx' % height\n        elif smode == 'stretch_both':\n            w, h = '100%', '100%'\n        elif smode == 'stretch_width':\n            w, h = '%spx' % width, '100%'\n        elif smode == 'stretch_height':\n            w, h = '100%', '%spx' % height\n        elif smode == 'scale_height':\n            w, h = 'auto', '100%'\n        else:\n            w, h = '100%', 'auto'\n\n        html = '<img src=\"{src}\" width=\"{width}\" height=\"{height}\" alt=\"{alt}\"></img>'.format(\n            src=src, width=w, height=h, alt=self.alt_text or '')\n\n        if self.link_url:\n            html = '<a href=\"{url}\" target=\"_blank\">{html}</a>'.format(\n                url=self.link_url, html=html)\n\n        return dict(p, width=width, height=height, text=escape(html))\n\n\nclass PNG(ImageBase):\n\n    imgtype = 'png'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack('>LL', data[16:24])\n        return int(w), int(h)\n\n\nclass GIF(ImageBase):\n\n    imgtype = 'gif'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack(\"<HH\", data[6:10])\n        return int(w), int(h)\n\n\nclass JPG(ImageBase):\n\n    imgtype = 'jpg'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        b = BytesIO(data)\n        b.read(2)\n        c = b.read(1)\n        while (c and ord(c) != 0xDA):\n            while (ord(c) != 0xFF): c = b.read(1)\n            while (ord(c) == 0xFF): c = b.read(1)\n            if (ord(c) >= 0xC0 and ord(c) <= 0xC3):\n                b.read(3)\n                h, w = struct.unpack(\">HH\", b.read(4))\n                break\n            else:\n                b.read(int(struct.unpack(\">H\", b.read(2))[0])-2)\n            c = b.read(1)\n        return int(w), int(h)\n\n\nclass SVG(ImageBase):\n\n    encode = param.Boolean(default=False, doc=\"\"\"\n        Whether to enable base64 encoding of the SVG, base64 encoded\n        SVGs do not support links.\"\"\")\n\n    imgtype = 'svg'\n\n    _rerender_params = ImageBase._rerender_params + ['encode']\n\n    @classmethod\n    def applies(cls, obj):\n        return (super(SVG, cls).applies(obj) or\n                (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename, \"\n                             \"URL or a SVG XML contents.\" % type(self).__name__)\n        super(SVG, self)._type_error(object)\n\n    def _img(self):\n        if (isinstance(self.object, string_types) and\n            self.object.lstrip().startswith('<svg')):\n            return self.object\n        return super(SVG, self)._img()\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return f\"data:image/svg+xml;base64,{b64}\"\n\n    def _imgshape(self, data):\n        return (self.width, self.height)\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        width, height = self._imgshape(data)\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n\n        if self.encode:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/svg+xml;base64,{b64}\".format(b64=b64)\n            html = \"<img src='{src}' width={width} height={height}></img>\".format(\n                src=src, width=width, height=height\n            )\n        else:\n            html = data.decode(\"utf-8\")\n        return dict(p, width=width, height=height, text=escape(html))\n", "path": "panel/pane/image.py"}], "after_files": [{"content": "\"\"\"\nContains Image panes including renderers for PNG, SVG, GIF and JPG\nfile types.\n\"\"\"\nfrom __future__ import absolute_import, division, unicode_literals\n\nimport base64\n\nfrom io import BytesIO\nfrom six import string_types\n\nimport param\n\nfrom .markup import escape, DivPaneBase\nfrom ..util import isfile, isurl\n\n\nclass ImageBase(DivPaneBase):\n    \"\"\"\n    Encodes an image as base64 and wraps it in a Bokeh Div model.\n    This is an abstract base class that needs the image type\n    to be specified and specific code for determining the image shape.\n\n    The imgtype determines the filetype, extension, and MIME type for\n    this image. Each image type (png,jpg,gif) has a base class that\n    supports anything with a `_repr_X_` method (where X is `png`,\n    `gif`, etc.), a local file with the given file extension, or a\n    HTTP(S) url with the given extension.  Subclasses of each type can\n    provide their own way of obtaining or generating a PNG.\n    \"\"\"\n\n    alt_text = param.String(default=None, doc=\"\"\"\n        alt text to add to the image tag. The alt text is shown when a\n        user cannot load or display the image.\"\"\")\n\n    link_url = param.String(default=None, doc=\"\"\"\n        A link URL to make the image clickable and link to some other\n        website.\"\"\")\n\n    embed = param.Boolean(default=True, doc=\"\"\"\n        Whether to embed the image as base64.\"\"\")\n\n    imgtype = 'None'\n\n    _rerender_params = ['alt_text', 'link_url', 'embed', 'object', 'style', 'width', 'height']\n\n    _target_transforms = {'object': \"\"\"'<img src=\"' + value + '\"></img>'\"\"\"}\n\n    __abstract = True\n\n    @classmethod\n    def applies(cls, obj):\n        imgtype = cls.imgtype\n        if hasattr(obj, '_repr_{}_'.format(imgtype)):\n            return True\n        if isinstance(obj, string_types):\n            if isfile(obj) and obj.endswith('.'+imgtype):\n                return True\n            if isurl(obj, [cls.imgtype]):\n                return True\n            elif isurl(obj, None):\n                return 0\n        if hasattr(obj, 'read'):  # Check for file like object\n            return True\n        return False\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename \"\n                             \"or URL.\" % type(self).__name__)\n        super(ImageBase, self)._type_error(object)\n\n    def _img(self):\n        if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):\n            return getattr(self.object, '_repr_' + self.imgtype + '_')()\n        if isinstance(self.object, string_types):\n            if isfile(self.object):\n                with open(self.object, 'rb') as f:\n                    return f.read()\n        if hasattr(self.object, 'read'):\n            if hasattr(self.object, 'seek'):\n                self.object.seek(0)\n            return self.object.read()\n        if isurl(self.object, None):\n            import requests\n            r = requests.request(url=self.object, method='GET')\n            return r.content\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return \"data:image/\"+self.imgtype+f\";base64,{b64}\"\n\n    def _imgshape(self, data):\n        \"\"\"Calculate and return image width,height\"\"\"\n        raise NotImplementedError\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = base64.b64decode(data)\n        width, height = self._imgshape(data)\n        if self.width is not None:\n            if self.height is None:\n                height = int((self.width/width)*height)\n            else:\n                height = self.height\n            width = self.width\n        elif self.height is not None:\n            width = int((self.height/height)*width)\n            height = self.height\n        if not self.embed:\n            src = self.object\n        else:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/\"+self.imgtype+\";base64,{b64}\".format(b64=b64)\n\n        smode = self.sizing_mode\n        if smode in ['fixed', None]:\n            w, h = '%spx' % width, '%spx' % height\n        elif smode == 'stretch_both':\n            w, h = '100%', '100%'\n        elif smode == 'stretch_width':\n            w, h = '%spx' % width, '100%'\n        elif smode == 'stretch_height':\n            w, h = '100%', '%spx' % height\n        elif smode == 'scale_height':\n            w, h = 'auto', '100%'\n        else:\n            w, h = '100%', 'auto'\n\n        html = '<img src=\"{src}\" width=\"{width}\" height=\"{height}\" alt=\"{alt}\"></img>'.format(\n            src=src, width=w, height=h, alt=self.alt_text or '')\n\n        if self.link_url:\n            html = '<a href=\"{url}\" target=\"_blank\">{html}</a>'.format(\n                url=self.link_url, html=html)\n\n        return dict(p, width=width, height=height, text=escape(html))\n\n\nclass PNG(ImageBase):\n\n    imgtype = 'png'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack('>LL', data[16:24])\n        return int(w), int(h)\n\n\nclass GIF(ImageBase):\n\n    imgtype = 'gif'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        w, h = struct.unpack(\"<HH\", data[6:10])\n        return int(w), int(h)\n\n\nclass JPG(ImageBase):\n\n    imgtype = 'jpg'\n\n    @classmethod\n    def _imgshape(cls, data):\n        import struct\n        b = BytesIO(data)\n        b.read(2)\n        c = b.read(1)\n        while (c and ord(c) != 0xDA):\n            while (ord(c) != 0xFF): c = b.read(1)\n            while (ord(c) == 0xFF): c = b.read(1)\n            if (ord(c) >= 0xC0 and ord(c) <= 0xC3):\n                b.read(3)\n                h, w = struct.unpack(\">HH\", b.read(4))\n                break\n            else:\n                b.read(int(struct.unpack(\">H\", b.read(2))[0])-2)\n            c = b.read(1)\n        return int(w), int(h)\n\n\nclass SVG(ImageBase):\n\n    encode = param.Boolean(default=False, doc=\"\"\"\n        Whether to enable base64 encoding of the SVG, base64 encoded\n        SVGs do not support links.\"\"\")\n\n    imgtype = 'svg'\n\n    _rerender_params = ImageBase._rerender_params + ['encode']\n\n    @classmethod\n    def applies(cls, obj):\n        return (super(SVG, cls).applies(obj) or\n                (isinstance(obj, string_types) and obj.lstrip().startswith('<svg')))\n\n    def _type_error(self, object):\n        if isinstance(object, string_types):\n            raise ValueError(\"%s pane cannot parse string that is not a filename, \"\n                             \"URL or a SVG XML contents.\" % type(self).__name__)\n        super(SVG, self)._type_error(object)\n\n    def _img(self):\n        if (isinstance(self.object, string_types) and\n            self.object.lstrip().startswith('<svg')):\n            return self.object\n        return super(SVG, self)._img()\n\n    def _b64(self):\n        data = self._img()\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n        b64 = base64.b64encode(data).decode(\"utf-8\")\n        return f\"data:image/svg+xml;base64,{b64}\"\n\n    def _imgshape(self, data):\n        return (self.width, self.height)\n\n    def _get_properties(self):\n        p = super(ImageBase, self)._get_properties()\n        if self.object is None:\n            return dict(p, text='<img></img>')\n        data = self._img()\n        width, height = self._imgshape(data)\n        if not isinstance(data, bytes):\n            data = data.encode('utf-8')\n\n        if self.encode:\n            b64 = base64.b64encode(data).decode(\"utf-8\")\n            src = \"data:image/svg+xml;base64,{b64}\".format(b64=b64)\n            html = \"<img src='{src}' width={width} height={height}></img>\".format(\n                src=src, width=width, height=height\n            )\n        else:\n            html = data.decode(\"utf-8\")\n        return dict(p, width=width, height=height, text=escape(html))\n", "path": "panel/pane/image.py"}]}