Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utility scripts for processing some of the flipper file formats directly #42

Merged
merged 13 commits into from
Jun 3, 2022
23 changes: 23 additions & 0 deletions scripts/User/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
encode.py
decode.py
A set of python3 scripts for processing the Flipper image files.


PREREQUISITES
You'll need heatshrink installed - a small embedded/RTOS compression and decompression library
You can get that here https://github.com/atomicobject/heatshrink


HOW TO USE
Decode a .mb into .xbm:
decode.py input_image output_image [width] [height]
Dimensions are not stored in .bm so you need to specify.
If you do not enter anything here it will assume 128x64. THIS WILL NOT ALWAYS BE CORRECT.


Encode an .xbm file into .xb
encode.py input_image output_image
That's it.



72 changes: 72 additions & 0 deletions scripts/User/decode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import logging
import argparse
import subprocess
import io
import os
import sys



def padded_hex(i, l):
given_int = i
given_len = l

hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
num_hex_chars = len(hex_result)
extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..

return ('0x' + hex_result if num_hex_chars == given_len else
'?' * given_len if num_hex_chars > given_len else
'0x' + extra_zeros + hex_result if num_hex_chars < given_len else
None)

parser = argparse.ArgumentParser(description='Turn cooked Flipper .bm files back into .xbm')

parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('outfile', metavar='o',
help='File to write to')
parser.add_argument('Width', metavar='W', type=int, nargs="?", default="128",
help='Width of the image')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image')

args = vars(parser.parse_args())

r = open(args["infile"],"rb")
w = open(args["outfile"],"w")

fileStream=r.read()
filename=os.path.splitext(os.path.basename(args["outfile"]))[0]


imageWidth=args["Width"]
imageHeight=args["Height"]


#remove headers and padding
if(fileStream[0:2] == bytes([0x01,0x00])):
unpad=fileStream[4:]
else:
if(fileStream[0:1] == bytes([0x00])):
unpad=fileStream[2:]



#lzss decompress
data_decoded_str = subprocess.check_output(
["heatshrink", "-d","-w8","-l4"], input=unpad
)

#turn it back into xbm

b=list(data_decoded_str)
c=', '.join(padded_hex(my_int,2) for my_int in b)

width_out = "#define "+ filename+ "_width "+ str(imageWidth) + "\n"
height_out = "#define "+ filename+ "_height "+ str(imageHeight) + "\n"
bytes_out = "static unsigned char "+ filename+ "_bits[] = {"+ str(c) + "};"

data=width_out+height_out+bytes_out

w.write(data)
43 changes: 43 additions & 0 deletions scripts/User/encode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import logging
import argparse
import subprocess
import io
import os
import sys


parser = argparse.ArgumentParser(description='Turn .xbm files into cooked .bm files for flipper FS')

parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('outfile', metavar='o',
help='File to write to')

args = vars(parser.parse_args())

r = open(args["infile"],"r")
w = open(args["outfile"],"wb")


output = subprocess.check_output(["cat", args["infile"]])
f = io.StringIO(output.decode().strip())
width = int(f.readline().strip().split(" ")[2])
height = int(f.readline().strip().split(" ")[2])

data = f.read().strip().replace("\n", "").replace(" ", "").split("=")[1][:-1]
data_str = data[1:-1].replace(",", " ").replace("0x", "")

data_bin = bytearray.fromhex(data_str)
data_encoded_str = subprocess.check_output(
["heatshrink", "-e", "-w8", "-l4"], input=data_bin
)

assert data_encoded_str

data_enc = bytearray(data_encoded_str)
data_enc = bytearray([len(data_enc) & 0xFF, len(data_enc) >> 8]) + data_enc
if len(data_enc) < len(data_bin) + 1:
data = b"\x01\x00" + data_enc
else:
data = b"\x00" + data_bin
w.write(data)