From 7806382d8e43a7a189157ab12ac632161a8fb8f8 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 29 Jun 2018 17:28:03 +0200 Subject: [PATCH] add RLE support for other bootloader bitmaps as well --- radio/src/bitmaps/480x272/CMakeLists.txt | 51 +++++------ radio/src/gui/480x272/bitmapbuffer.cpp | 4 +- radio/src/gui/480x272/bitmapbuffer.h | 37 ++++++++ radio/src/gui/480x272/splash.cpp | 4 + radio/src/gui/480x272/widgets.cpp | 7 ++ .../targets/horus/bootloader/boot_menu.cpp | 7 ++ radio/util/img2lbm.py | 86 ++++++++++--------- 7 files changed, 126 insertions(+), 70 deletions(-) diff --git a/radio/src/bitmaps/480x272/CMakeLists.txt b/radio/src/bitmaps/480x272/CMakeLists.txt index 34a42f37c..9337292af 100644 --- a/radio/src/bitmaps/480x272/CMakeLists.txt +++ b/radio/src/bitmaps/480x272/CMakeLists.txt @@ -1,31 +1,26 @@ if(PCB STREQUAL X12S) - add_bitmaps_target(x12s_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bmp_*.png" 480 5/6/5) - add_bitmaps_target(x12s_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/bmp_*.png" 480 5/6/5) - add_bitmaps_target(x12s_button_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/button/alpha_*.png" 480 4/4/4/4) - add_bitmaps_target(x12s_alpha_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/alpha_*.png" 480 4/4/4/4) - add_bitmaps_target(x12s_alpha_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/alpha_*.png" 480 4/4/4/4) - add_bitmaps_target(x12s_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/mask_*.png 480 8bits) - add_bitmaps_target(x12s_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/slider/*.png" 480 8bits) - add_bitmaps_target(x12s_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/480x272/layouts/*.png" 480 8bits) - add_bitmaps_target(x12s_themes_bitmaps "${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.png" 480 5/6/5) - add_bitmaps_target(x12s_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits rle) - add_bitmaps_target(x12s_volume_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/volume/*.png 480 8bits) - add_bitmaps_target(x12s_bootloader_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/bmp_*.png 480 5/6/5) - add_bitmaps_target(x12s_bootloader_icons ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/icon_*.png 480 8bits) - add_dependencies(x12s_bitmaps x12s_calibration_bitmaps x12s_button_bitmaps x12s_alpha_bitmaps x12s_alpha_calibration_bitmaps x12s_masks x12s_slider_masks x12s_layouts_masks x12s_themes_bitmaps x12s_fonts x12s_volume_masks x12s_bootloader_bitmaps x12s_bootloader_icons) + set(BITMAP_TARGET_PREFIX x12s) + set(BITMAP_FMT_SUFFIX "") else() - add_bitmaps_target(x10_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bmp_*.png" 480 5/6/5-R) - add_bitmaps_target(x10_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/bmp_*.png" 480 5/6/5-R) - add_bitmaps_target(x10_button_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/button/alpha_*.png" 480 4/4/4/4-R) - add_bitmaps_target(x10_alpha_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/alpha_*.png" 480 4/4/4/4-R) - add_bitmaps_target(x10_alpha_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/alpha_*.png" 480 4/4/4/4-R) - add_bitmaps_target(x10_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/mask_*.png 480 8bits) - add_bitmaps_target(x10_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/slider/*.png" 480 8bits) - add_bitmaps_target(x10_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/480x272/layouts/*.png" 480 8bits) - add_bitmaps_target(x10_themes_bitmaps "${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.png" 480 5/6/5-R) - add_bitmaps_target(x10_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits rle) - add_bitmaps_target(x10_volume_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/volume/*.png 480 8bits) - add_bitmaps_target(x10_bootloader_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/bmp_*.png 480 5/6/5-R) - add_bitmaps_target(x10_bootloader_icons ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/icon_*.png 480 8bits) - add_dependencies(x10_bitmaps x10_calibration_bitmaps x10_button_bitmaps x10_alpha_bitmaps x10_alpha_calibration_bitmaps x10_masks x10_slider_masks x10_layouts_masks x10_themes_bitmaps x10_fonts x10_volume_masks x10_bootloader_bitmaps x10_bootloader_icons) + set(BITMAP_TARGET_PREFIX x10) + set(BITMAP_FMT_SUFFIX "-R") endif() + +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bmp_*.png" 480 "5/6/5${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/bmp_*.png" 480 "5/6/5${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_button_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/button/alpha_*.png" 480 "4/4/4/4${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_alpha_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/alpha_*.png" 480 "4/4/4/4${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_alpha_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/calibration/alpha_*.png" 480 "4/4/4/4${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/mask_*.png 480 8bits) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/480x272/slider/*.png" 480 8bits) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/480x272/layouts/*.png" 480 8bits) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_themes_bitmaps "${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.png" 480 "5/6/5${BITMAP_FMT_SUFFIX}") +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_fonts ${RADIO_SRC_DIRECTORY}/fonts/480x272/*.png 480 8bits rle) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_volume_masks ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/volume/*.png 480 8bits) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_bootloader_bitmaps ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/bmp_*.png 480 "5/6/5${BITMAP_FMT_SUFFIX}" rle) +add_bitmaps_target(${BITMAP_TARGET_PREFIX}_bootloader_icons ${RADIO_SRC_DIRECTORY}/bitmaps/480x272/bootloader/icon_*.png 480 8bits) + +add_dependencies(${BITMAP_TARGET_PREFIX}_bitmaps ${BITMAP_TARGET_PREFIX}_calibration_bitmaps ${BITMAP_TARGET_PREFIX}_button_bitmaps ${BITMAP_TARGET_PREFIX}_alpha_bitmaps + ${BITMAP_TARGET_PREFIX}_alpha_calibration_bitmaps ${BITMAP_TARGET_PREFIX}_masks ${BITMAP_TARGET_PREFIX}_slider_masks ${BITMAP_TARGET_PREFIX}_layouts_masks + ${BITMAP_TARGET_PREFIX}_themes_bitmaps ${BITMAP_TARGET_PREFIX}_fonts ${BITMAP_TARGET_PREFIX}_volume_masks ${BITMAP_TARGET_PREFIX}_bootloader_bitmaps + ${BITMAP_TARGET_PREFIX}_bootloader_icons) diff --git a/radio/src/gui/480x272/bitmapbuffer.cpp b/radio/src/gui/480x272/bitmapbuffer.cpp index 204249e99..d75334c71 100644 --- a/radio/src/gui/480x272/bitmapbuffer.cpp +++ b/radio/src/gui/480x272/bitmapbuffer.cpp @@ -489,6 +489,8 @@ void BitmapBuffer::drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t * } } +#if !defined(BOOT) + BitmapBuffer * BitmapBuffer::load(const char * filename) { const char * ext = getFileExtension(filename); @@ -743,7 +745,6 @@ void *stb_realloc(void *ptr, unsigned int oldsz, unsigned int newsz) } #endif // #if defined(TRACE_STB_MALLOC) - #include "thirdparty/Stb/stb_image.h" // fill 'data' with 'size' bytes. return number of bytes actually read @@ -831,3 +832,4 @@ BitmapBuffer * BitmapBuffer::load_stb(const char * filename) stbi_image_free(img); return bmp; } +#endif diff --git a/radio/src/gui/480x272/bitmapbuffer.h b/radio/src/gui/480x272/bitmapbuffer.h index d4be9dd45..19074f8f7 100644 --- a/radio/src/gui/480x272/bitmapbuffer.h +++ b/radio/src/gui/480x272/bitmapbuffer.h @@ -23,6 +23,7 @@ #include #include "colors.h" +#include "rle.h" #if defined(PCBX10) && !defined(SIMU) #define MOVE_PIXEL_RIGHT(p, count) p -= count @@ -59,6 +60,16 @@ class BitmapBufferBase { } + BitmapBufferBase(uint8_t format, T * data): + format(format), + data(data), + data_end(NULL) + { + width = *((uint16_t*)data); + height = *(((uint16_t*)data)+1); + data_end = data + 4 + (width * height); + } + inline uint8_t getFormat() const { return format; @@ -103,6 +114,28 @@ class BitmapBufferBase typedef BitmapBufferBase Bitmap; +class RLEBitmap: + public BitmapBufferBase +{ +public: + RLEBitmap(uint8_t format, const uint8_t* rle_data) + : BitmapBufferBase(format, 0, 0, NULL) + { + width = *((uint16_t *)rle_data); + height = *(((uint16_t *)rle_data)+1); + + uint32_t pixels = width * height; + data = (uint16_t*)malloc(pixels * sizeof(uint16_t)); + rle_decode_8bit((uint8_t*)data, pixels * sizeof(uint16_t), rle_data+4); + data_end = data + pixels; + } + + ~RLEBitmap() + { + free(data); + } +}; + class BitmapBuffer: public BitmapBufferBase { private: @@ -231,11 +264,13 @@ class BitmapBuffer: public BitmapBufferBase void drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t * img, LcdFlags flags, int startAngle, int endAngle); +#if !defined(BOOT) static BitmapBuffer * load(const char * filename); static BitmapBuffer * loadMask(const char * filename); static BitmapBuffer * loadMaskOnBackground(const char * filename, LcdFlags foreground, LcdFlags background); +#endif void drawMask(coord_t x, coord_t y, BitmapBuffer * mask, LcdFlags flags, coord_t offset=0, coord_t width=0); @@ -325,8 +360,10 @@ class BitmapBuffer: public BitmapBufferBase } protected: +#if !defined(BOOT) static BitmapBuffer * load_bmp(const char * filename); static BitmapBuffer * load_stb(const char * filename); +#endif }; extern BitmapBuffer * lcd; diff --git a/radio/src/gui/480x272/splash.cpp b/radio/src/gui/480x272/splash.cpp index 4ed8b200d..64c45efb1 100644 --- a/radio/src/gui/480x272/splash.cpp +++ b/radio/src/gui/480x272/splash.cpp @@ -22,7 +22,10 @@ #if defined(SPLASH) +const uint8_t __bmp_splash[] { #include "bmp_splash.lbm" +}; +Bitmap BMP_SPLASH(BMP_RGB565, (const uint16_t*)__bmp_splash); void drawSplash() { @@ -45,6 +48,7 @@ void drawSplash() splashImg); } else { + // TODO: verify / load / decompress bitmap lcd->drawBitmap((LCD_W - BMP_SPLASH.getWidth())/2, (LCD_H - BMP_SPLASH.getHeight())/2, &BMP_SPLASH); diff --git a/radio/src/gui/480x272/widgets.cpp b/radio/src/gui/480x272/widgets.cpp index b3a56fc58..0557a15fe 100644 --- a/radio/src/gui/480x272/widgets.cpp +++ b/radio/src/gui/480x272/widgets.cpp @@ -34,8 +34,15 @@ void drawColumnHeader(const char * const * headers, const char * const * descrip } } +const uint8_t __alpha_button_on[] { #include "alpha_button_on.lbm" +}; +Bitmap ALPHA_BUTTON_ON(BMP_ARGB4444, (const uint16_t*)__alpha_button_on); + +const uint8_t __alpha_button_off[] { #include "alpha_button_off.lbm" +}; +Bitmap ALPHA_BUTTON_OFF(BMP_ARGB4444, (const uint16_t*)__alpha_button_off); void drawButton(coord_t x, coord_t y, const char * label, LcdFlags attr) { diff --git a/radio/src/targets/horus/bootloader/boot_menu.cpp b/radio/src/targets/horus/bootloader/boot_menu.cpp index 23b711c34..6d6d1fce4 100644 --- a/radio/src/targets/horus/bootloader/boot_menu.cpp +++ b/radio/src/targets/horus/bootloader/boot_menu.cpp @@ -4,8 +4,15 @@ #define SELECTED_COLOR (INVERS | TEXT_COLOR) +const uint8_t __bmp_plug_usb_rle[] { #include "bmp_plug_usb.lbm" +}; +RLEBitmap BMP_PLUG_USB(BMP_RGB565, __bmp_plug_usb_rle); + +const uint8_t __bmp_usb_plugged_rle[] { #include "bmp_usb_plugged.lbm" +}; +RLEBitmap BMP_USB_PLUGGED(BMP_RGB565, __bmp_usb_plugged_rle); const uint8_t LBM_FLASH[] = { #include "icon_flash.lbm" diff --git a/radio/util/img2lbm.py b/radio/util/img2lbm.py index 692a8efd0..40d2dc69c 100755 --- a/radio/util/img2lbm.py +++ b/radio/util/img2lbm.py @@ -69,6 +69,16 @@ def F_writeValue(f): f.write("0x%02x," % value) return writeValue +def F_getPixelCoord(): + def getCoord(x,y): + return (x,y) + return getCoord + +def F_getPixelCoord_R(w,h): + def getCoord(x,y): + return (w-x-1, h-y-1) + return getCoord + ## MAIN ## image = Image.open(sys.argv[1]) @@ -81,7 +91,11 @@ with open(output_filename, "w") as f: lcdwidth = int(sys.argv[3]) if len(sys.argv) > 4: - what = sys.argv[4] + s = sys.argv[4].split('-') + what = s[0] + pixel_coord = F_getPixelCoord() + if (len(s) > 1) and (s[1] == 'R'): + pixel_coord = F_getPixelCoord_R(width,height) else: for s in ("03x05", "04x06", "05x07", "08x10", "10x14", "22x38"): if s in sys.argv[2]: @@ -116,46 +130,6 @@ with open(output_filename, "w") as f: encoder.encode_byte(value) f.write("\n") encoder.encode_end() - elif what == "4/4/4/4": - constant = sys.argv[2].upper()[:-4] - values = [] - for y in range(height): - for x in range(width): - pixel = image.getpixel((x, y)) - val = ((pixel[3] // 16) << 12) + ((pixel[0] // 16) << 8) + ((pixel[1] // 16) << 4) + ((pixel[2] // 16) << 0) - values.append(str(val)) - f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(BMP_ARGB4444, %d, %d, __%s);\n" % (constant, width, height, constant)) - elif what == "4/4/4/4-R": - constant = sys.argv[2].upper()[:-4] - values = [] - for y in range(height): - for x in range(width): - pixel = image.getpixel((width-x-1, height-y-1)) - val = ((pixel[3] // 16) << 12) + ((pixel[0] // 16) << 8) + ((pixel[1] // 16) << 4) + ((pixel[2] // 16) << 0) - values.append(str(val)) - f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(BMP_ARGB4444, %d, %d, __%s);\n" % (constant, width, height, constant)) - elif what == "5/6/5": - constant = sys.argv[2].upper()[:-4] - values = [] - for y in range(height): - for x in range(width): - pixel = image.getpixel((x, y)) - val = ((pixel[0] >> 3) << 11) + ((pixel[1] >> 2) << 5) + ((pixel[2] >> 3) << 0) - values.append(str(val)) - f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(BMP_RGB565, %d, %d, __%s);\n" % (constant, width, height, constant)) - elif what == "5/6/5-R": - constant = sys.argv[2].upper()[:-4] - values = [] - for y in range(height): - for x in range(width): - pixel = image.getpixel((width-x-1, height-y-1)) - val = ((pixel[0] >> 3) << 11) + ((pixel[1] >> 2) << 5) + ((pixel[2] >> 3) << 0) - values.append(str(val)) - f.write("const uint16_t __%s[] __ALIGNED = { %s };\n" % (constant, ",".join(values))) - f.write("const Bitmap %s(BMP_RGB565, %d, %d, __%s);\n" % (constant, width, height, constant)) elif what == "4bits": colors = [] writeSize(f, width, height) @@ -187,6 +161,36 @@ with open(output_filename, "w") as f: encoder.encode_byte(value) f.write("\n") encoder.encode_end() + elif what == "4/4/4/4": + constant = sys.argv[2].upper()[:-4] + values = [] + #f.write("const uint8_t __%s[] __ALIGNED = {\n" % constant) + writeSize(f, width, height) + for y in range(height): + for x in range(width): + pixel = image.getpixel(pixel_coord(x, y)) + val = ((pixel[3] // 16) << 12) + ((pixel[0] // 16) << 8) + ((pixel[1] // 16) << 4) + ((pixel[2] // 16) << 0) + encoder.encode_byte(val & 255) + encoder.encode_byte(val >> 8) + encoder.encode_end() + #f.write("\n};\n") + #if extension != ".rle": + # f.write("const Bitmap %s(BMP_ARGB4444, %d, %d, (uint16_t*)__%s);\n" % (constant, width, height, constant)) + elif what == "5/6/5": + constant = sys.argv[2].upper()[:-4] + values = [] + #f.write("const uint8_t __%s[] __ALIGNED = {\n" % constant) + writeSize(f, width, height) + for y in range(height): + for x in range(width): + pixel = image.getpixel(pixel_coord(x, y)) + val = ((pixel[0] >> 3) << 11) + ((pixel[1] >> 2) << 5) + ((pixel[2] >> 3) << 0) + encoder.encode_byte(val & 255) + encoder.encode_byte(val >> 8) + encoder.encode_end() + #f.write("\n};\n") + #if extension != ".rle": + # f.write("const Bitmap %s(BMP_RGB565, %d, %d, (uint16_t*)__%s);\n" % (constant, width, height, constant)) elif what == "03x05": image = image.convert(mode='L') for y in range(0, height, 5):