We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Traceback when viewing certain gifs 
Open the attached flow dump in mitmproxy console. When viewing the content, observe the traceback that flashes to screen. A number of issues here:

- [ ] Kaitai should be able to parse this gif. It's not technically correct, but I've seen this often, especially with single-pixel tracking gifs. 
- *Even if Kaitai fails*, we shouldn't crash - the user should see an "invalid image" message (or something more informative). (#2698)
- *Even if we crash*, the traceback shouldn't be flashed to screen and disappear. This is an issue with the way we handle super-long error events in console. (#2699)

[bar.log](https://github.com/mitmproxy/mitmproxy/files/1545955/bar.log)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mitmproxy/contrib/kaitaistruct/gif.py`
Content:
```
1 # This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
2 
3 import array
4 import struct
5 import zlib
6 from enum import Enum
7 from pkg_resources import parse_version
8 
9 from kaitaistruct import __version__ as ks_version, KaitaiStruct, KaitaiStream, BytesIO
10 
11 
12 if parse_version(ks_version) < parse_version('0.7'):
13     raise Exception("Incompatible Kaitai Struct Python API: 0.7 or later is required, but you have %s" % (ks_version))
14 
15 class Gif(KaitaiStruct):
16 
17     class BlockType(Enum):
18         extension = 33
19         local_image_descriptor = 44
20         end_of_file = 59
21 
22     class ExtensionLabel(Enum):
23         graphic_control = 249
24         comment = 254
25         application = 255
26     def __init__(self, _io, _parent=None, _root=None):
27         self._io = _io
28         self._parent = _parent
29         self._root = _root if _root else self
30         self.hdr = self._root.Header(self._io, self, self._root)
31         self.logical_screen_descriptor = self._root.LogicalScreenDescriptorStruct(self._io, self, self._root)
32         if self.logical_screen_descriptor.has_color_table:
33             self._raw_global_color_table = self._io.read_bytes((self.logical_screen_descriptor.color_table_size * 3))
34             io = KaitaiStream(BytesIO(self._raw_global_color_table))
35             self.global_color_table = self._root.ColorTable(io, self, self._root)
36 
37         self.blocks = []
38         while not self._io.is_eof():
39             self.blocks.append(self._root.Block(self._io, self, self._root))
40 
41 
42     class ImageData(KaitaiStruct):
43         def __init__(self, _io, _parent=None, _root=None):
44             self._io = _io
45             self._parent = _parent
46             self._root = _root if _root else self
47             self.lzw_min_code_size = self._io.read_u1()
48             self.subblocks = self._root.Subblocks(self._io, self, self._root)
49 
50 
51     class ColorTableEntry(KaitaiStruct):
52         def __init__(self, _io, _parent=None, _root=None):
53             self._io = _io
54             self._parent = _parent
55             self._root = _root if _root else self
56             self.red = self._io.read_u1()
57             self.green = self._io.read_u1()
58             self.blue = self._io.read_u1()
59 
60 
61     class LogicalScreenDescriptorStruct(KaitaiStruct):
62         def __init__(self, _io, _parent=None, _root=None):
63             self._io = _io
64             self._parent = _parent
65             self._root = _root if _root else self
66             self.screen_width = self._io.read_u2le()
67             self.screen_height = self._io.read_u2le()
68             self.flags = self._io.read_u1()
69             self.bg_color_index = self._io.read_u1()
70             self.pixel_aspect_ratio = self._io.read_u1()
71 
72         @property
73         def has_color_table(self):
74             if hasattr(self, '_m_has_color_table'):
75                 return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None
76 
77             self._m_has_color_table = (self.flags & 128) != 0
78             return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None
79 
80         @property
81         def color_table_size(self):
82             if hasattr(self, '_m_color_table_size'):
83                 return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None
84 
85             self._m_color_table_size = (2 << (self.flags & 7))
86             return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None
87 
88 
89     class LocalImageDescriptor(KaitaiStruct):
90         def __init__(self, _io, _parent=None, _root=None):
91             self._io = _io
92             self._parent = _parent
93             self._root = _root if _root else self
94             self.left = self._io.read_u2le()
95             self.top = self._io.read_u2le()
96             self.width = self._io.read_u2le()
97             self.height = self._io.read_u2le()
98             self.flags = self._io.read_u1()
99             if self.has_color_table:
100                 self._raw_local_color_table = self._io.read_bytes((self.color_table_size * 3))
101                 io = KaitaiStream(BytesIO(self._raw_local_color_table))
102                 self.local_color_table = self._root.ColorTable(io, self, self._root)
103 
104             self.image_data = self._root.ImageData(self._io, self, self._root)
105 
106         @property
107         def has_color_table(self):
108             if hasattr(self, '_m_has_color_table'):
109                 return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None
110 
111             self._m_has_color_table = (self.flags & 128) != 0
112             return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None
113 
114         @property
115         def has_interlace(self):
116             if hasattr(self, '_m_has_interlace'):
117                 return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None
118 
119             self._m_has_interlace = (self.flags & 64) != 0
120             return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None
121 
122         @property
123         def has_sorted_color_table(self):
124             if hasattr(self, '_m_has_sorted_color_table'):
125                 return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None
126 
127             self._m_has_sorted_color_table = (self.flags & 32) != 0
128             return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None
129 
130         @property
131         def color_table_size(self):
132             if hasattr(self, '_m_color_table_size'):
133                 return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None
134 
135             self._m_color_table_size = (2 << (self.flags & 7))
136             return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None
137 
138 
139     class Block(KaitaiStruct):
140         def __init__(self, _io, _parent=None, _root=None):
141             self._io = _io
142             self._parent = _parent
143             self._root = _root if _root else self
144             self.block_type = self._root.BlockType(self._io.read_u1())
145             _on = self.block_type
146             if _on == self._root.BlockType.extension:
147                 self.body = self._root.Extension(self._io, self, self._root)
148             elif _on == self._root.BlockType.local_image_descriptor:
149                 self.body = self._root.LocalImageDescriptor(self._io, self, self._root)
150 
151 
152     class ColorTable(KaitaiStruct):
153         def __init__(self, _io, _parent=None, _root=None):
154             self._io = _io
155             self._parent = _parent
156             self._root = _root if _root else self
157             self.entries = []
158             while not self._io.is_eof():
159                 self.entries.append(self._root.ColorTableEntry(self._io, self, self._root))
160 
161 
162 
163     class Header(KaitaiStruct):
164         def __init__(self, _io, _parent=None, _root=None):
165             self._io = _io
166             self._parent = _parent
167             self._root = _root if _root else self
168             self.magic = self._io.ensure_fixed_contents(struct.pack('3b', 71, 73, 70))
169             self.version = (self._io.read_bytes(3)).decode(u"ASCII")
170 
171 
172     class ExtGraphicControl(KaitaiStruct):
173         def __init__(self, _io, _parent=None, _root=None):
174             self._io = _io
175             self._parent = _parent
176             self._root = _root if _root else self
177             self.block_size = self._io.ensure_fixed_contents(struct.pack('1b', 4))
178             self.flags = self._io.read_u1()
179             self.delay_time = self._io.read_u2le()
180             self.transparent_idx = self._io.read_u1()
181             self.terminator = self._io.ensure_fixed_contents(struct.pack('1b', 0))
182 
183         @property
184         def transparent_color_flag(self):
185             if hasattr(self, '_m_transparent_color_flag'):
186                 return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None
187 
188             self._m_transparent_color_flag = (self.flags & 1) != 0
189             return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None
190 
191         @property
192         def user_input_flag(self):
193             if hasattr(self, '_m_user_input_flag'):
194                 return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None
195 
196             self._m_user_input_flag = (self.flags & 2) != 0
197             return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None
198 
199 
200     class Subblock(KaitaiStruct):
201         def __init__(self, _io, _parent=None, _root=None):
202             self._io = _io
203             self._parent = _parent
204             self._root = _root if _root else self
205             self.num_bytes = self._io.read_u1()
206             self.bytes = self._io.read_bytes(self.num_bytes)
207 
208 
209     class ExtApplication(KaitaiStruct):
210         def __init__(self, _io, _parent=None, _root=None):
211             self._io = _io
212             self._parent = _parent
213             self._root = _root if _root else self
214             self.application_id = self._root.Subblock(self._io, self, self._root)
215             self.subblocks = []
216             while True:
217                 _ = self._root.Subblock(self._io, self, self._root)
218                 self.subblocks.append(_)
219                 if _.num_bytes == 0:
220                     break
221 
222 
223     class Subblocks(KaitaiStruct):
224         def __init__(self, _io, _parent=None, _root=None):
225             self._io = _io
226             self._parent = _parent
227             self._root = _root if _root else self
228             self.entries = []
229             while True:
230                 _ = self._root.Subblock(self._io, self, self._root)
231                 self.entries.append(_)
232                 if _.num_bytes == 0:
233                     break
234 
235 
236     class Extension(KaitaiStruct):
237         def __init__(self, _io, _parent=None, _root=None):
238             self._io = _io
239             self._parent = _parent
240             self._root = _root if _root else self
241             self.label = self._root.ExtensionLabel(self._io.read_u1())
242             _on = self.label
243             if _on == self._root.ExtensionLabel.application:
244                 self.body = self._root.ExtApplication(self._io, self, self._root)
245             elif _on == self._root.ExtensionLabel.comment:
246                 self.body = self._root.Subblocks(self._io, self, self._root)
247             elif _on == self._root.ExtensionLabel.graphic_control:
248                 self.body = self._root.ExtGraphicControl(self._io, self, self._root)
249             else:
250                 self.body = self._root.Subblocks(self._io, self, self._root)
251 
252 
253 
254
```
--- 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/mitmproxy/contrib/kaitaistruct/gif.py b/mitmproxy/contrib/kaitaistruct/gif.py
--- a/mitmproxy/contrib/kaitaistruct/gif.py
+++ b/mitmproxy/contrib/kaitaistruct/gif.py
@@ -35,9 +35,11 @@
             self.global_color_table = self._root.ColorTable(io, self, self._root)
 
         self.blocks = []
-        while not self._io.is_eof():
-            self.blocks.append(self._root.Block(self._io, self, self._root))
-
+        while True:
+            _ = self._root.Block(self._io, self, self._root)
+            self.blocks.append(_)
+            if  ((self._io.is_eof()) or (_.block_type == self._root.BlockType.end_of_file)) :
+                break
 
     class ImageData(KaitaiStruct):
         def __init__(self, _io, _parent=None, _root=None):

{"golden_diff": "diff --git a/mitmproxy/contrib/kaitaistruct/gif.py b/mitmproxy/contrib/kaitaistruct/gif.py\n--- a/mitmproxy/contrib/kaitaistruct/gif.py\n+++ b/mitmproxy/contrib/kaitaistruct/gif.py\n@@ -35,9 +35,11 @@\n             self.global_color_table = self._root.ColorTable(io, self, self._root)\n \n         self.blocks = []\n-        while not self._io.is_eof():\n-            self.blocks.append(self._root.Block(self._io, self, self._root))\n-\n+        while True:\n+            _ = self._root.Block(self._io, self, self._root)\n+            self.blocks.append(_)\n+            if  ((self._io.is_eof()) or (_.block_type == self._root.BlockType.end_of_file)) :\n+                break\n \n     class ImageData(KaitaiStruct):\n         def __init__(self, _io, _parent=None, _root=None):\n", "issue": "Traceback when viewing certain gifs \nOpen the attached flow dump in mitmproxy console. When viewing the content, observe the traceback that flashes to screen. A number of issues here:\r\n\r\n- [ ] Kaitai should be able to parse this gif. It's not technically correct, but I've seen this often, especially with single-pixel tracking gifs. \r\n- *Even if Kaitai fails*, we shouldn't crash - the user should see an \"invalid image\" message (or something more informative). (#2698)\r\n- *Even if we crash*, the traceback shouldn't be flashed to screen and disappear. This is an issue with the way we handle super-long error events in console. (#2699)\r\n\r\n[bar.log](https://github.com/mitmproxy/mitmproxy/files/1545955/bar.log)\r\n\n", "before_files": [{"content": "# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\nimport array\nimport struct\nimport zlib\nfrom enum import Enum\nfrom pkg_resources import parse_version\n\nfrom kaitaistruct import __version__ as ks_version, KaitaiStruct, KaitaiStream, BytesIO\n\n\nif parse_version(ks_version) < parse_version('0.7'):\n    raise Exception(\"Incompatible Kaitai Struct Python API: 0.7 or later is required, but you have %s\" % (ks_version))\n\nclass Gif(KaitaiStruct):\n\n    class BlockType(Enum):\n        extension = 33\n        local_image_descriptor = 44\n        end_of_file = 59\n\n    class ExtensionLabel(Enum):\n        graphic_control = 249\n        comment = 254\n        application = 255\n    def __init__(self, _io, _parent=None, _root=None):\n        self._io = _io\n        self._parent = _parent\n        self._root = _root if _root else self\n        self.hdr = self._root.Header(self._io, self, self._root)\n        self.logical_screen_descriptor = self._root.LogicalScreenDescriptorStruct(self._io, self, self._root)\n        if self.logical_screen_descriptor.has_color_table:\n            self._raw_global_color_table = self._io.read_bytes((self.logical_screen_descriptor.color_table_size * 3))\n            io = KaitaiStream(BytesIO(self._raw_global_color_table))\n            self.global_color_table = self._root.ColorTable(io, self, self._root)\n\n        self.blocks = []\n        while not self._io.is_eof():\n            self.blocks.append(self._root.Block(self._io, self, self._root))\n\n\n    class ImageData(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.lzw_min_code_size = self._io.read_u1()\n            self.subblocks = self._root.Subblocks(self._io, self, self._root)\n\n\n    class ColorTableEntry(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.red = self._io.read_u1()\n            self.green = self._io.read_u1()\n            self.blue = self._io.read_u1()\n\n\n    class LogicalScreenDescriptorStruct(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.screen_width = self._io.read_u2le()\n            self.screen_height = self._io.read_u2le()\n            self.flags = self._io.read_u1()\n            self.bg_color_index = self._io.read_u1()\n            self.pixel_aspect_ratio = self._io.read_u1()\n\n        @property\n        def has_color_table(self):\n            if hasattr(self, '_m_has_color_table'):\n                return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n            self._m_has_color_table = (self.flags & 128) != 0\n            return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n        @property\n        def color_table_size(self):\n            if hasattr(self, '_m_color_table_size'):\n                return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n            self._m_color_table_size = (2 << (self.flags & 7))\n            return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n\n    class LocalImageDescriptor(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.left = self._io.read_u2le()\n            self.top = self._io.read_u2le()\n            self.width = self._io.read_u2le()\n            self.height = self._io.read_u2le()\n            self.flags = self._io.read_u1()\n            if self.has_color_table:\n                self._raw_local_color_table = self._io.read_bytes((self.color_table_size * 3))\n                io = KaitaiStream(BytesIO(self._raw_local_color_table))\n                self.local_color_table = self._root.ColorTable(io, self, self._root)\n\n            self.image_data = self._root.ImageData(self._io, self, self._root)\n\n        @property\n        def has_color_table(self):\n            if hasattr(self, '_m_has_color_table'):\n                return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n            self._m_has_color_table = (self.flags & 128) != 0\n            return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n        @property\n        def has_interlace(self):\n            if hasattr(self, '_m_has_interlace'):\n                return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None\n\n            self._m_has_interlace = (self.flags & 64) != 0\n            return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None\n\n        @property\n        def has_sorted_color_table(self):\n            if hasattr(self, '_m_has_sorted_color_table'):\n                return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None\n\n            self._m_has_sorted_color_table = (self.flags & 32) != 0\n            return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None\n\n        @property\n        def color_table_size(self):\n            if hasattr(self, '_m_color_table_size'):\n                return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n            self._m_color_table_size = (2 << (self.flags & 7))\n            return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n\n    class Block(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.block_type = self._root.BlockType(self._io.read_u1())\n            _on = self.block_type\n            if _on == self._root.BlockType.extension:\n                self.body = self._root.Extension(self._io, self, self._root)\n            elif _on == self._root.BlockType.local_image_descriptor:\n                self.body = self._root.LocalImageDescriptor(self._io, self, self._root)\n\n\n    class ColorTable(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.entries = []\n            while not self._io.is_eof():\n                self.entries.append(self._root.ColorTableEntry(self._io, self, self._root))\n\n\n\n    class Header(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.magic = self._io.ensure_fixed_contents(struct.pack('3b', 71, 73, 70))\n            self.version = (self._io.read_bytes(3)).decode(u\"ASCII\")\n\n\n    class ExtGraphicControl(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.block_size = self._io.ensure_fixed_contents(struct.pack('1b', 4))\n            self.flags = self._io.read_u1()\n            self.delay_time = self._io.read_u2le()\n            self.transparent_idx = self._io.read_u1()\n            self.terminator = self._io.ensure_fixed_contents(struct.pack('1b', 0))\n\n        @property\n        def transparent_color_flag(self):\n            if hasattr(self, '_m_transparent_color_flag'):\n                return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None\n\n            self._m_transparent_color_flag = (self.flags & 1) != 0\n            return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None\n\n        @property\n        def user_input_flag(self):\n            if hasattr(self, '_m_user_input_flag'):\n                return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None\n\n            self._m_user_input_flag = (self.flags & 2) != 0\n            return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None\n\n\n    class Subblock(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.num_bytes = self._io.read_u1()\n            self.bytes = self._io.read_bytes(self.num_bytes)\n\n\n    class ExtApplication(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.application_id = self._root.Subblock(self._io, self, self._root)\n            self.subblocks = []\n            while True:\n                _ = self._root.Subblock(self._io, self, self._root)\n                self.subblocks.append(_)\n                if _.num_bytes == 0:\n                    break\n\n\n    class Subblocks(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.entries = []\n            while True:\n                _ = self._root.Subblock(self._io, self, self._root)\n                self.entries.append(_)\n                if _.num_bytes == 0:\n                    break\n\n\n    class Extension(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.label = self._root.ExtensionLabel(self._io.read_u1())\n            _on = self.label\n            if _on == self._root.ExtensionLabel.application:\n                self.body = self._root.ExtApplication(self._io, self, self._root)\n            elif _on == self._root.ExtensionLabel.comment:\n                self.body = self._root.Subblocks(self._io, self, self._root)\n            elif _on == self._root.ExtensionLabel.graphic_control:\n                self.body = self._root.ExtGraphicControl(self._io, self, self._root)\n            else:\n                self.body = self._root.Subblocks(self._io, self, self._root)\n\n\n\n", "path": "mitmproxy/contrib/kaitaistruct/gif.py"}], "after_files": [{"content": "# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild\n\nimport array\nimport struct\nimport zlib\nfrom enum import Enum\nfrom pkg_resources import parse_version\n\nfrom kaitaistruct import __version__ as ks_version, KaitaiStruct, KaitaiStream, BytesIO\n\n\nif parse_version(ks_version) < parse_version('0.7'):\n    raise Exception(\"Incompatible Kaitai Struct Python API: 0.7 or later is required, but you have %s\" % (ks_version))\n\nclass Gif(KaitaiStruct):\n\n    class BlockType(Enum):\n        extension = 33\n        local_image_descriptor = 44\n        end_of_file = 59\n\n    class ExtensionLabel(Enum):\n        graphic_control = 249\n        comment = 254\n        application = 255\n    def __init__(self, _io, _parent=None, _root=None):\n        self._io = _io\n        self._parent = _parent\n        self._root = _root if _root else self\n        self.hdr = self._root.Header(self._io, self, self._root)\n        self.logical_screen_descriptor = self._root.LogicalScreenDescriptorStruct(self._io, self, self._root)\n        if self.logical_screen_descriptor.has_color_table:\n            self._raw_global_color_table = self._io.read_bytes((self.logical_screen_descriptor.color_table_size * 3))\n            io = KaitaiStream(BytesIO(self._raw_global_color_table))\n            self.global_color_table = self._root.ColorTable(io, self, self._root)\n\n        self.blocks = []\n        while True:\n            _ = self._root.Block(self._io, self, self._root)\n            self.blocks.append(_)\n            if  ((self._io.is_eof()) or (_.block_type == self._root.BlockType.end_of_file)) :\n                break\n\n    class ImageData(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.lzw_min_code_size = self._io.read_u1()\n            self.subblocks = self._root.Subblocks(self._io, self, self._root)\n\n\n    class ColorTableEntry(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.red = self._io.read_u1()\n            self.green = self._io.read_u1()\n            self.blue = self._io.read_u1()\n\n\n    class LogicalScreenDescriptorStruct(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.screen_width = self._io.read_u2le()\n            self.screen_height = self._io.read_u2le()\n            self.flags = self._io.read_u1()\n            self.bg_color_index = self._io.read_u1()\n            self.pixel_aspect_ratio = self._io.read_u1()\n\n        @property\n        def has_color_table(self):\n            if hasattr(self, '_m_has_color_table'):\n                return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n            self._m_has_color_table = (self.flags & 128) != 0\n            return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n        @property\n        def color_table_size(self):\n            if hasattr(self, '_m_color_table_size'):\n                return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n            self._m_color_table_size = (2 << (self.flags & 7))\n            return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n\n    class LocalImageDescriptor(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.left = self._io.read_u2le()\n            self.top = self._io.read_u2le()\n            self.width = self._io.read_u2le()\n            self.height = self._io.read_u2le()\n            self.flags = self._io.read_u1()\n            if self.has_color_table:\n                self._raw_local_color_table = self._io.read_bytes((self.color_table_size * 3))\n                io = KaitaiStream(BytesIO(self._raw_local_color_table))\n                self.local_color_table = self._root.ColorTable(io, self, self._root)\n\n            self.image_data = self._root.ImageData(self._io, self, self._root)\n\n        @property\n        def has_color_table(self):\n            if hasattr(self, '_m_has_color_table'):\n                return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n            self._m_has_color_table = (self.flags & 128) != 0\n            return self._m_has_color_table if hasattr(self, '_m_has_color_table') else None\n\n        @property\n        def has_interlace(self):\n            if hasattr(self, '_m_has_interlace'):\n                return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None\n\n            self._m_has_interlace = (self.flags & 64) != 0\n            return self._m_has_interlace if hasattr(self, '_m_has_interlace') else None\n\n        @property\n        def has_sorted_color_table(self):\n            if hasattr(self, '_m_has_sorted_color_table'):\n                return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None\n\n            self._m_has_sorted_color_table = (self.flags & 32) != 0\n            return self._m_has_sorted_color_table if hasattr(self, '_m_has_sorted_color_table') else None\n\n        @property\n        def color_table_size(self):\n            if hasattr(self, '_m_color_table_size'):\n                return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n            self._m_color_table_size = (2 << (self.flags & 7))\n            return self._m_color_table_size if hasattr(self, '_m_color_table_size') else None\n\n\n    class Block(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.block_type = self._root.BlockType(self._io.read_u1())\n            _on = self.block_type\n            if _on == self._root.BlockType.extension:\n                self.body = self._root.Extension(self._io, self, self._root)\n            elif _on == self._root.BlockType.local_image_descriptor:\n                self.body = self._root.LocalImageDescriptor(self._io, self, self._root)\n\n\n    class ColorTable(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.entries = []\n            while not self._io.is_eof():\n                self.entries.append(self._root.ColorTableEntry(self._io, self, self._root))\n\n\n\n    class Header(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.magic = self._io.ensure_fixed_contents(struct.pack('3b', 71, 73, 70))\n            self.version = (self._io.read_bytes(3)).decode(u\"ASCII\")\n\n\n    class ExtGraphicControl(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.block_size = self._io.ensure_fixed_contents(struct.pack('1b', 4))\n            self.flags = self._io.read_u1()\n            self.delay_time = self._io.read_u2le()\n            self.transparent_idx = self._io.read_u1()\n            self.terminator = self._io.ensure_fixed_contents(struct.pack('1b', 0))\n\n        @property\n        def transparent_color_flag(self):\n            if hasattr(self, '_m_transparent_color_flag'):\n                return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None\n\n            self._m_transparent_color_flag = (self.flags & 1) != 0\n            return self._m_transparent_color_flag if hasattr(self, '_m_transparent_color_flag') else None\n\n        @property\n        def user_input_flag(self):\n            if hasattr(self, '_m_user_input_flag'):\n                return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None\n\n            self._m_user_input_flag = (self.flags & 2) != 0\n            return self._m_user_input_flag if hasattr(self, '_m_user_input_flag') else None\n\n\n    class Subblock(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.num_bytes = self._io.read_u1()\n            self.bytes = self._io.read_bytes(self.num_bytes)\n\n\n    class ExtApplication(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.application_id = self._root.Subblock(self._io, self, self._root)\n            self.subblocks = []\n            while True:\n                _ = self._root.Subblock(self._io, self, self._root)\n                self.subblocks.append(_)\n                if _.num_bytes == 0:\n                    break\n\n\n    class Subblocks(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.entries = []\n            while True:\n                _ = self._root.Subblock(self._io, self, self._root)\n                self.entries.append(_)\n                if _.num_bytes == 0:\n                    break\n\n\n    class Extension(KaitaiStruct):\n        def __init__(self, _io, _parent=None, _root=None):\n            self._io = _io\n            self._parent = _parent\n            self._root = _root if _root else self\n            self.label = self._root.ExtensionLabel(self._io.read_u1())\n            _on = self.label\n            if _on == self._root.ExtensionLabel.application:\n                self.body = self._root.ExtApplication(self._io, self, self._root)\n            elif _on == self._root.ExtensionLabel.comment:\n                self.body = self._root.Subblocks(self._io, self, self._root)\n            elif _on == self._root.ExtensionLabel.graphic_control:\n                self.body = self._root.ExtGraphicControl(self._io, self, self._root)\n            else:\n                self.body = self._root.Subblocks(self._io, self, self._root)\n\n\n\n", "path": "mitmproxy/contrib/kaitaistruct/gif.py"}]}