1
1
# SPDX-FileCopyrightText: 2019 Radomir Dopieralski for Adafruit Industries
2
+ # SPDX-FileCopyrightText: 2022 Matt Land
2
3
#
3
4
# SPDX-License-Identifier: MIT
4
5
9
10
Load pixel values (indices or colors) into a bitmap and colors into a palette
10
11
from a GIF file.
11
12
12
- * Author(s): Radomir Dopieralski
13
+ * Author(s): Radomir Dopieralski, Matt Land
13
14
14
15
"""
15
16
16
17
import struct
17
18
19
+ try :
20
+ from typing import Tuple , Iterator , Optional , List
21
+ from io import BufferedReader
22
+ from displayio import Palette , Bitmap
23
+ from .displayio_types import PaletteConstructor , BitmapConstructor
24
+ except ImportError :
25
+ pass
18
26
19
27
__version__ = "0.0.0-auto.0"
20
28
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git"
21
29
22
30
23
- def load (file , * , bitmap = None , palette = None ):
31
+ def load (
32
+ file : BufferedReader ,
33
+ * ,
34
+ bitmap : BitmapConstructor ,
35
+ palette : PaletteConstructor = None
36
+ ) -> Tuple [Bitmap , Optional [Palette ]]:
24
37
"""Loads a GIF image from the open ``file``.
25
38
26
39
Returns tuple of bitmap object and palette object.
27
40
41
+ :param BufferedReader file: The *.gif file being loaded
28
42
:param object bitmap: Type to store bitmap data. Must have API similar to `displayio.Bitmap`.
29
43
Will be skipped if None
30
44
:param object palette: Type to store the palette. Must have API similar to
31
45
`displayio.Palette`. Will be skipped if None"""
32
46
header = file .read (6 )
33
47
if header not in {b"GIF87a" , b"GIF89a" }:
34
48
raise ValueError ("Not a GIF file" )
35
- width , height , flags , _ , _ = struct .unpack ("<HHBBB" , file .read (7 ))
49
+ width , height , flags , _ , _ = struct .unpack ( # pylint: disable=no-member
50
+ "<HHBBB" , file .read (7 )
51
+ )
36
52
if (flags & 0x80 ) != 0 :
37
53
palette_size = 1 << ((flags & 0x07 ) + 1 )
38
54
palette_obj = palette (palette_size )
@@ -57,9 +73,11 @@ def load(file, *, bitmap=None, palette=None):
57
73
return bitmap_obj , palette_obj
58
74
59
75
60
- def _read_frame (file , bitmap ):
61
- """Read a signle frame and apply it to the bitmap."""
62
- ddx , ddy , width , _ , flags = struct .unpack ("<HHHHB" , file .read (9 ))
76
+ def _read_frame (file : BufferedReader , bitmap : Bitmap ) -> None :
77
+ """Read a single frame and apply it to the bitmap."""
78
+ ddx , ddy , width , _ , flags = struct .unpack ( # pylint: disable=no-member
79
+ "<HHHHB" , file .read (9 )
80
+ )
63
81
if (flags & 0x40 ) != 0 :
64
82
raise NotImplementedError ("Interlacing not supported" )
65
83
if (flags & 0x80 ) != 0 :
@@ -78,7 +96,7 @@ def _read_frame(file, bitmap):
78
96
y += 1
79
97
80
98
81
- def _read_blockstream (file ) :
99
+ def _read_blockstream (file : BufferedReader ) -> Iterator [ int ] :
82
100
"""Read a block from a file."""
83
101
while True :
84
102
size = file .read (1 )[0 ]
@@ -95,21 +113,21 @@ class EndOfData(Exception):
95
113
class LZWDict :
96
114
"""A dictionary of LZW codes."""
97
115
98
- def __init__ (self , code_size ) :
116
+ def __init__ (self , code_size : int ) -> None :
99
117
self .code_size = code_size
100
118
self .clear_code = 1 << code_size
101
119
self .end_code = self .clear_code + 1
102
- self .codes = []
103
- self .last = None
120
+ self .codes = [] # type: List[bytes]
121
+ self .last = b""
104
122
self .clear ()
105
123
106
- def clear (self ):
124
+ def clear (self ) -> None :
107
125
"""Reset the dictionary to default codes."""
108
126
self .last = b""
109
127
self .code_len = self .code_size + 1
110
128
self .codes [:] = []
111
129
112
- def decode (self , code ) :
130
+ def decode (self , code : int ) -> bytes :
113
131
"""Decode a code."""
114
132
if code == self .clear_code :
115
133
self .clear ()
@@ -133,7 +151,7 @@ def decode(self, code):
133
151
return value
134
152
135
153
136
- def lzw_decode (data , code_size ) :
154
+ def lzw_decode (data : Iterator [ int ] , code_size : int ) -> Iterator [ bytes ] :
137
155
"""Decode LZW-compressed data."""
138
156
dictionary = LZWDict (code_size )
139
157
bit = 0
0 commit comments