Skip to content

Commit

Permalink
Fix CI issues (Linter on Python code & Type checking)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmorais-ledger committed Jul 26, 2023
1 parent 4c627d0 commit 86cf2ba
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 54 deletions.
1 change: 0 additions & 1 deletion speculos/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import sys
import threading
import pkg_resources
from distutils.spawn import find_executable
from elftools.elf.elffile import ELFFile
from mnemonic import mnemonic
from typing import Optional, Type
Expand Down
47 changes: 24 additions & 23 deletions speculos/mcu/bagl_font.py
Original file line number Diff line number Diff line change
Expand Up @@ -3061,29 +3061,30 @@
]

FONTS = [
Font(BAGL_FONT_LUCIDA_CONSOLE_8PX, 1, 8, 16, 0, 0x0020, 0x00ff, charactersLUCIDA_CONSOLE_6PT_8H,
bitmapLUCIDA_CONSOLE_6PT_8H),
Font(BAGL_FONT_OPEN_SANS_LIGHT_16_22PX, 4, 22, 16, 0, 0x0020, 0x007f, charactersOPEN_SANS_LIGHT_16_22PX,
bitmapOPEN_SANS_LIGHT_16_22PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 4, 11, 8, 0, 0x0020, 0x007f, charactersOPEN_SANS_REGULAR_8_11PX,
bitmapOPEN_SANS_REGULAR_8_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 4, 14, 10, 0, 0x0020, 0x007F, charactersOPEN_SANS_REGULAR_10_13PX,
bitmapOPEN_SANS_REGULAR_10_13PX),
Font(BAGL_FONT_OPEN_SANS_EXTRABOLD_11px, 1, 12, 9, 0, 0x0020, 0x007F, charactersOPEN_SANS_EXTRABOLD_11PX,
bitmapOPEN_SANS_EXTRABOLD_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_11px, 1, 12, 9, 0, 0x0020, 0x007F, charactersOPEN_SANS_REGULAR_11PX,
bitmapOPEN_SANS_REGULAR_11PX),
Font(BAGL_FONT_OPEN_SANS_LIGHT_16px, 1, 18, 13, 0, 0x0020, 0x007F, charactersOPEN_SANS_LIGHT_16PX,
bitmapOPEN_SANS_LIGHT_16PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX, 4, 14, 10, 0, 0x0020, 0x007f, charactersOPEN_SANS_SEMIBOLD_10_13PX,
bitmapOPEN_SANS_SEMIBOLD_10_13PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 4, 11, 8, 0, 0x0020, 0x007f, charactersOPEN_SANS_SEMIBOLD_8_11PX,
bitmapOPEN_SANS_SEMIBOLD_8_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_11_14PX, 4, 16, 12, 0, 0x0020, 0x007f, charactersOPEN_SANS_REGULAR_11_14PX,
bitmapOPEN_SANS_REGULAR_11_14PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_11_16PX, 4, 16, 12, 0, 0x0020, 0x007f, charactersOPEN_SANS_SEMIBOLD_11_16PX,
bitmapOPEN_SANS_SEMIBOLD_11_16PX),
Font(BAGL_FONT_SYMBOLS_0, 4, 16, 16, 0, 0x0000, 0x0006, charactersSYMBOLS_0, bitmapSYMBOLS_0)
Font(BAGL_FONT_LUCIDA_CONSOLE_8PX, 1, 8, 16, 0, 0x0020, 0x00ff,
charactersLUCIDA_CONSOLE_6PT_8H, bitmapLUCIDA_CONSOLE_6PT_8H),
Font(BAGL_FONT_OPEN_SANS_LIGHT_16_22PX, 4, 22, 16, 0, 0x0020, 0x007f,
charactersOPEN_SANS_LIGHT_16_22PX, bitmapOPEN_SANS_LIGHT_16_22PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 4, 11, 8, 0, 0x0020, 0x007f,
charactersOPEN_SANS_REGULAR_8_11PX, bitmapOPEN_SANS_REGULAR_8_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 4, 14, 10, 0, 0x0020, 0x007F,
charactersOPEN_SANS_REGULAR_10_13PX, bitmapOPEN_SANS_REGULAR_10_13PX),
Font(BAGL_FONT_OPEN_SANS_EXTRABOLD_11px, 1, 12, 9, 0, 0x0020, 0x007F,
charactersOPEN_SANS_EXTRABOLD_11PX, bitmapOPEN_SANS_EXTRABOLD_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_11px, 1, 12, 9, 0, 0x0020, 0x007F,
charactersOPEN_SANS_REGULAR_11PX, bitmapOPEN_SANS_REGULAR_11PX),
Font(BAGL_FONT_OPEN_SANS_LIGHT_16px, 1, 18, 13, 0, 0x0020, 0x007F,
charactersOPEN_SANS_LIGHT_16PX, bitmapOPEN_SANS_LIGHT_16PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX, 4, 14, 10, 0, 0x0020, 0x007f,
charactersOPEN_SANS_SEMIBOLD_10_13PX, bitmapOPEN_SANS_SEMIBOLD_10_13PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 4, 11, 8, 0, 0x0020, 0x007f,
charactersOPEN_SANS_SEMIBOLD_8_11PX, bitmapOPEN_SANS_SEMIBOLD_8_11PX),
Font(BAGL_FONT_OPEN_SANS_REGULAR_11_14PX, 4, 16, 12, 0, 0x0020, 0x007f,
charactersOPEN_SANS_REGULAR_11_14PX, bitmapOPEN_SANS_REGULAR_11_14PX),
Font(BAGL_FONT_OPEN_SANS_SEMIBOLD_11_16PX, 4, 16, 12, 0, 0x0020, 0x007f,
charactersOPEN_SANS_SEMIBOLD_11_16PX, bitmapOPEN_SANS_SEMIBOLD_11_16PX),
Font(BAGL_FONT_SYMBOLS_0, 4, 16, 16, 0, 0x0000, 0x0006,
charactersSYMBOLS_0, bitmapSYMBOLS_0)
]


