Skip to content

Commit 4fe2546

Browse files
committed
#18 add type annotations
1 parent 5b89512 commit 4fe2546

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

adafruit_bitmapsaver.py

+35-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries
2+
# SPDX-FileCopyrightText: 2022 Matt Land
23
#
34
# SPDX-License-Identifier: MIT
45

@@ -10,7 +11,7 @@
1011
Make a screenshot (the contents of a displayio.Display) and save in a BMP file.
1112
1213
13-
* Author(s): Dave Astels
14+
* Author(s): Dave Astels, Matt Land
1415
1516
Implementation Notes
1617
--------------------
@@ -32,19 +33,25 @@
3233
import board
3334
from displayio import Bitmap, Palette, Display
3435

36+
try:
37+
from typing import Tuple, Optional, Union
38+
from io import BufferedWriter
39+
except ImportError:
40+
pass
41+
3542
__version__ = "0.0.0-auto.0"
3643
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BitmapSaver.git"
3744

3845

39-
def _write_bmp_header(output_file, filesize):
46+
def _write_bmp_header(output_file: BufferedWriter, filesize: int) -> None:
4047
output_file.write(bytes("BM", "ascii"))
4148
output_file.write(struct.pack("<I", filesize))
4249
output_file.write(b"\00\x00")
4350
output_file.write(b"\00\x00")
4451
output_file.write(struct.pack("<I", 54))
4552

4653

47-
def _write_dib_header(output_file, width, height):
54+
def _write_dib_header(output_file: BufferedWriter, width: int, height: int) -> None:
4855
output_file.write(struct.pack("<I", 40))
4956
output_file.write(struct.pack("<I", width))
5057
output_file.write(struct.pack("<I", height))
@@ -54,44 +61,50 @@ def _write_dib_header(output_file, width, height):
5461
output_file.write(b"\x00")
5562

5663

57-
def _bytes_per_row(source_width):
64+
def _bytes_per_row(source_width: int) -> int:
5865
pixel_bytes = 3 * source_width
5966
padding_bytes = (4 - (pixel_bytes % 4)) % 4
6067
return pixel_bytes + padding_bytes
6168

6269

63-
def _rotated_height_and_width(pixel_source):
70+
def _rotated_height_and_width(pixel_source: Union[Bitmap, Display]) -> Tuple[int, int]:
6471
# flip axis if the display is rotated
6572
if isinstance(pixel_source, Display) and (pixel_source.rotation % 180 != 0):
66-
return (pixel_source.height, pixel_source.width)
67-
return (pixel_source.width, pixel_source.height)
73+
return pixel_source.height, pixel_source.width
74+
return pixel_source.width, pixel_source.height
6875

6976

70-
def _rgb565_to_bgr_tuple(color):
71-
blue = (color << 3) & 0x00F8 # extract each of the RGB tripple into it's own byte
77+
def _rgb565_to_bgr_tuple(color: int) -> Tuple[int, int, int]:
78+
blue = (color << 3) & 0x00F8 # extract each of the RGB triple into it's own byte
7279
green = (color >> 3) & 0x00FC
7380
red = (color >> 8) & 0x00F8
74-
return (blue, green, red)
81+
return blue, green, red
7582

7683

7784
# pylint:disable=too-many-locals
78-
def _write_pixels(output_file, pixel_source, palette):
85+
def _write_pixels(
86+
output_file: BufferedWriter,
87+
pixel_source: Union[Bitmap, Display],
88+
palette: Optional[Palette],
89+
) -> None:
7990
saving_bitmap = isinstance(pixel_source, Bitmap)
8091
width, height = _rotated_height_and_width(pixel_source)
8192
row_buffer = bytearray(_bytes_per_row(width))
8293
for y in range(height, 0, -1):
8394
buffer_index = 0
8495
if saving_bitmap:
96+
# pixel_source: Bitmap
8597
for x in range(width):
86-
pixel = pixel_source[x, y - 1]
87-
color = palette[pixel]
98+
pixel = pixel_source[x, y - 1] # type: ignore
99+
color = palette[pixel] # type: ignore # handled by save_pixel's guardians
88100
for _ in range(3):
89101
row_buffer[buffer_index] = color & 0xFF
90102
color >>= 8
91103
buffer_index += 1
92104
else:
105+
# pixel_source: Display
93106
result_buffer = bytearray(2048)
94-
data = pixel_source.fill_row(y - 1, result_buffer)
107+
data = pixel_source.fill_row(y - 1, result_buffer) # type: ignore
95108
for i in range(width):
96109
pixel565 = (data[i * 2] << 8) + data[i * 2 + 1]
97110
for b in _rgb565_to_bgr_tuple(pixel565):
@@ -106,7 +119,11 @@ def _write_pixels(output_file, pixel_source, palette):
106119
# pylint:enable=too-many-locals
107120

108121

109-
def save_pixels(file_or_filename, pixel_source=None, palette=None):
122+
def save_pixels(
123+
file_or_filename: Union[str, BufferedWriter],
124+
pixel_source: Union[Display, Bitmap] = None,
125+
palette: Palette = None,
126+
) -> None:
110127
"""Save pixels to a 24 bit per pixel BMP file.
111128
If pixel_source if a displayio.Bitmap, save it's pixels through palette.
112129
If it's a displayio.Display, a palette isn't required.
@@ -116,10 +133,10 @@ def save_pixels(file_or_filename, pixel_source=None, palette=None):
116133
:param palette: the Palette to use for looking up colors in the bitmap
117134
"""
118135
if not pixel_source:
119-
if "DISPLAY" in dir(board):
120-
pixel_source = board.DISPLAY
121-
else:
136+
if "DISPLAY" not in dir(board):
122137
raise ValueError("Second argument must be a Bitmap or Display")
138+
pixel_source = board.DISPLAY
139+
123140
if isinstance(pixel_source, Bitmap):
124141
if not isinstance(palette, Palette):
125142
raise ValueError("Third argument must be a Palette for a Bitmap save")

mypy.ini

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-FileCopyrightText: 2022 Matt Land
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
[mypy]
5+
python_version = 3.7
6+
disallow_untyped_defs = True
7+
disable_error_code = no-redef
8+
exclude = (examples|tests|setup.py|docs)

0 commit comments

Comments
 (0)