my changes for some plugins and 2048

This commit is contained in:
RogueMaster
2022-09-16 17:23:45 -04:00
parent 93d5839a51
commit 918c5a8439
25 changed files with 1260 additions and 39 deletions
+69
View File
@@ -0,0 +1,69 @@
#####################################
encode.py
decode.py
iconencode.py
icondecode.py
A set of python3 scripts for processing the Flipper image files.
These work as-is but I am rolling in improvements.
#####################################
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.
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 have the meta.txt available for the animation set the dimensions will be in here.
It may also be part of the directory name for the animation files as well.
If you do not enter anything here it will assume 128x64. THIS WILL NOT ALWAYS BE CORRECT.
##
# encode
Encode an .xbm file into .xb
encode.py input_image output_image
You will also get the image dimensions for use in meta.txt
That's it.
##
# iconencode
Compress an icon asset from an XBM to a compressed char array ready to paste
Will assume dimensions of 128x64
Header works like this, you'll have to do this manually for now!
Image Header Format Example
0x01 = Compressed
0x00 = Reserved Section
0xa4,0x01 = 0x1a4, or, 420 - the size of the compressed array, minus this header. Just count the commas ;)
Rest of the data is char array output from heatshrink of the original XBM char array.
Calculated Header: 0x01,0x00,0xa4,0x01
from furi_hal_compress.c:
typedef struct {
uint8_t is_compressed;
uint8_t reserved;
uint16_t compressed_buff_size;
} FuriHalCompressHeader;
##
# icondecode
Decompress an icon asset (as found in assets_icons.c and elsewhere)
icondecodepy input_image output_image [trim] [width] [height]
The icons in this file have a different header format. This will need to be trimmed.
A value of 8 for trim appears to be correct.
As with regular decoding, the width and height are not listed - but can be found in code/const/variable/etc names.
copy just the char array. The script does not care if the curly braces or semicolon are in place.
i.e. the following are all acceptable and equivalent.
{0x00,0x08,0x1C,0x3E,0x7F,};
{0x00,0x08,0x1C,0x3E,0x7F,}
0x00,0x08,0x1C,0x3E,0x7F
+74
View File
@@ -0,0 +1,74 @@
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. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
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)
r.close()
w.close()
+49
View File
@@ -0,0 +1,49 @@
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())
print("Image Dimensions:")
width = int(f.readline().strip().split(" ")[2])
print("W: ", width)
height = int(f.readline().strip().split(" ")[2])
print("H: ", height)
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)
r.close()
w.close()
+65
View File
@@ -0,0 +1,65 @@
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 icon char arrays 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. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
parser.add_argument('Trim', metavar='T', type=int, nargs="?", default="8",
help='Number of bytes off the start/header to trim. Multiples of 2 required.')
args = vars(parser.parse_args())
r = open(args["infile"],"r")
w = open(args["outfile"],"w")
imageWidth=args["Width"]
imageHeight=args["Height"]
trimStart=args["Trim"]
output = subprocess.check_output(["cat", args["infile"]]) #yes this is terrible.
f = io.StringIO(output.decode().strip())
data = f.read().strip().replace(";","").replace("{","").replace("}","")
data_str = data.replace(",", "").replace("0x", "")
data_bin = bytearray.fromhex(data_str[trimStart:])
data_decoded_str = subprocess.check_output(
["heatshrink", "-d","-w8","-l4"], input=data_bin
)
b=list(data_decoded_str)
c=', '.join(padded_hex(my_int,2) for my_int in b)
width_out = "#define icon_width "+ str(imageWidth) + "\n"
height_out = "#define icon_height "+ str(imageHeight) + "\n"
bytes_out = "static unsigned char icon_bits[] = {"+ str(c) + "};"
data=width_out+height_out+bytes_out
w.write(data)
r.close()
w.close()
+68
View File
@@ -0,0 +1,68 @@
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 icon char arrays back into .xbm')
parser.add_argument('infile', metavar='i',
help='Input file')
parser.add_argument('Width', metavar='W', type=int, nargs="?", default="128",
help='Width of the image. Find from meta.txt or directory name')
parser.add_argument('Height', metavar='H', type=int, nargs="?", default="64",
help='Height of the image. Find from meta.txt or directory name')
args = vars(parser.parse_args())
r = open(args["infile"],"r")
infile=args["infile"].split(".")[0]
imageWidth=args["Width"]
imageHeight=args["Height"]
dims=str(imageWidth)+"x"+str(imageHeight)
output = subprocess.check_output(["cat", args["infile"]]) #yes this is terrible.
f = io.StringIO(output.decode().strip())
data = f.read().strip().replace(";","").replace("{","").replace("}","")
data_str = data.replace(",", "").replace("0x", "")
data_bin = bytearray.fromhex(data_str)
data_encoded_str = subprocess.check_output(
["heatshrink", "-e","-w8","-l4"], input=data_bin
)
b=list(data_encoded_str)
c=','.join(padded_hex(my_int,2) for my_int in b)
# a bit ugly.
framename="_I_"+infile+"_"+dims
print(len(b))
#d=len(b)
# if b > 255 split 0x1234 into 0x34,0x12
#d=hex(len(b))
char_out = "const uint8_t "+framename+"_0[] = {"+ str(c) + ",};"
char_out2 = "const uint8_t "+framename+"[] = {"+framename+"_0};"
#data=bytes_out
print(char_out)
print(char_out2)
#w.write(data)
#w.close()