Expand Down
2 changes: 1 addition & 1 deletion speculos/mcu/nbgl.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,6 @@ def hal_draw_image_rle(self, data):
buffer += RLECustom.decode(1, bitmap, bpp)

# Display the uncompressed image
transformation = 0 # NO_TRANSFORMATION
transformation = 0 # NO_TRANSFORMATION
color_map = data[nbgl_area_t.sizeof() + len(bitmap)] # front color in case of BPP4
self.draw_image(area, bpp, transformation, buffer, color_map)
44 changes: 23 additions & 21 deletions speculos/mcu/ocr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
import string
from dataclasses import dataclass
from typing import List, Optional, Mapping
from typing import Dict, List, Mapping
from speculos.observer import TextEvent
from . import bagl_font

Expand All @@ -30,7 +30,13 @@
Char = str # a single character string (chars are 1-char strings in Python)


__FONT_MAP = {}
@dataclass
class BitMapChar:
char: bagl_font.FontCharacter
bitmap: bytes


__FONT_MAP: Dict[int, Mapping[str, BitMapChar]] = {}

DISPLAY_CHARS = string.ascii_letters + string.digits + string.punctuation

Expand All @@ -46,12 +52,6 @@ def wrapper(byte_string: bytes):
return wrapper


@dataclass
class BitMapChar:
char: bagl_font.FontCharacter
bitmap: bytes


def split(bits: BitVector, n: Width) -> List[BitVector]:
"""
Split a bit array (string of '1' and '0')
Expand Down Expand Up @@ -125,8 +125,8 @@ class OCR:
MAX_BLANK_SPACE = 12
# Font names for LNX & LNS+ (most used ones first)
FONT_NAMES_NANOX_NANOSP = ["bagl_font_open_sans_regular_11px",
"bagl_font_open_sans_extrabold_11px",
"bagl_font_open_sans_light_16px"]
"bagl_font_open_sans_extrabold_11px",
"bagl_font_open_sans_light_16px"]
# Font names for stax (most used ones first)
FONT_NAMES_STAX = ["nbgl_font_inter_regular_24",
"nbgl_font_inter_semibold_24",
Expand All @@ -137,12 +137,12 @@ class OCR:
"nbgl_font_hmalpha_mono_medium_32"]

def __init__(self,
fonts_path:str,
model:str,
api_level:int):
fonts_path: str,
model: str,
api_level: int):
self.events: List[TextEvent] = []
# To keep track of loaded JSON fonts
self.json_fonts = []
self.json_fonts: List[Dict] = []
# By default use legacy OCR (built-in font bitmaps)
self.legacy = True
# Maximum space for a letter to be considered part of the same word
Expand Down Expand Up @@ -172,7 +172,7 @@ def __init__(self,
self.legacy = False
else:
logger = logging.getLogger("OCR")
logger.warning("WARNING: didn't find any JSON font files => "\
logger.warning("WARNING: didn't find any JSON font files => "
"OCR will not work properly!\n")

def get_json_font(self, name, struct_name) -> None:
Expand All @@ -185,9 +185,9 @@ def get_json_font(self, name, struct_name) -> None:

# Deserialize bitmap
bitmap = base64.b64decode(font_info['bitmap'])
if not struct_name in font_info:
if struct_name not in font_info:
logger = logging.getLogger("OCR")
logger.warning(f"WARNING: didn't find field '{struct_name}' "\
logger.warning(f"WARNING: didn't find field '{struct_name}' "
f"in {name} => this font will be ignored!\n")
return
# Build BitMapChar
Expand All @@ -204,7 +204,7 @@ def get_json_font(self, name, struct_name) -> None:
self.json_fonts.append(font_map)

@staticmethod
def find_char_from_bitmap_legacy(bitmap: BitMap) -> Optional[str]:
def find_char_from_bitmap_legacy(bitmap: BitMap) -> str:
"""
Find a character from a bitmap
>>> font = get_font(4)
Expand All @@ -228,9 +228,10 @@ def find_char_from_bitmap_legacy(bitmap: BitMap) -> Optional[str]:
if char == "\x80":
char = " "
return char
return ""

def find_bitmap_legacy(self, x: int, y: int, w: int, h: int,
bitmap: bytes) -> None:
bitmap: bytes) -> None:
char = self.find_char_from_bitmap_legacy(bitmap)
if char:
if self.events and y <= self.events[-1].y:
Expand All @@ -240,7 +241,7 @@ def find_bitmap_legacy(self, x: int, y: int, w: int, h: int,
# or if there is a new line
self.events.append(TextEvent(char, x, y, w, h))

def find_char_from_bitmap(self, bitmap: BitMap) -> Optional[str]:
def find_char_from_bitmap(self, bitmap: BitMap) -> str:
"""
Parse loaded JSON fonts and compare font bitmaps with the one provided
"""
Expand All @@ -254,8 +255,9 @@ def find_char_from_bitmap(self, bitmap: BitMap) -> Optional[str]:
if char == "\x80":
char = " "
return char
return ""

def store_char_in_last_event(self, x: int, y: int, w: int, h:int, char:str) -> None:
def store_char_in_last_event(self, x: int, y: int, w: int, h: int, char: str) -> None:
"""
Add current character to last event
"""
Expand Down
26 changes: 18 additions & 8 deletions speculos/mcu/rle_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import argparse
import sys


# -----------------------------------------------------------------------------
# Regular RLE encoding
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -299,6 +300,7 @@ def get_encoded_size(data):
"""
return len(data)


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -370,6 +372,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte +
# - white handling
Expand Down Expand Up @@ -474,6 +477,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte +
# - white handling
Expand Down Expand Up @@ -559,7 +563,7 @@ def encode_pass2(pairs, max_count=64):
if count > 6:
# Special case: if count = 8 then do 5+3
if count == 8:
count = 5 # to allow storing next 3 singles!!
count = 5 # to allow storing next 3 singles!!
else:
count = 6
# Do we have at least 3 singles?
Expand All @@ -578,13 +582,13 @@ def encode_pass2(pairs, max_count=64):
index += 1
count -= 1
while count > 0:
byte = single_output[index] # No need to mask
byte = single_output[index] # No need to mask
index += 1
count -= 1
byte <<= 4
# Do we have an other quartet?
if count > 0:
byte |= single_output[index] # No need to mask
byte |= single_output[index] # No need to mask
index += 1
count -= 1
# Store the quartet(s)
Expand Down Expand Up @@ -667,6 +671,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -736,6 +741,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -772,7 +778,7 @@ def encode_pass2(self, pairs, max_count=64):
infos = []
index = 0
if self.bpp == 1:
#threshold = 7
# threshold = 7
threshold = 2
else:
threshold = 3
Expand Down Expand Up @@ -884,11 +890,12 @@ def get_encoded_size(self, data):
pixels_size += 1

sys.stdout.write(f"Nb pixels: {total_pixels}\n")
sys.stdout.write(f"sizes: cmd={cmd_size}, count={count_size}"\
sys.stdout.write(f"sizes: cmd={cmd_size}, count={count_size}"
f", data={pixels_size}\n")

return cmd_size + count_size + pixels_size


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -988,6 +995,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Custom RLE encoding: pack repeat count & value into 1 byte
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1091,6 +1099,7 @@ def decode_pass2(self, data):

return pairs


# -----------------------------------------------------------------------------
# Entry point for easy RLE encoding/decoding
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1151,6 +1160,7 @@ def decode(cls, method, encoded_data, bpp, verbose=False):

return decoded


# -----------------------------------------------------------------------------
# Program entry point:
# -----------------------------------------------------------------------------
Expand All @@ -1161,7 +1171,7 @@ def main(args):
"""
Main method.
"""
#ascii 0x0040 (88 bytes)
# ascii 0x0040 (88 bytes)
data = bytes([
0x00, 0x7F, 0xE0, 0x00, 0x1F, 0xFF, 0x00, 0x07,
0xC0, 0x38, 0x00, 0xF0, 0x01, 0x80, 0x1E, 0x00,
Expand All @@ -1178,7 +1188,7 @@ def main(args):
with RLECustomA(args.bpp, args.verbose) as rle:
compressed = rle.encode(data)
encoded_size = rle.get_encoded_size(compressed)
sys.stdout.write(f"Encoded size: {encoded_size} bytes "\
sys.stdout.write(f"Encoded size: {encoded_size} bytes "
f"(instead of {len(data)})\n")
# No need to check if decoding is fine, already done when encoding

Expand All @@ -1197,7 +1207,7 @@ def main(args):

parser.add_argument(
"-v", "--verbose",
action = 'store_true',
action='store_true',
help="Add verbosity to output ('%(default)s' by default)")

# Call main function:
Expand Down
1 change: 1 addition & 0 deletions speculos/mcu/seproxyhal.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ def can_read(self, screen: DisplayNotifier):
screen.display.gl.hal_draw_image(data)

elif tag == SephTag.NBGL_DRAW_IMAGE_RLE:
assert isinstance(screen.display.gl, NBGL)
self.ocr.analyze_bitmap(data)
screen.display.gl.hal_draw_image_rle(data)

Expand Down

0 comments on commit 86cf2ba

Please sign in to comment.