diff --git a/components/lcd/esp_lcd_ssd1681/esp_lcd_panel_ssd1681.c b/components/lcd/esp_lcd_ssd1681/esp_lcd_panel_ssd1681.c index 2cec32e07..c3aa381c8 100644 --- a/components/lcd/esp_lcd_ssd1681/esp_lcd_panel_ssd1681.c +++ b/components/lcd/esp_lcd_ssd1681/esp_lcd_panel_ssd1681.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "sdkconfig.h" + #if CONFIG_LCD_ENABLE_DEBUG_LOG // The local log level must be defined before including esp_log.h // Set the maximum log level for this source file @@ -23,10 +24,8 @@ #include "esp_lcd_panel_vendor.h" #include "esp_lcd_ssd1681_commands.h" +// TODO: valid for 1.54 inch 200x200 display. Might not be valid for others. #define SSD1681_LUT_SIZE 159 -#define SSD1681_EPD_1IN54_V2_WIDTH 200 -#define SSD1681_EPD_1IN54_V2_HEIGHT 200 - static const char *TAG = "lcd_panel.epaper"; @@ -45,6 +44,8 @@ typedef struct { // Configurations from epaper_ssd1681_conf int busy_gpio_num; bool full_refresh; + int display_x; // width in pixels + int display_y; // height in pixels // Configurations from interface functions int gap_x; int gap_y; @@ -150,6 +151,8 @@ static esp_err_t epaper_set_lut(esp_lcd_panel_io_handle_t io, const uint8_t *lut static esp_err_t epaper_set_cursor(esp_lcd_panel_io_handle_t io, uint32_t cur_x, uint32_t cur_y) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "set_cursor: x,y = %lu, %lu", cur_x, cur_y); ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, SSD1681_CMD_SET_INIT_X_ADDR_COUNTER, (uint8_t[]) { (uint8_t)((cur_x >> 3) & 0xff) }, 1), TAG, "SSD1681_CMD_SET_INIT_X_ADDR_COUNTER err"); @@ -164,12 +167,13 @@ static esp_err_t epaper_set_cursor(esp_lcd_panel_io_handle_t io, uint32_t cur_x, static esp_err_t epaper_set_area(esp_lcd_panel_io_handle_t io, uint32_t start_x, uint32_t start_y, uint32_t end_x, uint32_t end_y) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "epaper_set_area: start_xy=(%lu,%lu), end_xy=(%lu,%lu)", start_x, start_y, end_x, end_y); // --- Set RAMX Start/End Position ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, SSD1681_CMD_SET_RAMX_START_END_POS, (uint8_t[]) { (start_x >> 3) & 0xff, // start_x (end_x >> 3) & 0xff // end_x }, 2), TAG, "SSD1681_CMD_SET_RAMX_START_END_POS err"); - // --- Set RAMY Start/End Position ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, SSD1681_CMD_SET_RAMY_START_END_POS, (uint8_t[]) { (start_y) & 0xff, // start_y[7:0] @@ -192,6 +196,9 @@ static esp_err_t panel_epaper_wait_busy(esp_lcd_panel_t *panel) esp_err_t panel_epaper_set_vram(esp_lcd_panel_io_handle_t io, uint8_t *bw_bitmap, uint8_t *red_bitmap, size_t size) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "panel_epaper_set_vram: size = %u", size); + // Note: the screen region to be used to draw bitmap had been defined // The region of BLACK VRAM and RED VRAM are set by the same series of command, the two bitmaps will be drawn at // the same region, so the two bitmaps can share a same size. @@ -242,9 +249,7 @@ esp_err_t esp_lcd_new_panel_ssd1681(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel_dev_config_t *const panel_dev_config, esp_lcd_panel_handle_t *const ret_panel) { -#if CONFIG_LCD_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); -#endif ESP_RETURN_ON_FALSE(io && panel_dev_config && ret_panel, ESP_ERR_INVALID_ARG, TAG, "1 or more args is NULL"); esp_lcd_ssd1681_config_t *epaper_ssd1681_conf = panel_dev_config->vendor_config; esp_err_t ret = ESP_OK; @@ -270,6 +275,8 @@ esp_lcd_new_panel_ssd1681(const esp_lcd_panel_io_handle_t io, const esp_lcd_pane epaper_panel->busy_gpio_num = epaper_ssd1681_conf->busy_gpio_num; epaper_panel->reset_level = panel_dev_config->flags.reset_active_high; epaper_panel->_non_copy_mode = epaper_ssd1681_conf->non_copy_mode; + epaper_panel->display_x = epaper_ssd1681_conf->display_x; + epaper_panel->display_y = epaper_ssd1681_conf->display_y; // functions epaper_panel->base.del = epaper_panel_del; epaper_panel->base.reset = epaper_panel_reset; @@ -283,7 +290,7 @@ esp_lcd_new_panel_ssd1681(const esp_lcd_panel_io_handle_t io, const esp_lcd_pane *ret_panel = &(epaper_panel->base); // --- Init framebuffer if (!(epaper_panel->_non_copy_mode)) { - epaper_panel->_framebuffer = heap_caps_malloc(SSD1681_EPD_1IN54_V2_WIDTH * SSD1681_EPD_1IN54_V2_HEIGHT / 8, + epaper_panel->_framebuffer = heap_caps_malloc(epaper_panel->display_x * epaper_panel->display_y / 8, MALLOC_CAP_DMA); ESP_RETURN_ON_FALSE(epaper_panel->_framebuffer, ESP_ERR_NO_MEM, TAG, "epaper_panel_draw_bitmap allocating buffer memory err"); } @@ -328,6 +335,7 @@ esp_lcd_new_panel_ssd1681(const esp_lcd_panel_io_handle_t io, const esp_lcd_pane static esp_err_t epaper_panel_del(esp_lcd_panel_t *panel) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); epaper_panel_t *epaper_panel = __containerof(panel, epaper_panel_t, base); // --- Reset used GPIO pins if ((epaper_panel->reset_gpio_num) >= 0) { @@ -335,8 +343,8 @@ static esp_err_t epaper_panel_del(esp_lcd_panel_t *panel) } gpio_reset_pin(epaper_panel->busy_gpio_num); // --- Free allocated RAM + // Do not free if buffer is not allocated by driver (non_copy_mode==True) if ((epaper_panel->_framebuffer) && (!(epaper_panel->_non_copy_mode))) { - // Should not free if buffer is not allocated by driver free(epaper_panel->_framebuffer); } ESP_LOGD(TAG, "del ssd1681 epaper panel @%p", epaper_panel); @@ -381,9 +389,9 @@ static esp_err_t epaper_panel_init(esp_lcd_panel_t *panel) ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, SSD1681_CMD_SWRST, NULL, 0), TAG, "param SSD1681_CMD_SWRST err"); panel_epaper_wait_busy(panel); - // --- Driver Output Control + // --- Driver Output Control: prescribe the length of a row ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_OUTPUT_CTRL, - SSD1681_PARAM_OUTPUT_CTRL, 3), TAG, "SSD1681_CMD_OUTPUT_CTRL err"); + SSD1681_PARAM_OUTPUT_CTRL(epaper_panel->display_y), 3), TAG, "SSD1681_CMD_OUTPUT_CTRL err"); // --- Border Waveform Control ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_SET_BORDER_WAVEFORM, (uint8_t[]) { @@ -413,6 +421,8 @@ static esp_err_t epaper_panel_init(esp_lcd_panel_t *panel) static esp_err_t epaper_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "epaper_panel_draw_bitmap: xy_start=(%d,%d), end=(%d,%d)", x_start, y_start, x_end, y_end); epaper_panel_t *epaper_panel = __containerof(panel, epaper_panel_t, base); if (gpio_get_level(epaper_panel->busy_gpio_num)) { return ESP_ERR_NOT_FINISHED; @@ -442,55 +452,75 @@ epaper_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x ESP_LOGW(TAG, "Bitmap not DMA capable, use DMA capable memory to avoid additional data copy."); } } else { - // Copy & convert image according to configuration + // Copy & convert image according to configuration. + // Loads the panel framebuffer with image, possibly mirroring about X and/or Y axes. process_bitmap(panel, len_x, len_y, buffer_size, color_data); } // --- Set cursor & data entry sequence + // NO MIRROR if ((!(epaper_panel->_mirror_x)) && (!(epaper_panel->_mirror_y))) { // --- Cursor Settings + ESP_LOGD(TAG, "epaper_panel_draw_bitmap, no_mirror: x0,y0 = %d,%d, x1,y1=%d,%d", x_start, y_start, x_end, y_end); ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start, x_end, y_end), TAG, "epaper_set_area() error"); ESP_RETURN_ON_ERROR(epaper_set_cursor(epaper_panel->io, x_start, y_start), TAG, "epaper_set_cursor() error"); - // --- Data Entry Sequence Setting + // --- Data Entry Sequence Setting: staqrt on first row and increment Y ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_DATA_ENTRY_MODE, (uint8_t[]) { SSD1681_PARAM_DATA_ENTRY_MODE_3 }, 1), TAG, "SSD1681_CMD_DATA_ENTRY_MODE err"); } - if ((!(epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { + // Y MIRROR + else if ((!(epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { + if (epaper_panel->display_x == epaper_panel->display_y) { + y_end = y_end + len_y - 1; // code for square panel + } else { + y_end = 0; // code for rectangular panels + } + ESP_LOGD(TAG, "epaper_panel_draw_bitmap, mirror Y: x0,y0 = %d,%d, x1,y1=%d,%d", x_start, y_start + len_y - 1, x_end, y_end); // --- Cursor Settings - ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start + len_y - 1, x_end, y_end + len_y - 1), TAG, + ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start + len_y - 1, x_end, y_end), TAG, "epaper_set_area() error"); ESP_RETURN_ON_ERROR(epaper_set_cursor(epaper_panel->io, x_start, y_start + len_y - 1), TAG, "epaper_set_cursor() error"); - // --- Data Entry Sequence Setting + // --- Data Entry Sequence Setting: staqrt on last row and decrement Y ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_DATA_ENTRY_MODE, (uint8_t[]) { SSD1681_PARAM_DATA_ENTRY_MODE_1 }, 1), TAG, "SSD1681_CMD_DATA_ENTRY_MODE err"); } - if (((epaper_panel->_mirror_x)) && (!(epaper_panel->_mirror_y))) { + // X MIRROR + else if (((epaper_panel->_mirror_x)) && (!(epaper_panel->_mirror_y))) { + if (epaper_panel->display_x == epaper_panel->display_y) { + y_end = y_end + len_y - 1; // code for square panel + } else { + y_end = 0; // code for rectangular panels + } + ESP_LOGD(TAG, "epaper_panel_draw_bitmap, mirror X: x0,y0 = %d,%d, x1,y1=%d,%d", x_start, y_start + len_y - 1, x_end, y_end); // --- Cursor Settings - ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start + len_y - 1, x_end, y_end + len_y - 1), TAG, + ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start + len_y - 1, x_end, y_end), TAG, "epaper_set_area() error"); ESP_RETURN_ON_ERROR(epaper_set_cursor(epaper_panel->io, x_start, y_start + len_y - 1), TAG, "epaper_set_cursor() error"); - // --- Data Entry Sequence Setting + // --- Data Entry Sequence Setting: start on last row and decrement Y ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_DATA_ENTRY_MODE, (uint8_t[]) { SSD1681_PARAM_DATA_ENTRY_MODE_1 }, 1), TAG, "SSD1681_CMD_DATA_ENTRY_MODE err"); } - if (((epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { + // XY MIRROR + else if (((epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { + ESP_LOGD(TAG, "epaper_panel_draw_bitmap, mirror XY: x0,y0 = %d,%d, x1,y1=%d,%d", x_start, y_start, x_end, y_end); // --- Cursor Settings ESP_RETURN_ON_ERROR(epaper_set_area(epaper_panel->io, x_start, y_start, x_end, y_end), TAG, "epaper_set_area() error"); ESP_RETURN_ON_ERROR(epaper_set_cursor(epaper_panel->io, x_start, y_start), TAG, "epaper_set_cursor() error"); - // --- Data Entry Sequence Setting + // --- Data Entry Sequence Setting: staqrt on first row and increment Y ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_DATA_ENTRY_MODE, (uint8_t[]) { SSD1681_PARAM_DATA_ENTRY_MODE_3 }, 1), TAG, "SSD1681_CMD_DATA_ENTRY_MODE err"); } // --- Send bitmap to e-Paper VRAM + ESP_LOGD(TAG, "epaper_panel_draw_bitmap, call set_vram: len_x, len_y = %d, %d", len_x, len_y); if (epaper_panel->bitmap_color == SSD1681_EPAPER_BITMAP_BLACK) { ESP_RETURN_ON_ERROR(panel_epaper_set_vram(epaper_panel->io, (uint8_t *) (epaper_panel->_framebuffer), NULL, (len_x * len_y / 8)), @@ -502,7 +532,7 @@ epaper_panel_draw_bitmap(esp_lcd_panel_t *panel, int x_start, int y_start, int x } // --- Refresh the display, show image in VRAM // tx_param will wait until DMA transaction finishes, so it is safe to call panel_epaper_refresh_screen at once. - // The driver will not call the `epaper_panel_refresh_screen` automatically, please call it manually. + // The driver will not call the `epaper_panel_refresh_screen` automatically, please call it after return from this function. return ESP_OK; } @@ -575,63 +605,80 @@ static esp_err_t epaper_panel_disp_on_off(esp_lcd_panel_t *panel, bool on_off) static esp_err_t process_bitmap(esp_lcd_panel_t *panel, int len_x, int len_y, int buffer_size, const void *color_data) { + esp_log_level_set(TAG, ESP_LOG_DEBUG); epaper_panel_t *epaper_panel = __containerof(panel, epaper_panel_t, base); // --- Convert image according to configuration + // NO MIRROR if ((!(epaper_panel->_mirror_x)) && (!(epaper_panel->_mirror_y))) { if (!(epaper_panel->_non_copy_mode)) { if (epaper_panel->_swap_xy) { - memset(epaper_panel->_framebuffer, 0, 200 * 200 / 8); + memset(epaper_panel->_framebuffer, 0, epaper_panel->display_x * epaper_panel->display_y / 8); for (int i = 0; i < buffer_size * 8; i++) { uint8_t bitmap_byte = ((uint8_t *) (color_data))[i / 8]; uint8_t bitmap_pixel = (bitmap_byte & (0x01 << (7 - (i % 8)))) ? 0x01 : 0x00; (epaper_panel->_framebuffer)[((i * len_y / 8) % buffer_size) + (i / 8 / len_x)] |= (bitmap_pixel << (7 - ((i / len_x) % 8))); } } else { + ESP_LOGD(TAG, "process_bitmap, no mirror, no swap: buffer_size = %d", buffer_size); for (int i = 0; i < buffer_size; i++) { (epaper_panel->_framebuffer)[i] = ((uint8_t *) (color_data))[i]; } } } } + // MIRROR Y if ((!(epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { if (epaper_panel->_swap_xy) { - memset((epaper_panel->_framebuffer), 0, 200 * 200 / 8); + memset((epaper_panel->_framebuffer), 0, epaper_panel->display_x * epaper_panel->display_y / 8); for (int i = 0; i < buffer_size * 8; i++) { uint8_t bitmap_byte = ((uint8_t *) (color_data))[i / 8]; uint8_t bitmap_pixel = (bitmap_byte & (0x01 << (7 - (i % 8)))) ? 0x01 : 0x00; (epaper_panel->_framebuffer)[buffer_size - (((i * len_y / 8) % buffer_size) + (i / 8 / len_x)) - 1] |= (bitmap_pixel << (((i / len_x) % 8))); } } else { + ESP_LOGD(TAG, "process_bitmap, mirror Y, no swap: buffer_size = %d", buffer_size); + // Copy to framebuffer: image ends up with X & Y axes mirrored. When epaper_panel_draw_bitmap is called, + // image is transferred to panel by starting at Y=end and decrementing with each row, + // thereby undoing the X mirror. for (int i = 0; i < buffer_size; i++) { (epaper_panel->_framebuffer)[buffer_size - i - 1] = byte_reverse(((uint8_t *)(color_data))[i]); } } } + // MIRROR_X if (((epaper_panel->_mirror_x)) && (!(epaper_panel->_mirror_y))) { if (!(epaper_panel->_non_copy_mode)) { if (epaper_panel->_swap_xy) { - memset((epaper_panel->_framebuffer), 0, 200 * 200 / 8); + memset((epaper_panel->_framebuffer), 0, epaper_panel->display_x * epaper_panel->display_y / 8); for (int i = 0; i < buffer_size * 8; i++) { uint8_t bitmap_byte = ((uint8_t *) (color_data))[i / 8]; uint8_t bitmap_pixel = (bitmap_byte & (0x01 << (7 - (i % 8)))) ? 0x01 : 0x00; (epaper_panel->_framebuffer)[((i * len_y / 8) % buffer_size) + (i / 8 / len_x)] |= (bitmap_pixel << (7 - ((i / len_x) % 8))); } } else { + // Straight copy to framebuffer. When epaper_panel_draw_bitmap is called, + // image is transferred to panel by starting at Y=end and decrementing with each row, + // thereby mirroring about the X axis. + ESP_LOGD(TAG, "process_bitmap, mirror X, no swap: buffer_size = %d", buffer_size); for (int i = 0; i < buffer_size; i++) { (epaper_panel->_framebuffer)[i] = ((uint8_t *) (color_data))[i]; } } } } + // MIRROR_XY if (((epaper_panel->_mirror_x)) && (epaper_panel->_mirror_y)) { if (epaper_panel->_swap_xy) { - memset((epaper_panel->_framebuffer), 0, 200 * 200 / 8); + memset((epaper_panel->_framebuffer), 0, epaper_panel->display_x * epaper_panel->display_y / 8); for (int i = 0; i < buffer_size * 8; i++) { uint8_t bitmap_byte = ((uint8_t *) (color_data))[i / 8]; uint8_t bitmap_pixel = (bitmap_byte & (0x01 << (7 - (i % 8)))) ? 0x01 : 0x00; (epaper_panel->_framebuffer)[buffer_size - (((i * len_y / 8) % buffer_size) + (i / 8 / len_x)) - 1] |= (bitmap_pixel << (((i / len_x) % 8))); } } else { + // Copy to framebuffer: image ends up with X & Y axes mirrored. When epaper_panel_draw_bitmap is called, + // image is transferred to panel by starting at Y=0 and incrementing with each row. + ESP_LOGD(TAG, "process_bitmap, mirror XY, no swap: buffer_size = %d", buffer_size); for (int i = 0; i < buffer_size; i++) { (epaper_panel->_framebuffer)[buffer_size - i - 1] = byte_reverse(((uint8_t *)(color_data))[i]); } @@ -641,6 +688,17 @@ static esp_err_t process_bitmap(esp_lcd_panel_t *panel, int len_x, int len_y, in return ESP_OK; } +esp_err_t set_panel_size(esp_lcd_panel_t *panel, int len_x, int len_y) +{ + epaper_panel_t *epaper_panel = __containerof(panel, epaper_panel_t, base); + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "set_panel_size: x,y = %d, %d", len_x, len_y); + ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(epaper_panel->io, SSD1681_CMD_OUTPUT_CTRL, + SSD1681_PARAM_OUTPUT_CTRL(len_x), 0), TAG, "SSD1681_CMD_OUTPUT_CTRL err"); + return ESP_OK; +} + +// If MIRROR Y, then bytes must be reversed. static inline uint8_t byte_reverse(uint8_t data) { static uint8_t _4bit_reverse_lut[] = { diff --git a/components/lcd/esp_lcd_ssd1681/esp_lcd_ssd1681_commands.h b/components/lcd/esp_lcd_ssd1681/esp_lcd_ssd1681_commands.h index 2287c46b9..074f5ed73 100644 --- a/components/lcd/esp_lcd_ssd1681/esp_lcd_ssd1681_commands.h +++ b/components/lcd/esp_lcd_ssd1681/esp_lcd_ssd1681_commands.h @@ -14,11 +14,12 @@ #define SSD1681_CMD_SWRST 0x12 // --- Driver output control #define SSD1681_CMD_OUTPUT_CTRL 0x01 -#define SSD1681_PARAM_OUTPUT_CTRL ((uint8_t[]) {0xc7, 0x00, 0x00}) +// Chipset wants (total row count - 1) i.e. 250 rows = 249 here +#define SSD1681_PARAM_OUTPUT_CTRL(rows) ((uint8_t[]) {(rows-1) & 0xFF, (rows-1) >> 8, 0x00}) // --- Data Entry Sequence Setting #define SSD1681_CMD_DATA_ENTRY_MODE 0x11 // A [1:0] = ID[1:0], A[2] = AM -// the address counter is updated in the X direction +// AM = 0, the address counter is updated in the X direction // 000 - Y decrement, X decrement #define SSD1681_PARAM_DATA_ENTRY_MODE_0 0x00 // 001 – Y decrement, X increment @@ -26,8 +27,8 @@ // 010 - Y increment, X decrement #define SSD1681_PARAM_DATA_ENTRY_MODE_2 0x02 // 011 - Y increment, X increment -// AM = 1, the address counter is updated in the Y direction #define SSD1681_PARAM_DATA_ENTRY_MODE_3 0x03 +// AM = 1, the address counter is updated in the Y direction // 100 - Y decrement, X decrement #define SSD1681_PARAM_DATA_ENTRY_MODE_4 0x04 // 101 – Y decrement, X increment diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/README.md b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/README.md index bc1174489..67c6d555d 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/README.md +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/README.md @@ -9,7 +9,7 @@ This example shows how to use SSD1681 e-paper display driver from Component mana ### Hardware Required * An ESP development board -* An SSD1681 e-paper panel, with SPI interface +* An SSD1681 or SSD1680 e-paper panel, with SPI interface * An USB cable for power supply and programming ### Hardware Connection @@ -42,7 +42,9 @@ The GPIO number used by this example can be changed in [main.c](main/main.c). ### Software configuration - Change all the `EXAMPLE_PIN` macro definition according to your hardware connection. -- If you are not using waveshare 1.54 inch V2 e-paper panel, please use the waveform lut provided by your panel vendor instead of using the demo built-in ones, or just simply comment the `epaper_panel_set_custom_lut` call and use the panel built-in waveform lut. +- Select the display model in esp_lcd_panel_ssd1681.h. Supported displays are 1.54 inch 200x200 and 2.7 inch 176x264. The 2.7 inch display has a SSD1680 controller. +- If you are not using waveshare 1.54 inch V2 e-paper panel, please use the waveform lut provided by your panel vendor instead of using the demo built-in ones, or just simply comment out the `epaper_panel_set_custom_lut` call and use the panel built-in waveform lut. +NOTE: Waveshare and GooDisplay epaper displays can default to use built-in LUT. ### Build and Flash @@ -72,7 +74,10 @@ I (720) epaper_demo_plain: Drawing bitmap... ... ``` -## Show Custom Bitmap +## Show Test Images + +Images are found in img_bitmap.c and bitmaps_176x264.c. If you want to test other size panels you should make your own bitmap image files. +Choosing the display (see Software COnfiguration) also selects an appropriate test image. As you could see from the demo, each bitmap is stored as an array. If you want to display your custom image, you need to convert your image to a bitmap array first. @@ -87,6 +92,7 @@ You could convert your image to bitmap array by the following steps: - Do not select the `Output in big-endian format` option. - Click `Convert` and you get a `.c` file containing the bitmap array. +Programs image2cpp or img2cpp can generate bitmap.c files from JPEG or PNG inputs. There are plenty of software alternative with such functionality, please pay attention to the scan mode if you prefer to use them. The driver writes bitmap array to the vram in the sequence below by default: diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/CMakeLists.txt b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/CMakeLists.txt index 1af3548a5..6f1750590 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/CMakeLists.txt +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "main.c" "img_bitmap.c" +idf_component_register(SRCS "bitmaps_176x264.c" "main.c" "img_bitmap.c" INCLUDE_DIRS "") diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/bitmaps_176x264.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/bitmaps_176x264.c new file mode 100644 index 000000000..7fc66e7b2 --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/bitmaps_176x264.c @@ -0,0 +1,1110 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ +// Zorro B&W +#include "img_bitmap.h" +const unsigned int IMAGE_WIDTH = 176; +const unsigned int IMAGE_HEIGHT = 264; + +// A cat. +const uint8_t BITMAP_176_264[] = { + 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xf8, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0e, 0xbf, + 0xff, 0xf9, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x9f, 0xff, 0xfb, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x9f, 0xff, 0xfb, 0xfe, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xdf, 0xff, 0xf9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xcf, 0xff, 0xfd, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xef, 0xff, 0xff, + 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, + 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xfe, 0x7f, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xde, 0x3f, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, + 0xdf, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x7f, 0x3f, 0xff, 0xff, + 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0x3f, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xbf, 0x3f, 0xff, 0xff, 0xff, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x9f, 0xff, 0xff, + 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x9f, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0x9f, + 0xff, 0xff, 0xff, 0xf4, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xfe, 0x6f, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xfe, 0xcf, 0xff, + 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x7c, 0xdf, 0xff, 0xdf, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3d, 0x9f, 0xff, 0xdf, 0x9f, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x39, + 0xbf, 0xff, 0xdf, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x01, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x73, 0xbf, 0xff, 0xdf, 0x8f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x7f, 0xff, 0xfd, 0x8f, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe3, 0x7f, 0xff, 0xfd, 0xcf, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, 0xef, 0xcf, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xe6, 0xff, 0xff, + 0xef, 0xcf, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfb, + 0x00, 0x3f, 0xff, 0xcc, 0xff, 0xff, 0xef, 0xdf, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xbf, 0x00, 0x00, 0x0f, 0xff, 0xcd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x01, 0xc3, 0x99, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xff, 0xf0, 0x00, 0x01, 0xbb, 0xff, 0xff, 0xf7, 0xdf, 0xff, 0xff, 0xee, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x01, 0x33, 0xff, 0xff, 0xf7, 0xdf, + 0xff, 0xff, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x37, 0xff, 0xff, 0xf7, 0xcf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x07, 0xfc, 0x00, 0x00, 0x06, 0x0f, 0xbf, 0xff, 0xcf, 0xff, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0xf7, 0xdf, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x60, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x13, + 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0x70, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, + 0x1f, 0xe0, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x07, 0xe0, 0x00, 0x00, 0x03, 0x88, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc1, 0xe0, 0x60, 0x80, 0x00, + 0x21, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xbf, 0xfc, 0x78, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xdc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xbe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xfc, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, + 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xbf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xff, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xff, 0xfe, 0x0f, + 0xf7, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0xff, 0xe6, 0x4f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x1f, 0xe3, 0xef, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1f, + 0xe3, 0xe7, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0xf1, 0x3c, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0xff, 0xff, + 0xff, 0xe3, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xee, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf3, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, + 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfb, 0xe3, 0xe2, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf7, 0xff, 0xe0, 0x67, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xfc, 0x73, 0xf3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x06, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xff, 0xc1, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x06, 0x00, 0x00, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc0, 0x07, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x3f, + 0xfb, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe2, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0x80, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x67, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x0b, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x1f, + 0xff, 0xff, 0x07, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, + 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0xc0, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0xfe, 0xc0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xf8, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x0f, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x70, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, + 0xc0, 0x60, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0x7f, + 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe1, 0xa0, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x03, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, + 0xff, 0xff, 0x80, 0x1c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x3f, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, + 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xfc, 0x1f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xfe, + 0x18, 0x03, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, + 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0x02, 0x0f, 0xff, 0xff, 0xfc, 0x3f, 0x07, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xfd, 0x80, 0xc7, 0xff, 0xff, + 0xfc, 0x3f, 0x01, 0xff, 0xe3, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, + 0xff, 0xf8, 0x60, 0x3f, 0xff, 0xff, 0xf8, 0x7f, 0x00, 0xff, 0xc0, 0xff, 0xff, 0xff, 0x80, 0x07, + 0xcf, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xf8, 0x18, 0x7f, 0xff, 0xff, 0xfd, 0xff, 0xc0, 0x3f, + 0xc3, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xdf, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xe5, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0x87, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xfc, + 0x00, 0xff, 0xff, 0xcb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xfc, 0x7e, 0x07, 0xff, 0xff, 0xff, + 0xc0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xbe, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, + 0xff, 0xff, 0xc0, 0x10, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xe0, 0x40, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0x7f, 0xff, 0xff, 0xfc, + 0x07, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x33, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x4f, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xa7, 0xff, 0xff, 0xff, + 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xc7, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, + 0xe0, 0x01, 0x44, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x4f, 0xff, + 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x4f, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0xff, + 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x80, + 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xc0, 0x3f, 0xff, 0xff, 0xc0, + 0x00, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x9c, 0x40, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x0c, 0x20, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x04, 0x00, 0x7f, 0xff, + 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x80, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0x80, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0x40, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe4, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x1f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xff, 0xff, + 0xff, 0xff, 0x18, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x38, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xbc, 0x00, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xf9, 0x3f, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf1, 0x1f, 0xff, 0xc1, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, + 0x3f, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xfc, 0x7f, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xf9, + 0xff, 0xfc, 0x3f, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x00, 0x07, 0xfd, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xbf, 0xff, + 0xff, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, + 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xfe, 0xff, 0xfc, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0x9f, 0xff, 0xf8, 0x00, 0x1f, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xe1, 0x00, 0xff, 0xe0, 0x01, + 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc3, + 0x8f, 0xc7, 0xc3, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc3, 0x1c, 0x0f, 0xe3, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xf0, + 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xcf, 0xff, + 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x03, 0xff, + 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xfc, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, + 0x0f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xf0, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0x80, 0x7f, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, + 0xff, 0xfe, 0x0f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x10, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0x1c, 0x1e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe0, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7f, 0xfe, 0x00, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0xff, 0xc1, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x18, 0xe7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x07, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x01, 0x80, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x03, 0x0f, + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, + 0x0f, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x02, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x2f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, + 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x7f, 0x00, 0x3e, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0xc1, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7f, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// A cat. This image would need to swap XY to display. +const unsigned char BITMAP_264_176[] = { + 0x00, 0x10, 0x00, 0x0f, 0xe0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xbf, 0xff, 0xf1, 0x3f, + 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x80, 0xe3, 0xe1, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x7f, 0xbf, 0xff, 0xe0, + 0x0f, 0xf3, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x27, 0x98, 0x63, 0xf0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x7f, 0xff, 0xff, + 0xe0, 0x42, 0xff, 0xfc, 0x3f, 0xff, 0xdf, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x23, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x3f, 0xe3, + 0xff, 0x80, 0x42, 0xff, 0xfe, 0x03, 0xff, 0xc7, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x30, 0x60, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, + 0xc3, 0xff, 0xc8, 0x03, 0xff, 0xe0, 0x81, 0xff, 0xf1, 0xff, 0xff, 0xff, 0x7f, 0x80, 0x70, 0x02, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x1f, 0xff, 0xfe, 0x81, 0xff, 0x00, 0x60, 0x7f, 0xf8, 0x3f, 0xff, 0xfe, 0x7f, 0x80, 0x70, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x3c, 0x1f, 0xf7, 0xfc, 0x81, 0xff, 0xc0, 0x60, 0x1f, 0xfc, 0x1f, 0xff, 0x3e, 0xff, 0xe3, + 0xf0, 0x38, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x80, 0x00, 0x38, 0x3f, 0xff, 0xb8, 0xd3, 0xfc, 0xf0, 0x74, 0x07, 0xfc, 0x0f, 0xfc, 0x3f, 0xff, + 0xff, 0xd0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x80, 0x00, 0x3c, 0x3f, 0xfc, 0x00, 0x89, 0xf8, 0x00, 0xfc, 0x03, 0x7c, 0x07, 0xf8, 0x3b, + 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x06, 0x08, 0x00, 0x00, 0x20, 0x7f, 0xf8, 0xe0, 0x41, 0xf8, 0x00, 0xfc, 0x00, 0x0c, 0x89, 0xe0, + 0x73, 0xff, 0xff, 0xe0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0xf8, 0x00, 0x00, + 0x00, 0x0e, 0x00, 0x00, 0x00, 0x20, 0xff, 0xf9, 0xe0, 0x61, 0xf8, 0x00, 0xff, 0x00, 0x6c, 0xc4, + 0x6d, 0xf3, 0xff, 0xff, 0xe0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7f, 0x00, + 0x00, 0xe0, 0x08, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xc0, 0x61, 0xf8, 0x00, 0x3f, 0xc0, 0x00, + 0x46, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x7f, + 0x00, 0x30, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0xf8, 0x00, 0x3f, 0xe3, + 0xd8, 0x71, 0xfd, 0xff, 0xff, 0xff, 0xe0, 0x81, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0xff, 0x00, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0xf8, 0x00, 0x1f, + 0xf9, 0xf8, 0x79, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, + 0xcf, 0xff, 0x00, 0x83, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x70, 0x00, + 0x1f, 0xf9, 0xf0, 0xfe, 0xfd, 0xfc, 0x3f, 0xff, 0xc0, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x1f, 0xfe, 0x00, 0x30, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x21, 0xe0, + 0x00, 0x1f, 0xfd, 0xf0, 0xfe, 0x3d, 0xf0, 0x3f, 0xff, 0xc1, 0x8f, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x1f, 0xff, 0xa0, 0x0c, 0x00, 0x00, 0x1e, 0x42, 0x04, 0x00, 0x3f, 0xf0, 0x00, 0x10, + 0xe0, 0x00, 0x0f, 0xff, 0xe1, 0xff, 0x05, 0xf0, 0x3f, 0xff, 0x80, 0x4f, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x0f, 0xfe, 0x03, 0x07, 0x00, 0x00, 0x1f, 0xb0, 0x00, 0x00, 0x3c, 0x70, 0x00, + 0x00, 0xc0, 0x00, 0x0f, 0xff, 0x87, 0xff, 0x63, 0xf0, 0x3f, 0xff, 0x80, 0x07, 0xfc, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x38, 0x7c, 0x01, 0xef, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x38, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc7, 0xf0, 0x3f, 0xff, 0xc4, 0x10, 0xfc, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1f, 0xf0, 0x08, 0xff, 0x9c, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x10, + 0xe0, 0x00, 0x08, 0x00, 0x00, 0x07, 0xff, 0xff, 0xdf, 0xff, 0xe0, 0x3f, 0x0f, 0xc4, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x18, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x10, 0x1c, 0x00, 0x00, 0x03, 0xff, 0xff, 0x03, 0xf3, 0xfc, 0x3f, 0x03, 0xc4, 0x03, + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x78, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x08, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xe3, 0x01, 0xc0, 0xfc, 0x7f, 0x81, 0xc0, + 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x80, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x01, 0xc1, 0xfe, 0xff, 0x00, + 0xc0, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xe0, 0x00, 0x00, + 0x00, 0x02, 0x30, 0x00, 0x08, 0x0f, 0x9c, 0x00, 0x00, 0x06, 0x1e, 0x00, 0x03, 0x81, 0xff, 0xff, + 0x00, 0xe0, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x0f, 0x88, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x0c, 0x07, 0x18, 0x00, 0x00, 0x03, 0x7c, 0x00, 0x00, 0x01, 0x9f, + 0xfe, 0x00, 0x60, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x30, 0x00, 0x00, 0x00, 0x0f, 0x1c, + 0x00, 0x00, 0x00, 0x20, 0x70, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x01, + 0xff, 0xff, 0x00, 0x71, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x60, 0xc6, + 0x18, 0x00, 0x00, 0x00, 0x0c, 0x70, 0x01, 0x00, 0x0f, 0x40, 0x00, 0x00, 0x3f, 0x90, 0x00, 0x00, + 0x01, 0xfe, 0xc1, 0xc0, 0x79, 0x87, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x7f, + 0xc0, 0x18, 0x00, 0x00, 0x00, 0x0e, 0x40, 0x00, 0x00, 0x01, 0x00, 0x03, 0xc0, 0x7f, 0x80, 0x00, + 0x00, 0x01, 0xfc, 0x00, 0xf3, 0x9e, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x1f, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xe0, 0x03, 0x00, + 0x00, 0x00, 0x01, 0xfc, 0x00, 0x3f, 0xce, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0xbe, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x1f, 0xf6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x13, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x04, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x01, 0x00, 0x7d, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf9, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x02, 0x0f, 0xfc, 0x00, 0x02, 0x00, 0x03, 0x80, 0x08, 0x00, 0x00, 0x00, 0x01, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x3d, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x3c, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x3f, 0xfc, 0x00, 0x03, 0xc0, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x3f, 0xfe, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x7f, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0xfe, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x7f, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3a, 0x3f, 0xfe, 0x00, 0x3b, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0xff, 0xff, 0xc0, 0x1f, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x07, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7f, 0xff, 0xe0, 0x1f, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0xff, 0xf1, 0x9f, 0xc0, + 0x00, 0x01, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xfe, 0xf1, 0xff, + 0xc4, 0x0f, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0xff, 0xf3, + 0xff, 0xc0, 0xfe, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xff, + 0x77, 0xff, 0xf0, 0xe4, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xff, 0x73, 0xff, 0xf0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0xfe, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xff, 0x73, 0xff, 0xfc, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xfe, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0x7f, 0xff, 0xfe, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x7c, 0x5f, 0xff, 0xff, 0x80, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe3, 0xff, 0xc0, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x83, 0xff, 0x81, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xfe, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0xfe, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc1, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfd, 0xff, 0xff, 0x80, 0x7f, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0xf3, 0xff, 0xc8, 0xff, 0xe0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x3f, 0xff, 0xcb, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfb, 0xff, + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x9f, + 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfe, + 0x0f, 0xff, 0xf0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, + 0xfc, 0x1f, 0xff, 0xf8, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, + 0xe7, 0xfc, 0x3f, 0xff, 0xf8, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x7f, 0xff, + 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xff, + 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xf4, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, + 0xff, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xfe, 0x10, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xd0, 0x3f, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x80, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xc8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x9c, 0x07, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x9f, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0xff, + 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x98, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x88, 0x30, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x80, + 0x18, 0x1f, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x10, 0x7f, + 0x80, 0x18, 0x3e, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x00, 0x01, 0xff, 0xff, 0x80, + 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x38, + 0x7f, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x7f, 0xff, + 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x30, 0x00, 0x00, 0x20, 0x00, 0x20, 0x03, + 0x7e, 0xc0, 0x36, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x3f, + 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x3e, 0x80, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x78, 0x00, + 0x1f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x07, 0xf8, + 0x31, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0x00, 0x80, 0x00, 0x7c, + 0x00, 0x03, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x80, 0x80, 0x18, 0x81, + 0xfe, 0x38, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x76, 0x80, 0x00, + 0xce, 0x00, 0x00, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x87, 0x80, 0x1e, + 0x00, 0xff, 0xfe, 0x38, 0x00, 0x3c, 0x0f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, + 0x01, 0xe1, 0x00, 0x00, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x00, + 0x1f, 0x00, 0xf9, 0x63, 0xc1, 0xc3, 0x3f, 0x1f, 0xff, 0xff, 0xfc, 0x00, 0xc0, 0x00, 0x00, 0x10, + 0x00, 0x01, 0xf0, 0x00, 0x00, 0x37, 0xc0, 0x0f, 0x9b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x00, 0x3f, 0x81, 0xf0, 0x00, 0xff, 0xe1, 0x7f, 0xff, 0xc7, 0xff, 0xfe, 0x63, 0x40, 0x00, 0x00, + 0x10, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x01, 0x60, 0x08, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xe0, 0x38, 0xff, 0x89, 0x1d, 0x86, 0x7e, 0xf0, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0xff, 0xff, 0x80, 0x9f, 0x67, 0xfe, 0x3f, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, + 0x20, 0x00, 0x00, 0x0f, 0x80, 0x0d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xcc, 0xff, 0xff, 0xd8, 0x8f, 0x7e, 0xf0, 0x9f, 0xff, 0xfe, 0x81, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcf, 0xff, 0x78, 0x0f, 0xff, 0xf8, 0x00, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xfe, 0xff, 0xff, 0x7f, 0xef, 0xff, 0xf0, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x80, 0x00, 0x01, 0xfe, 0x01, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x20, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x20, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x0f, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0xf3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x90, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, + 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0xc0, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xf8, 0x03, 0xff, 0xfc, + 0xff, 0xfe, 0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x07, 0xc1, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xf8, 0x01, 0xff, + 0xff, 0xfc, 0xfc, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0xcf, 0x0f, 0xc1, 0xe0, + 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xfc, 0x01, + 0xff, 0xff, 0xf8, 0xfe, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x1e, 0x1f, 0x8f, + 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xfc, + 0x0f, 0xff, 0xff, 0xc3, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x06, 0x00, 0x00, 0x3c, 0x3f, + 0x9f, 0x80, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3d, 0xff, 0xff, 0xfe, 0x0f, 0xff, + 0xe6, 0x3f, 0xff, 0xff, 0x86, 0x7b, 0x80, 0xff, 0x87, 0xff, 0x60, 0x00, 0x0f, 0x00, 0x00, 0xfe, + 0x7f, 0xb2, 0x00, 0x00, 0x07, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7d, 0xff, 0xff, 0xff, 0x9f, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0x9e, 0x79, 0xe0, 0xfc, 0x01, 0xff, 0xf0, 0x00, 0x1f, 0x80, 0x00, + 0x3f, 0x6f, 0x00, 0x00, 0x00, 0x0f, 0x01, 0xff, 0xff, 0xff, 0x80, 0x07, 0x79, 0xff, 0xff, 0xff, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x19, 0xf0, 0x7c, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0xcf, 0x00, 0x00, 0x00, 0x1f, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x18, 0xff, 0xff, + 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x0f, 0xf8, 0x7c, 0x00, 0x0f, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x08, 0xff, + 0xff, 0xff, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x8d, 0xfc, 0xfc, 0x00, 0x00, 0x60, 0x00, + 0x03, 0x80, 0x00, 0xfc, 0x00, 0x3f, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x76, + 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xef, 0xfe, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xa0, 0x07, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, + 0x3f, 0x7f, 0xff, 0xe8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x87, 0xff, 0x7f, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0x3f, 0xff, 0xe0, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x87, 0xc0, 0x7e, 0xef, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0x67, 0xff, + 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x00, 0x07, 0xc3, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xe7, 0xfc, 0x7f, 0xff, 0xf8, + 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x00, 0x06, 0x81, 0xfe, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xe7, 0xff, 0xff, 0x9f, + 0x07, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x81, 0x80, 0x07, 0x80, 0x18, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x7f, 0x00, 0x00, 0x0f, 0x00, 0x11, 0xfc, 0x00, 0x1f, 0xff, 0x7f, 0xff, 0xf9, + 0xff, 0xe0, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x07, 0x00, 0x00, 0x0f, 0x07, 0xe3, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xf9, + 0x87, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe3, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0xef, 0x60, 0x73, 0x3f, 0xff, 0xff, + 0xfc, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xfc, 0x30, 0x00, 0x00, 0x38, 0x0f, 0xe3, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc7, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xfe, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x00, 0x00, 0xfc, 0x1f, 0xf3, 0xff, + 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x70, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xf8, 0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0xef, 0xfe, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xfe, 0xb8, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0x10, 0x00, 0x07, 0xff, 0x1f, + 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x0f, 0xa0, 0x00, 0x00, 0x3f, + 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x1b, 0xff, 0xff, 0xff, 0xc3, 0x80, 0x78, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xc3, 0xc3, 0x3c, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x00, 0x00, 0x07, 0xfd, 0x60, + 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xfe, + 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x82, 0x00, 0x00, 0x03, + 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x80, 0x00, 0x00, + 0x11, 0xff, 0xff, 0x03, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0x20, 0x00, + 0x03, 0x9d, 0xff, 0xff, 0x03, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xfb, 0x7f, 0xff, 0xff, 0xf8, 0x1d, 0x00, + 0x00, 0x03, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf8, 0x0f, + 0xc0, 0x00, 0x03, 0xff, 0xff, 0xff, 0x01, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xfc, + 0x0e, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0x03, 0xc9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0x00, 0x07, 0xfb, 0xff, + 0xfc, 0x01, 0x71, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x03, 0x01, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xf8, 0x01, 0xff, 0xff, + 0x7f, 0xfe, 0x00, 0xf8, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfc, 0x03, 0xff, + 0xfc, 0x7f, 0xff, 0x00, 0x78, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x81, 0xff, 0x47, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfc, 0x03, + 0xff, 0xf8, 0x7f, 0xff, 0x80, 0x3c, 0x78, 0x7f, 0xff, 0xff, 0xff, 0x01, 0x03, 0xbf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, + 0x07, 0xff, 0xf0, 0x7f, 0xff, 0xc0, 0x08, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x03, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x0f, 0xff, 0xf1, 0xff, 0xff, 0xe0, 0x00, 0x3c, 0x7f, 0xff, 0xff, 0xbf, 0x04, 0x00, 0xfe, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x0f, 0xff, 0xdf, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f, 0x02, 0x00, + 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0x1b, 0x00, + 0x03, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0x03 +}; + +// Text at the corners and center of the image +const uint8_t TEXT_176_264[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe0, 0x00, 0x0c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xc0, 0x3f, 0xe0, 0x00, 0x0c, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x80, 0x07, 0xff, 0xc7, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x7f, 0x8f, 0x83, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xe3, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, + 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xe3, 0xff, 0xc7, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x7f, 0x8f, 0x87, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x80, 0x0f, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x80, 0x1f, + 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0x87, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xc7, 0xff, 0xc7, 0xfc, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0x8f, 0xe3, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xe3, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xe3, 0xff, 0xc7, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x7f, 0x8f, 0xf3, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, + 0xff, 0xc7, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf1, 0xff, 0xc7, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0x8f, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x3e, 0x00, 0x1e, 0x1f, 0xfc, 0x60, 0x00, 0x0c, 0x00, 0x3e, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0e, 0x00, 0x1e, 0x1f, 0xfc, 0x60, 0x00, 0x0c, + 0x00, 0x3c, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0f, 0xde, 0x3f, + 0xfe, 0x0f, 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7c, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x07, 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x1f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0x3f, 0xfe, 0x07, 0xfc, 0x7f, + 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xfe, 0x3f, 0xfe, 0x23, 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xfe, 0x3f, 0xfe, 0x21, 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, + 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xfe, 0x3f, 0xfe, 0x31, + 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe3, 0xff, 0xfe, 0x3f, 0xfe, 0x30, 0xfc, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfe, 0x3f, 0xfe, 0x38, 0x7c, 0x7f, 0xc7, 0xfc, + 0x7f, 0xfc, 0x7f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfe, 0x00, + 0x1e, 0x3c, 0x7c, 0x7f, 0xc7, 0xfc, 0x00, 0x3c, 0x7c, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe3, 0xff, 0xfe, 0x00, 0x1e, 0x3c, 0x3c, 0x7f, 0xc7, 0xfc, 0x00, 0x3c, 0x00, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfe, 0x3f, 0xfe, 0x3e, 0x1c, 0x7f, + 0xc7, 0xfc, 0x7f, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, + 0xfe, 0x3f, 0xfe, 0x3f, 0x1c, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7c, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xfe, 0x3f, 0xfe, 0x3f, 0x0c, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, + 0x7e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xfe, 0x3f, 0xfe, 0x3f, + 0x8c, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf1, 0xff, 0xfe, 0x3f, 0xfe, 0x3f, 0xc4, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xfe, 0x3f, 0xfe, 0x3f, 0xc4, 0x7f, 0xc7, 0xfc, + 0x7f, 0xfc, 0x7f, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0x3f, + 0xfe, 0x3f, 0xe0, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x3f, 0xf0, 0x7f, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0f, 0xde, 0x3f, 0xfe, 0x3f, 0xf0, 0x7f, + 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x0e, 0x00, 0x0e, 0x3f, 0xf8, 0x7f, 0xc7, 0xfc, 0x00, 0x1c, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3e, 0x00, 0x0e, 0x3f, 0xfc, 0x7f, 0xc7, 0xfc, 0x00, 0x1c, + 0x7f, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xc0, 0x3f, 0xf8, 0x03, 0xfc, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, + 0x80, 0x07, 0xf8, 0x00, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x3e, 0x0f, 0x8f, 0x83, 0xf8, 0xf8, 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0x87, 0x8f, 0xe3, 0xf8, 0xfc, + 0x7c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x3f, 0xc7, 0x8f, 0xf1, 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xc7, 0x8f, 0xf1, 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xc7, 0x8f, 0xf1, + 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x3f, 0xc7, 0x8f, 0xf1, 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0x8f, 0x8f, 0xf1, 0xf8, 0xfc, 0x7c, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0x1f, + 0x8f, 0xe3, 0xf8, 0xf8, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x8f, 0x87, 0xf8, 0x01, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0x80, 0x0f, 0xf8, 0x00, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x3f, 0x0f, 0x80, 0x1f, 0xf8, 0xf8, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xc7, 0x8f, 0x87, 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0x8f, 0xc7, + 0xf8, 0xff, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x3f, 0xe3, 0x8f, 0xe3, 0xf8, 0xff, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0x8f, 0xe3, 0xf8, 0xff, 0x1c, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, + 0x8f, 0xe3, 0xf8, 0xff, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe3, 0x8f, 0xf3, 0xf8, 0xfe, 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xc7, 0x8f, 0xf1, 0xf8, 0xf8, + 0x3c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x3f, 0x07, 0x8f, 0xf1, 0xf8, 0x00, 0x7c, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0x8f, 0xf1, 0xf8, 0x03, 0xfc, 0x00, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xff, 0x8f, 0xf8 +}; diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.c index 79fc95acb..9a5920fcb 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.c +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.c @@ -316,7 +316,8 @@ const uint8_t BITMAP_200_200[] = { /* 0X00,0X01,0XC8,0X00,0XC8,0X00, */ 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X80, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X80, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, - 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0XFF, + 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, + 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, }; diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.h b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.h index e51a99ed0..3fb52344b 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.h +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/img_bitmap.h @@ -14,7 +14,9 @@ extern "C" { extern const uint8_t BITMAP_200_200[]; extern const uint8_t BITMAP_128_64[]; extern const uint8_t BITMAP_64_128[]; - +extern const uint8_t BITMAP_176_264[]; +extern const uint8_t BITMAP_264_176[]; +extern const uint8_t TEXT_176_264[]; #ifdef __cplusplus } #endif diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/main.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/main.c index c2b42fe61..a850a80f7 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/main.c +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_demo/main/main.c @@ -1,8 +1,48 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG + +// Select the Waveshare or GooDisplay epaper display that you have. +// The display must use a SSD1680 or 1681 controller (see Waveshare documentation to be sure). +#define WAVE_27 1 // 2.7 inch V2 +#define WAVE_154 0 // 1.54 inch square (this code originally only supported this model) + +/* NOTE: (GDN) in my limited experience the rectangular displays assume portrait orientation: + * the X coordinate is the small dimension, Y is long. Waveshare documentation is ambiguous on this topic! + * When transferring bitmaps to the display, + * the controller increments X (index within a row) and then increments Y (row selector) when X has reached the end of a row. + * There are command options to change the direction of X and/or Y, from increment to decrement. + * The implementation in esp_lcd_panel_ssd1681.c changes the increment/decrement setting when mirroring the image. + * If you orient the display in landscape, the controller can be made to increment first over Y, then over X. + * The code in esp_lcd_panel_ssd1681.c is not currently implemented for these modes. + * See SSD1681_CMD_DATA_ENTRY_MODE values in esp_lcd_ssd1681_commands.h for more info. + */ +#define SSD1681_LUT_SIZE 159 +#if defined(WAVE_154) && WAVE_154==1 +#define SSD1681_EPD_1IN54_V2_WIDTH 200 +#define SSD1681_EPD_1IN54_V2_HEIGHT 200 +#define DISPLAY_X SSD1681_EPD_1IN54_V2_WIDTH +#define DISPLAY_Y SSD1681_EPD_1IN54_V2_HEIGHT +#define SQUARE_PANEL 1 +#elif defined(WAVE_27) && WAVE_27==1 +// Waveshare 2.7 inch +#define WAVE_27_V2_WIDTH 176 +#define WAVE_27_V2_HEIGHT 264 +#define DISPLAY_X WAVE_27_V2_WIDTH +#define DISPLAY_Y WAVE_27_V2_HEIGHT +#endif + +// Full screen test controls +#define MIRROR_NONE 1 // display image as input +#define MIRROR_X 1 // mirror on the X axis +#define MIRROR_Y 1 // mirror on the Y axis +#define MIRROR_XY 1 // mirror on both axes + +// second part of test, smaller than full screen, move images around +#define SHOW_PENGUIN 1 #include #include @@ -17,15 +57,28 @@ #include "esp_lcd_panel_ops.h" #include "driver/spi_common.h" #include "driver/gpio.h" - +// NOTE: Custom LUT tables are not used in this example. Displays default to a built-in LUT. #include "ssd1681_waveshare_1in54_lut.h" #include "img_bitmap.h" +// Test Images +#if WAVE_154 +#define FULL_IMAGE BITMAP_200_200 +#define FULL_INVERT false +#elif WAVE_27 +//#define FULL_IMAGE BITMAP_176_264 +#define FULL_IMAGE TEXT_176_264 +#define FULL_INVERT true // the test image was constructed wrong with WHITE=0xff and BLACK=0x00 +#endif + // SPI Bus #define EPD_PANEL_SPI_CLK 1000000 #define EPD_PANEL_SPI_CMD_BITS 8 #define EPD_PANEL_SPI_PARAM_BITS 8 #define EPD_PANEL_SPI_MODE 0 + +// ESP32 GPIO pins used +#if 0 // e-Paper GPIO #define EXAMPLE_PIN_NUM_EPD_DC 9 #define EXAMPLE_PIN_NUM_EPD_RST 4 @@ -34,6 +87,17 @@ // e-Paper SPI #define EXAMPLE_PIN_NUM_MOSI 7 #define EXAMPLE_PIN_NUM_SCLK 6 +#endif +#if 1 +// e-Paper GPIO with Waveshare ESP32S3 +#define EXAMPLE_PIN_NUM_EPD_DC 8 +#define EXAMPLE_PIN_NUM_EPD_RST 10 +#define EXAMPLE_PIN_NUM_EPD_CS 5 +#define EXAMPLE_PIN_NUM_EPD_BUSY 11 +// e-Paper SPI +#define EXAMPLE_PIN_NUM_MOSI 15 +#define EXAMPLE_PIN_NUM_SCLK 18 +#endif static const char *TAG = "epaper_demo_plain"; @@ -49,9 +113,60 @@ static bool give_semaphore_in_isr(const esp_lcd_panel_handle_t handle, const voi return false; } +// Copy a bitmap image to display buffer. Not used when FULL_IMAGE is same size as screen. +// Also the display buffer is usually assumed to be full screen. +uint8_t *crop_bitmap(const uint8_t *in_bitmap, int in_x, int in_y, int out_x, int out_y) +{ + if (out_x > DISPLAY_X) { + ESP_LOGW(TAG, "crop_bitmap: out_x = %d too large, change to %d", out_x, DISPLAY_X); + out_x = DISPLAY_X; + } + if (out_y > DISPLAY_Y) { + ESP_LOGW(TAG, "crop_bitmap: out_y = %d too large, change to %d", out_y, DISPLAY_Y); + out_y = DISPLAY_Y; + } + out_x = (out_x < in_x) ? out_x : in_x; // don't allow out_x to be bigger than in_x + bool b_dup = false; + if (out_y > in_y) { + b_dup = true; // if out_y > in_y, then duplicate some of the input image + } + + // The bitmap must be full size, so use DISPLAY_X and DISPLAY_Y, regardless of out_x, out_y. + uint8_t *out_bitmap = heap_caps_malloc(DISPLAY_X * DISPLAY_Y / 8, MALLOC_CAP_DMA); + memset(out_bitmap, 0, DISPLAY_X * DISPLAY_Y / 8); + + if (in_x == out_x && in_y == out_y) { + // in and out are same size + memcpy(out_bitmap, in_bitmap, in_x * in_y / 8); + } else { + uint8_t *out_ptr = out_bitmap; + uint8_t *in_ptr = in_bitmap; + ESP_LOGD(TAG, "in_bitmap = %p", (void *)in_bitmap); + ESP_LOGD(TAG, "out_bitmap = %p", (void *)out_bitmap); + // row index + for (int iy = 0; iy < out_y; iy++) { + if (b_dup && iy >= in_y) { + // Duplicate some of the input image, so start over. + in_ptr = in_bitmap; b_dup = 0; + } + // ix is column index. Inner loop copies a single row. + for (int ix = 0; ix < out_x / 8; ix++) { + *out_ptr = *in_ptr; + out_ptr++; in_ptr++; + } + //ESP_LOGI(TAG, "crop_bitmap: row = %d, in_ptr idx = %d", iy, in_ptr-in_bitmap); + in_ptr += (in_x - out_x) / 8; + } + ESP_LOGD(TAG, "crop_bitmap copied %d bytes", (out_ptr - out_bitmap)); + } + return out_bitmap; +} + void app_main(void) { esp_err_t ret; + esp_log_level_set(TAG, ESP_LOG_DEBUG); + // --- Init SPI Bus ESP_LOGI(TAG, "Initializing SPI Bus..."); spi_bus_config_t buscfg = { @@ -85,6 +200,9 @@ void app_main(void) // since those operations are not supported by ssd1681 and are implemented by software // Better use DMA-capable memory region, to avoid additional data copy .non_copy_mode = false, + // panel dimensions + .display_x = DISPLAY_X, + .display_y = DISPLAY_Y, }; esp_lcd_panel_dev_config_t panel_config = { .reset_gpio_num = EXAMPLE_PIN_NUM_EPD_RST, @@ -120,13 +238,6 @@ void app_main(void) static SemaphoreHandle_t epaper_panel_semaphore; epaper_panel_semaphore = xSemaphoreCreateBinary(); xSemaphoreGive(epaper_panel_semaphore); - // --- Clear the VRAM of RED and BLACK - uint8_t *empty_bitmap = heap_caps_malloc(200 * 200 / 8, MALLOC_CAP_DMA); - memset(empty_bitmap, 0, 200 * 200 / 8); - epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_RED); - esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, empty_bitmap); - epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_BLACK); - esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, empty_bitmap); // --- Register the e-Paper refresh done callback // cbs does not have to be static for ssd1681 driver, for the callback ptr is copied, not pointed @@ -135,56 +246,79 @@ void app_main(void) }; epaper_panel_register_event_callbacks(panel_handle, &cbs, &epaper_panel_semaphore); + // --- Clear the VRAM of RED and BLACK + ESP_LOGI(TAG, "Clear Screen"); + uint8_t *empty_bitmap = heap_caps_malloc(DISPLAY_X * DISPLAY_Y / 8, MALLOC_CAP_DMA); + memset(empty_bitmap, 0, DISPLAY_X * DISPLAY_Y / 8); +#if WAVE_154 // no RED on WAVE_27 + epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_RED); + esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, empty_bitmap); +#endif + epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_BLACK); + esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, empty_bitmap); + // refresh screen just so I can see that it is blank - not required + ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); + // Maybe SPI operation is still going on, so set a delay + vTaskDelay(pdMS_TO_TICKS(5000)); + heap_caps_free(empty_bitmap); + // --- Draw full-screen bitmap ESP_LOGI(TAG, "Drawing bitmap..."); ESP_LOGI(TAG, "Show image full-screen"); - + uint8_t *crop_image = heap_caps_malloc(DISPLAY_X * DISPLAY_Y / 8, MALLOC_CAP_DMA); + memset(crop_image, 0, DISPLAY_X * DISPLAY_Y / 8); + memcpy(crop_image, FULL_IMAGE, DISPLAY_X * DISPLAY_Y / 8); +#if MIRROR_NONE + ESP_LOGI(TAG, "Draw image NO Mirror"); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false)); - ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, FULL_INVERT)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, false)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, crop_image)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - +#endif +#if MIRROR_Y + ESP_LOGI(TAG, "Mirror Y axis"); + vTaskDelay(pdMS_TO_TICKS(5000)); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, true)); - ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, FULL_INVERT)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, false)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, crop_image)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - +#endif +#if MIRROR_X + ESP_LOGI(TAG, "Mirror X axis"); + vTaskDelay(pdMS_TO_TICKS(5000)); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, true, false)); - ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, FULL_INVERT)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, false)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, crop_image)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - +#endif +#if MIRROR_XY + ESP_LOGI(TAG, "Mirror X&Y axis"); + vTaskDelay(pdMS_TO_TICKS(5000)); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, true, true)); - ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); + ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, FULL_INVERT)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, false)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); - ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - - xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); - ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false)); - ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); - ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); - ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, crop_image)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - +#endif +#if SQUARE_PANEL // swap_xy tests: not implemented for non-square panels + // TODO: if display is normally portrait, then test swap_xy by inputting a landscape image xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, true)); ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, BITMAP_200_200)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); @@ -192,7 +326,7 @@ void app_main(void) ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, BITMAP_200_200)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); xSemaphoreTake(epaper_panel_semaphore, portMAX_DELAY); @@ -200,9 +334,16 @@ void app_main(void) ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, false)); ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, true)); ESP_LOGI(TAG, "Drawing bitmap..."); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, 200, 200, BITMAP_200_200)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, DISPLAY_X, DISPLAY_Y, BITMAP_200_200)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); +#endif + heap_caps_free(crop_image); +#if SHOW_PENGUIN + // Show penguin images that are smaller than full screen. + // This code does not clear the display so the previous full screen image remains and goes thru + // various XY mirrors. Furthermore the full screen image may have been displayed with invert_color, + // if so it will not be inverted here. vTaskDelay(pdMS_TO_TICKS(5000)); ESP_LOGI(TAG, "Go to sleep mode..."); esp_lcd_panel_disp_on_off(panel_handle, false); @@ -249,7 +390,7 @@ void app_main(void) ESP_LOGI(TAG, "Drawing bitmap..."); ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 16, 0, 144, 64, BITMAP_128_64)); ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); - +#endif vTaskDelay(pdMS_TO_TICKS(5000)); ESP_LOGI(TAG, "Go to sleep mode..."); esp_lcd_panel_disp_on_off(panel_handle, false); diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/idf_component.yml b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/idf_component.yml index 44eb36905..8cd9c3ec9 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/idf_component.yml +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/idf_component.yml @@ -5,4 +5,4 @@ dependencies: # I am specifying the path of the component because the component # had not been published to the ESP Component Registry by the time # I write this example. - path: "../../../" \ No newline at end of file + path: "../../../" diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/main.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/main.c index 1d850d4a4..6c8d5e049 100644 --- a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/main.c +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_demo/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -30,6 +30,7 @@ static const char *TAG = "example"; //////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) +#if 0 #define EXAMPLE_PIN_NUM_SCLK 6 #define EXAMPLE_PIN_NUM_MOSI 7 #define EXAMPLE_PIN_NUM_MISO (-1) // Unused @@ -37,10 +38,31 @@ static const char *TAG = "example"; #define EXAMPLE_PIN_NUM_EPD_RST 4 #define EXAMPLE_PIN_NUM_EPD_CS 10 #define EXAMPLE_PIN_NUM_EPD_BUSY 18 +#endif +#if 1 +// e-Paper GPIO with Waveshare ESP32S3 +#define EXAMPLE_PIN_NUM_EPD_DC 8 +#define EXAMPLE_PIN_NUM_EPD_RST 10 +#define EXAMPLE_PIN_NUM_EPD_CS 5 +#define EXAMPLE_PIN_NUM_EPD_BUSY 11 +// e-Paper SPI +#define EXAMPLE_PIN_NUM_MOSI 15 +#define EXAMPLE_PIN_NUM_SCLK 18 +#define EXAMPLE_PIN_NUM_MISO (-1) // Unused +#endif + +#define WAVE_27 1 // The pixel number in horizontal and vertical +#if defined(WAVE_154) && WAVE_154==1 #define EXAMPLE_LCD_H_RES 200 #define EXAMPLE_LCD_V_RES 200 +#elif defined(WAVE_27) && WAVE_27==1 +#define EXAMPLE_LCD_H_RES 176 +#define EXAMPLE_LCD_V_RES 264 +#endif +#define DISPLAY_X EXAMPLE_LCD_H_RES +#define DISPLAY_Y EXAMPLE_LCD_V_RES // Bit number used to represent command and parameter #define EXAMPLE_LCD_CMD_BITS 8 @@ -157,7 +179,7 @@ void app_main(void) .miso_io_num = EXAMPLE_PIN_NUM_MISO, .quadwp_io_num = -1, .quadhd_io_num = -1, - .max_transfer_sz = EXAMPLE_LCD_H_RES * 200 / 8, + .max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 8, }; ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); @@ -221,15 +243,15 @@ void app_main(void) lv_init(); // alloc draw buffers used by LVGL // it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized - lv_color_t *buf1 = heap_caps_malloc(EXAMPLE_LCD_H_RES * 200 * sizeof(lv_color_t), MALLOC_CAP_DMA); + lv_color_t *buf1 = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(lv_color_t), MALLOC_CAP_DMA); assert(buf1); - lv_color_t *buf2 = heap_caps_malloc(EXAMPLE_LCD_H_RES * 200 * sizeof(lv_color_t), MALLOC_CAP_DMA); + lv_color_t *buf2 = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(lv_color_t), MALLOC_CAP_DMA); assert(buf2); // alloc bitmap buffer to draw converted_buffer_black = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 8, MALLOC_CAP_DMA); converted_buffer_red = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 8, MALLOC_CAP_DMA); // initialize LVGL draw buffers - lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * 200); + lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES); // initialize LVGL display driver lv_disp_drv_init(&disp_drv); disp_drv.hor_res = EXAMPLE_LCD_H_RES; diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/CMakeLists.txt b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/CMakeLists.txt new file mode 100644 index 000000000..158a2d39a --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(epaper_lvgl_rotate) \ No newline at end of file diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/README.md b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/README.md new file mode 100644 index 000000000..010254189 --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/README.md @@ -0,0 +1,92 @@ +# _LVGL Rotate_ + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example demonstrates rotation of the screen on an eInk display. It displays a long text string +at rotations of 0, 90, 180 and 270 degrees. It will work on a Waveshare 2.7" eInk display that natively +has screen dimensions of 176W x 264H; it should also work on a Waveshare 1.54" display with dimensions +200 x 200 (not tested by me). Changing the width and height constants (search main.c for DISPLAY_X) +should work with other displays that have SSD1680 or SSD1681 controllers. + +Rotating eInk displays is not the same as more dyanmic displays such as LCD. +The screen can be rotated only in multiples of 90 degrees: 0, 90, 180, 270. +An eInk display should not be updated often, in fact the manufacturers (Waveshare and GooDisplay) +state that displays should be rewritten no more often than 3 minutess. During development you can +rewrite more often, but this can shorten the lifetime of the display. +With some eInk displays it is possible to only update portions of the screen, but manufacturers +warn that this should not be done for too many cycles - eventually you should refresh the entire screen. +This demo only does full screen refreshes. + +An eInk display should usually be thought of as static - for example you will display +a weather forecast and update it every 15 minutes. + +Let's discuss eInk rotation. + +- eInk displays handled by this example have either a SSD1680 or SSD1681 controller. + +- The controller cannot perform hardware rotation (unlike some LCD). + +- Some eInk display examples in ESP-IDF and ESP-BSP use a 1.54 inch square display, 200x200 pixels. +You can rotate a square screen by multiples of 90 degrees by using mirror and swap axes operations. + +- If the display is not square, then most rotation schemes result in a clipped output. +Swapping X&Y axes is poorly defined. + +- LVGL can do software rotation (sw_rotate=true), but it is unusable for our needs. Why? +Suppose the display is 200W x 100H. When you rotate by 90, many algorithms don't know +where to put the pixels from 101 to 200, so the screen image becomes a square measuring 100 x 100 +and the screen image is clipped. + +Waveshare eInk displays have a default orientation, portrait or landscape. AFAIK, +the SSD1680 controller cannot be programmed to change the orientation (sure would be nice). +Many non-square displays are portrait, even though many applications would prefer landscape. +So what to do? + +- The controller does not perform hardware rotation. + +- LVGL software rotation has problems (see below). + +- Since we want to change orientation between portrait and landscape, we need a function that +moves the pixels from rows to columns. + +## What are the problems with LVGL sw_rotate? + +If **sw_rotate=true**, then **full_refresh** must be *false*. This results in the full screen image +getting rotated in pieces and written to the device by DMA. While this is fine for an LCD, +eInk displays need to refresh when each DMA transfer completes, resulting in flashing of the disdplay +multiple times until all the chunks have been transferred. Furthermore, **sw_rotate** will clip the screen +image as mentioned above. + +## How can we change from portrait to landscape orientation? + +The answer is to use a *canvas*. We create a canvas in the desired orientation (for example: landscape) +and write to it. If you write a landscape canvas to a portrait display, it will be clipped. If you rotate +the landscape canvas by 90 or 270 degrees, you expect that it should appear on the screen without clipping. +You should be able to rotate a canvas with **lv_canvas_transform()**, but I was unable to get it to work +with LVGL v. 8.3.0. Therefore I wrote function **rotate_buffer()** to perform a 90 degree rotation. +270 degree roatation is performed with 90 degree rotation plus mirror on both X and Y axes. + +## How to use example +We encourage the users to use the example as a template for new projects. +A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project). + +## Example folder contents + +The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main). + +ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` +files that provide set of directives and instructions describing the project's source files and targets +(executable, library, or both). + +Below is short explanation of remaining files in the project folder. + +``` +├── CMakeLists.txt +├── main +│   ├── CMakeLists.txt +│   ├── main.c +│ └── lvgl_demo_ui.c +└── README.md This is the file you are currently reading +``` +Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system. +They are not used or needed when building with CMake and idf.py. diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/CMakeLists.txt b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/CMakeLists.txt new file mode 100644 index 000000000..52fb02e01 --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "lvgl_demo_ui.c" + INCLUDE_DIRS ".") diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/idf_component.yml b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/idf_component.yml new file mode 100644 index 000000000..a7f8ba42e --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/idf_component.yml @@ -0,0 +1,9 @@ +dependencies: + idf: ">=5.0" + lvgl/lvgl: "~8.3.0" + esp_lcd_ssd1681: + # I am specifying the path of the component because the component + # had not been published to the ESP Component Registry by the time + # I write this example. + # Development will be better if you add esp_lcd_ssd1681 as a component to your project. + path: "../../../" diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/lvgl_demo_ui.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/lvgl_demo_ui.c new file mode 100644 index 000000000..2df4dda2c --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/lvgl_demo_ui.c @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +// This demo UI is adapted from LVGL official example: https://docs.lvgl.io/master/widgets/extra/meter.html#simple-meter +// This demo writes text onto canvas that can later be rotated to appear on a portrait or landscape oriened display. + +#define LV_FONT_MONTSERRAT_28 1 // 28 pt font. Must precede "lvgl.h". + +#include "lvgl.h" +#include "esp_heap_caps.h" + +#define CANVAS_COLOR_FORMAT LV_IMG_CF_ALPHA_1BIT // desginates 1 bit per pixel display. + +extern void rotate_buffer(uint32_t rotate, int xlen, int ylen, uint8_t *in_buf, uint8_t *out_buf); + +static lv_style_t style_28; +static uint8_t *canvas_buffer = NULL; +/** + * + * @brief Use LVGL canvas to generate display and demonstrate rotation + * @param width pixels of non-rotated display + * @param height pixels of non-rotated display + * @param rotate LVGL rotation value, [0, 1, 2, 3] for LV_DISP_ROT_ + * @note A canvas is created with no parent. Text is written to the canvas. + * The canvas is then assigned the active screen as parent. + * This apparently causes lvgl_flush_callback to be invoked. + */ +void lvgl_canvas_ui(int width, int height, uint32_t rotate) + +{ + int disp_x, disp_y; + if (rotate == LV_DISP_ROT_90 || rotate == LV_DISP_ROT_270) { + disp_x = height; + disp_y = width; + } else { + disp_y = height; + disp_x = width; + } + if (!canvas_buffer) { + // Needs 8 extra bytes for monochrome displays? + canvas_buffer = heap_caps_malloc(disp_x * disp_y / 8 + 8, MALLOC_CAP_DMA); + } + memset(canvas_buffer, 0x00, disp_x * disp_y / 8 + 8); + + // Create a screen (a necessary, non-visible step in LVGL) + lv_obj_t *scr = lv_obj_create(NULL); // canvas must not be attached to display until later + // Create the canvas on the screen + lv_obj_t *canvas = lv_canvas_create(scr); + // Assign canvas_buffer to the canvas. The canvas is configured to be either portrait or landscape orientation. + lv_canvas_set_buffer(canvas, canvas_buffer, disp_x, disp_y, CANVAS_COLOR_FORMAT); + lv_canvas_fill_bg(canvas, lv_color_hex(0x000000), LV_OPA_0); // 0x000000 is a white background on eInk displays + +#if 0 + // NOTE: palette is only used with indexed color formats, not monochrome. + // Might be used for multi-color eInk displays? + lv_canvas_set_palette(canvas, 0, LV_COLOR_WHITE); + lv_canvas_set_palette(canvas, 1, LV_COLOR_BLACK); +#endif + + lv_style_init(&style_28); + lv_style_set_text_font(&style_28, &lv_font_montserrat_28); + lv_draw_label_dsc_t label_dsc; // label properties descriptor + lv_draw_label_dsc_init(&label_dsc); + label_dsc.color = lv_color_make(0xFF, 0xFF, 0xFF); // Black color (or use lv_color_hex(0xFFFFFF)) + label_dsc.font = &lv_font_montserrat_28; // Use a built-in font + label_dsc.align = LV_TEXT_ALIGN_LEFT; + + int xoff = 10, yoff = 10; // offset for start of text string + // canvas_draw_text automatically wraps text when right margin is reached + lv_canvas_draw_text(canvas, xoff, yoff, disp_x - xoff, &label_dsc, "This text goes to end of line and then wraps. Isn't that cool?"); + + // Now we need a second canvas if we want to rotate + lv_obj_t *rot_canvas = lv_canvas_create(lv_obj_create(NULL)); + uint8_t *rot_buf = heap_caps_malloc(disp_x * disp_y / 8 + 8, MALLOC_CAP_DMA); + memset(rot_buf, 0x00, disp_x * disp_y / 8 + 8); + + if (rotate == LV_DISP_ROT_90 || rotate == LV_DISP_ROT_270) { +#if 1 // use my rotate function + // ROT_270 is performed by ROT90 and then mirror both X & Y (in main.c) + rotate_buffer(rotate, disp_x, disp_y, canvas_buffer, rot_buf); + lv_canvas_set_buffer(canvas, rot_buf, width, height, LV_IMG_CF_ALPHA_1BIT); + +#else // use lvgl_canvas_transform + // Display of 90 appears as 0 degrees, and clipped on right side. + // Display of 270 appears as 180 degrees, and clipped on left side of display. + // The text is first written to a landscape canvas. Thus it seems that no rotation occurs, + // thereby resulting in the text clipping. + int angle = 900 * rotate; + + lv_canvas_set_buffer(rot_canvas, rot_buf, height, width, LV_IMG_CF_ALPHA_1BIT); + lv_img_dsc_t img_desc = *lv_canvas_get_img(canvas); + lv_canvas_transform(rot_canvas, &img_desc, angle, 256, 0, 264, width / 2, height / 2, true); + lv_canvas_copy_buf(canvas, rot_buf, 0, 0, lv_obj_get_height(rot_canvas), lv_obj_get_width(rot_canvas)); +#endif + } + // Must clear LVGL display, else we get "double-exposure" image on screen + lv_obj_clean(lv_scr_act()); + // Attach the canvas to the active screen (the display device). + // This presumably triggers LVGL flush callback (see flush_cb in main.c) + lv_obj_set_parent(canvas, lv_scr_act()); +} diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/main.c b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/main.c new file mode 100644 index 000000000..715ca133a --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/main.c @@ -0,0 +1,546 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "esp_timer.h" +#include "esp_lcd_panel_io.h" +#include "esp_lcd_panel_vendor.h" +#include "esp_lcd_panel_ops.h" +#include "driver/gpio.h" +#include "driver/spi_master.h" +#include "esp_err.h" +#include "esp_check.h" +#include "esp_log.h" +#include "lvgl.h" + +#include "ssd1681_waveshare_1in54_lut.h" + +static const char *TAG = "main"; + +// Program displays screen with each of these rotation values +const uint32_t ROTATE_TEST[] = { + LV_DISP_ROT_NONE, + LV_DISP_ROT_90, + LV_DISP_ROT_180, + LV_DISP_ROT_270 +}; + +#define TEST_DELAY 15000 // time between each rotate of display, milliseconds + +// Using SPI2 in the example +#define LCD_HOST SPI2_HOST + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// Please update the following configurations according to your LCD spec ///////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define LCD_PIXEL_CLOCK_HZ (20 * 1000 * 1000) + +// ------ Waveshare or GooDisplay 2.7" B&W with SSD1680 controller ------ // +#define WAVE_27 1 + +// The pixel dimension in horizontal and vertical +#if defined(WAVE_27) && WAVE_27==1 +#define LCD_H_RES 176 +#define LCD_V_RES 264 +#define SQUARE_DISP 0 +#define BLACK_RED_DISP 0 // don't know if this example supports it +#elif defined(WAVE_154) && WAVE_154==1 +#define LCD_H_RES 200 +#define LCD_V_RES 200 +#define SQUARE_DISP 1 +#define BLACK_RED_DISP 1 +#endif + +#define DISPLAY_X LCD_H_RES +#define DISPLAY_Y LCD_V_RES + +// ----- GPIO pin assignments ----- // +#if 0 +#define PIN_NUM_SCLK 6 +#define PIN_NUM_MOSI 7 +#define PIN_NUM_MISO (-1) // Unused +#define PIN_NUM_EPD_DC 9 +#define PIN_NUM_EPD_RST 4 +#define PIN_NUM_EPD_CS 10 +#define PIN_NUM_EPD_BUSY 18 +#endif +#if 1 +// e-Paper GPIO with Waveshare ESP32S3 +#define PIN_NUM_EPD_DC 8 +#define PIN_NUM_EPD_RST 10 +#define PIN_NUM_EPD_CS 5 +#define PIN_NUM_EPD_BUSY 11 +// e-Paper SPI +#define PIN_NUM_MOSI 15 +#define PIN_NUM_SCLK 18 +#define PIN_NUM_MISO (-1) // Unused +#endif + +// Bit number used to represent command and parameter +#define LCD_CMD_BITS 8 +#define LCD_PARAM_BITS 8 + +#define LVGL_TICK_PERIOD_MS 2 + +static uint8_t *converted_buffer_black; +static uint8_t *converted_buffer_red; +#define TRAVERSE_COLS 0 // experiment if ==1, traverse columns + +static SemaphoreHandle_t panel_refreshing_sem = NULL; + +extern void lvgl_canvas_ui(int xdim, int ydim, uint32_t rotate); + +IRAM_ATTR bool epaper_flush_ready_callback(const esp_lcd_panel_handle_t handle, const void *edata, void *user_data) +{ + lv_disp_drv_t *disp_driver = (lv_disp_drv_t *) user_data; + lv_disp_flush_ready(disp_driver); + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(panel_refreshing_sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) { + return true; + } + return false; +} + +// Can rotate input buffer by 0, 90, 180 or 270 degrees. +// The buffers represent the display as an array of bytes, each byte contains 8 monochrome pixels in a row. +// xlen: number of pixels in a row. +// ylen: number of rows. +// Therefore each row has xlen/8 bytes. +void rotate_buffer(uint32_t rotate, int xlen, int ylen, uint8_t *in_buf, uint8_t *out_buf) +{ + esp_log_level_set("rotate_buffer", ESP_LOG_DEBUG); + ESP_LOGD("rotate_buffer", "in_buf: xlen=%d, ylen=%d", xlen, ylen); + const int MAX_ERR_MSG = 5; + int bad0 = 0, bad1 = 0; // record any mistakes where the index is out of bounds (I think this is completely debugged now) + memset(out_buf, 0x0, xlen * ylen / 8); + + if (rotate == LV_DISP_ROT_90 || rotate == LV_DISP_ROT_270) { + // ------- Code for 90 degree rotation ---------- // + // ---- 270 rotation uses this code followed by mirror on both X&Y axes ---- // + int in_idx, out_idx; + // iterate over columns of in_buf + for (int ix = 0; ix < xlen / 8; ix++) { + // iterate over rows of in_buf + for (int iy = 0; iy < ylen; iy += 1) { + in_idx = (iy * xlen) / 8 + ix; + if (in_idx >= (xlen * ylen) / 8 || in_idx < 0) { + // BIG surprise if this ever hahpens! + ESP_LOGE("rotate_buffer", "in_buf: out-of-bounds: in_idx = %d, ix = %d, iy = %d", in_idx, ix, iy); + continue; + } + uint8_t inbits = in_buf[in_idx]; + // with 90 rotate, idx0 is the out_buf location for the first bit (bit7 of inbits) + int idx0 = (xlen - ix * 8 - 1) * ylen / 8 + iy / 8; + // iterate over bits + for (int ii = 0; ii < 8; ii++) { + out_idx = idx0 - ii * ylen / 8; // each bit from inbits translates to the next row up in out_buf + if (out_idx >= (xlen * ylen) / 8) { + // When I was debugging this I had instances of impossible values + if (bad1 < MAX_ERR_MSG) { + ESP_LOGE("rotate_buffer", "out_idx = %d, ix = %d, iy = %d, ii = %d", out_idx, ix, iy, ii); + } + bad1++; + continue; + } + if (out_idx < 0) { + // When I was debugging this I had instances of impossible values + if (bad0 < MAX_ERR_MSG) { + ESP_LOGE("rotate_buffer", "out_idx = %d, ix = %d, iy = %d, ii = %d", out_idx, ix, iy, ii); + } + bad0++; + continue; + } + uint8_t inbit = (inbits & (1 << (7 - ii))) ? 0x1 : 0x0; // the current bit + out_buf[ out_idx ] |= inbit << (7 - iy % 8); + } + } + } + if (bad0 || bad1) { + ESP_LOGE("rotate_buffer", "out_buf: out-of-bounds: idx < 0: %d, idx > max: %d", bad0, bad1); + } + } else { + // Either 0 or 180 degree rotate which is accomplished by using function mirror_xy elsewhere in code + // Do nothing here, just copy in_buf to out_buf + memcpy(out_buf, in_buf, (xlen * ylen) / 8); + } +#if 0 // print entire buffer for debugging +#if 0 // print in_buf + // write buffer to stdout + for (int iy = 0; iy < ylen; iy++) { + //printf("%3d: ", iy); + for (int ix = 0; ix < xlen / 8; ix++) { + printf("0x%02x, ", in_buf[ix + iy * xlen / 8]); + } + printf("\n"); + } +#else// prin out_buf + int itmp = xlen; + xlen = ylen; + ylen = itmp; + for (int iy = 0; iy < ylen; iy++) { + //printf("%3d: ", iy); + for (int ix = 0; ix < xlen / 8; ix++) { + printf("0x%02x, ", out_buf[ix + iy * xlen / 8]); + } + printf("\n"); + } +#endif +#endif + ESP_LOGD("rotate_buffer", "OK DONE"); +} + +/** + * Callback function that transfer data to display. + */ +static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) +{ + esp_log_level_set(TAG, ESP_LOG_DEBUG); + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; + int offsetx1 = area->x1; + int offsetx2 = area->x2; + int offsety1 = area->y1; + int offsety2 = area->y2; + ESP_LOGD(TAG, "flush_cb: X offset = (%d, %d), Y offset = (%d, %d)", offsetx1, offsetx2, offsety1, offsety2); + int xlen = abs(offsetx1 - offsetx2) + 1; + int ylen = abs(offsety1 - offsety2) + 1; + // --- Convert buffer from color to monochrome bitmap + int len_bits = (xlen * ylen); + + memset(converted_buffer_black, 0x00, len_bits / 8); +#if BLACK_RED_DISP + memset(converted_buffer_red, 0x00, len_bits / 8); +#endif + for (int i = 0; i < len_bits; i++) { + // NOTE: Set bits of converted_buffer[] FROM LOW ADDR TO HIGH ADDR, FROM HSB TO LSB + // NOTE: 1 means BLACK/RED, 0 means WHITE +#if !TRAVERSE_COLS + // Horizontal traverse lvgl framebuffer (by row) + converted_buffer_black[i / 8] |= (((lv_color_brightness(color_map[i])) < 251) << (7 - (i % 8))); +#if BLACK_RED_DISP + converted_buffer_red[i / 8] |= ((((color_map[i].ch.red) > 3) && ((lv_color_brightness(color_map[i])) < 251)) << (7 - (i % 8))); +#endif +#else // TRAVERSE_COLS==1. An experiment. + // Vertical traverse lvgl framebuffer (by column) + // NOTE: If your screen rotation requires setting the pixels vertically, you could use the code below. + // I don't think this functions as a way to change default orientation from portrait to landscape. + int ii; + ii = ((i * xlen) % len_bits) + i / ylen; + converted_buffer_black[i / 8] |= (((lv_color_brightness(color_map[ii])) < 251) << (7 - (i % 8))); +#if BLACK_RED_DISP + converted_buffer_red[i / 8] |= ((((color_map[ii].ch.red) > 3) && ((lv_color_brightness(color_map[ii])) < 251)) << (7 - (i % 8))); +#endif +#endif + } + + // --- Draw bitmap - this performs DMA transfer + ESP_ERROR_CHECK(epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_BLACK)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, converted_buffer_black)); +#if BLACK_RED_DISP + ESP_ERROR_CHECK(epaper_panel_set_bitmap_color(panel_handle, SSD1681_EPAPER_BITMAP_RED)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, converted_buffer_red)); +#endif + // refresh_screen is required to make the new screen image visible. It is accompanied by visible flashing of eInk display. + ESP_ERROR_CHECK(epaper_panel_refresh_screen(panel_handle)); +} + +static void lvgl_wait_cb(struct _lv_disp_drv_t *disp_drv) +{ + xSemaphoreTake(panel_refreshing_sem, portMAX_DELAY); +} + +// normally this would be done in lvgl_port_update_callback, but non-square eInk displays have problems with that. +static void set_swap_mirror(lv_disp_drv_t *drv, uint32_t rotate) +{ + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "set_swap_mirror: rotated = %lu", rotate); + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; +#if SQUARE_DISP // square display can accomplish display rotation with combination of mirror and swap_xy + switch (rotate) { + case LV_DISP_ROT_NONE: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_90: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, false, true); + break; + case LV_DISP_ROT_180: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + case LV_DISP_ROT_270: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, true, false); + break; + } +#else // not SQUARE + // Non-square display cannot use swap_xy, must be handled by LVGL sw_rotate, + // so be sure to set all to false. + switch (rotate) { + case LV_DISP_ROT_NONE: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_180: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + case LV_DISP_ROT_90: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_270: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + } +#endif +} + +/** + * Tell LVGL to rotate display and touch. + * Called when driver parameters are updated. + * NOTE: this function causes problems with non-square displays, principally because + * if drv->rotated is 90 or 270 then LVGL does things that are incompatible + * with the intent of changing orientation from portrait to landscape. + * + */ +static void lvgl_port_update_callback(lv_disp_drv_t *drv) +{ + esp_log_level_set(TAG, ESP_LOG_DEBUG); + ESP_LOGD(TAG, "lvgl_port_update_callback"); + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data; +#if SQUARE_DISP // square display can accomplish display rotation with combination of mirror and swap_xy + switch (drv->rotated) { + case LV_DISP_ROT_NONE: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_90: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, false, true); + break; + case LV_DISP_ROT_180: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + case LV_DISP_ROT_270: + // Rotate LCD display + esp_lcd_panel_swap_xy(panel_handle, true); + esp_lcd_panel_mirror(panel_handle, true, false); + break; + } +#else // not SQUARE + // Non-square display cannot use swap_xy, must be handled by LVGL sw_rotate, + // so be sure to set all to false. + ESP_LOGD(TAG, "port_update: rotated = %d", drv->rotated); + switch (drv->rotated) { + case LV_DISP_ROT_NONE: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_180: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + case LV_DISP_ROT_90: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, false, false); + break; + case LV_DISP_ROT_270: + esp_lcd_panel_swap_xy(panel_handle, false); + esp_lcd_panel_mirror(panel_handle, true, true); + break; + } +#endif +} + +/** + * This function carries over from another example, don't know if it's needed. + */ +static void example_increase_lvgl_tick(void *arg) +{ + /* Tell LVGL how many milliseconds has elapsed */ + lv_tick_inc(LVGL_TICK_PERIOD_MS); +} + +void app_main(void) +{ + static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) + static lv_disp_drv_t disp_drv; // contains callback functions + + esp_log_level_set(TAG, ESP_LOG_DEBUG); + + panel_refreshing_sem = xSemaphoreCreateBinary(); + xSemaphoreGive(panel_refreshing_sem); + + ESP_LOGI(TAG, "Initialize SPI bus"); + spi_bus_config_t buscfg = { + .sclk_io_num = PIN_NUM_SCLK, + .mosi_io_num = PIN_NUM_MOSI, + .miso_io_num = PIN_NUM_MISO, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = DISPLAY_X * DISPLAY_Y / 8, + }; + ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); + + ESP_LOGI(TAG, "Install panel IO"); + esp_lcd_panel_io_handle_t io_handle = NULL; + esp_lcd_panel_io_spi_config_t io_config = { + .dc_gpio_num = PIN_NUM_EPD_DC, + .cs_gpio_num = PIN_NUM_EPD_CS, + .pclk_hz = LCD_PIXEL_CLOCK_HZ, + .lcd_cmd_bits = LCD_CMD_BITS, + .lcd_param_bits = LCD_PARAM_BITS, + .spi_mode = 0, + .trans_queue_depth = 10, + .on_color_trans_done = NULL, + }; + // --- Attach the LCD to the SPI bus + ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t) LCD_HOST, &io_config, &io_handle)); + esp_lcd_panel_handle_t panel_handle = NULL; + + // --- Create esp_lcd panel + esp_lcd_ssd1681_config_t epaper_ssd1681_config = { + .busy_gpio_num = PIN_NUM_EPD_BUSY, + // NOTE: Enable this to reduce one buffer copy if you do not use swap-xy, mirror y or invert color + // since those operations are not supported by ssd1681 and are implemented by software + // Better use DMA-capable memory region, to avoid additional data copy + .non_copy_mode = false, // TODO: was true + // panel dimensions - not used by LVGL + .display_x = DISPLAY_X, + .display_y = DISPLAY_Y, + }; + esp_lcd_panel_dev_config_t panel_config = { + .reset_gpio_num = PIN_NUM_EPD_RST, + .flags.reset_active_high = false, + .vendor_config = &epaper_ssd1681_config + }; + gpio_install_isr_service(0); + // panel_handle is returned. io_handle is a member. + ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1681(io_handle, &panel_config, &panel_handle)); + + // --- Reset the display + ESP_LOGI(TAG, "Resetting e-Paper display..."); + ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); + vTaskDelay(100 / portTICK_PERIOD_MS); // for ESP32 this equates to a delay of 100 ms + // --- Initialize panel + ESP_LOGI(TAG, "Initializing e-Paper display..."); + ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); + // --- Register the e-Paper refresh done callback + epaper_panel_callbacks_t cbs = { + .on_epaper_refresh_done = epaper_flush_ready_callback + }; + epaper_panel_register_event_callbacks(panel_handle, &cbs, &disp_drv); + vTaskDelay(100 / portTICK_PERIOD_MS); + // --- Turn on display + ESP_LOGI(TAG, "Turning e-Paper display on..."); + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); + vTaskDelay(100 / portTICK_PERIOD_MS); + // --- Configurate the screen + // NOTE: the configurations below are all FALSE by default + //ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false)); + //ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel_handle, false)); + esp_lcd_panel_invert_color(panel_handle, false); + // NOTE: Calling esp_lcd_panel_disp_on_off(panel_handle, true) will reset the LUT to the panel built-in one, + // custom LUT will not take effect any more after calling esp_lcd_panel_disp_on_off(panel_handle, true) + // TODO: why call this a second time? + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); + + // --------------------------- // + // ----- Initialize LVGL ----- // + // --------------------------- // + ESP_LOGI(TAG, "Initialize LVGL library"); + lv_init(); + // alloc draw buffers used by LVGL + // it's recommended to choose the size of the draw buffer(s) to be at least 1/10 screen sized + // TODO: for B&W epaper, shouldn't the buffer be divide by 8? + lv_color_t *buf1 = heap_caps_malloc(DISPLAY_X * DISPLAY_Y * sizeof(lv_color_t), MALLOC_CAP_DMA); + assert(buf1); +#if 0 + // optional second display buffer for faster updates - not useful for eInk + lv_color_t *buf2 = heap_caps_malloc(DISPLAY_X * DISPLAY_Y * sizeof(lv_color_t), MALLOC_CAP_DMA); + assert(buf2); +#endif + // alloc bitmap buffer to draw. Add 8 for monochrome palette? + converted_buffer_black = heap_caps_malloc(DISPLAY_X * DISPLAY_Y / 8 + 8, MALLOC_CAP_DMA); +#if BLACK_RED_DISP + converted_buffer_red = heap_caps_malloc(DISPLAY_X * DISPLAY_Y / 8 + 8, MALLOC_CAP_DMA); +#endif + // initialize LVGL draw buffers + lv_disp_draw_buf_init(&disp_buf, buf1, NULL, DISPLAY_X * DISPLAY_Y); + // initialize LVGL display driver + lv_disp_drv_init(&disp_drv); + //lv_display_set_color_format(disp_drv, LV_COLOR_FORMAT_I1); // recommended but did not compile + disp_drv.flush_cb = lvgl_flush_cb; + disp_drv.wait_cb = lvgl_wait_cb; + disp_drv.drv_update_cb = lvgl_port_update_callback; + disp_drv.draw_buf = &disp_buf; + disp_drv.user_data = panel_handle; + // NOTE: The ssd1681 e-paper is monochrome and 1 byte represents 8 pixels + // so full_refresh is MANDATORY because we cannot set position to bitmap at pixel level + // NOTE (GDN): eInk controllers don't seem to have hardware rotate, + // so we have to provide our own rotate function. + // Do not use sw_totate=true for eInk displays because it results in multiple refreshes of screen + // and the rotated image will always be clipped. + disp_drv.rotated = LV_DISP_ROT_NONE; + disp_drv.full_refresh = true; + disp_drv.sw_rotate = false; + disp_drv.hor_res = DISPLAY_X; + disp_drv.ver_res = DISPLAY_Y; + ESP_LOGI(TAG, "Register display driver to LVGL"); + lv_disp_t *disp = lv_disp_drv_register(&disp_drv); +#if 0 // lvgl_port_update_callback causes trouble if you want to rotate by 90 or 270 + lv_disp_set_rotation(disp, LV_DISP_ROT_NONE); // must do this in order to activate lvgl_port_update_callback +#endif + + // init lvgl tick - but is it needed? + ESP_LOGI(TAG, "Install LVGL tick timer"); + // Tick interface for LVGL (using esp_timer to generate 2ms periodic event) + const esp_timer_create_args_t lvgl_tick_timer_args = { + .callback = &example_increase_lvgl_tick, + .name = "lvgl_tick" + }; + esp_timer_handle_t lvgl_tick_timer = NULL; + ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, LVGL_TICK_PERIOD_MS * 1000)); + + // ----- The main loop. eInk demo is not interactive, so the loop exits. ----- // + uint32_t lv_time; + for (int i = 0; i < sizeof(ROTATE_TEST) / sizeof(ROTATE_TEST[0]); i++) { + // raise the task priority of LVGL and/or reduce the handler period can improve the performance + // The task running lv_timer_handler should have lower priority than that running `lv_tick_inc` + lv_time = lv_timer_handler(); + ESP_LOGD(TAG, "lv_time returned = %lu", lv_time); + set_swap_mirror(&disp_drv, ROTATE_TEST[i]); + lvgl_canvas_ui(DISPLAY_X, DISPLAY_Y, ROTATE_TEST[i]); + int delay_ms = 0; + while (delay_ms < TEST_DELAY) { + // waste time before changing display + lv_time = lv_timer_handler(); + // 10 is the smallest delay with FreeRTOS and ESP-IDF when using vTaskDelay + vTaskDelay(pdMS_TO_TICKS(10)); + delay_ms += 10; + } + } + + // Do not leave eInk panels powered on when you're done. + esp_lcd_panel_disp_on_off(panel_handle, false); +} diff --git a/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/ssd1681_waveshare_1in54_lut.h b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/ssd1681_waveshare_1in54_lut.h new file mode 100644 index 000000000..6bab06a3f --- /dev/null +++ b/components/lcd/esp_lcd_ssd1681/examples/epaper_lvgl_rotate/main/ssd1681_waveshare_1in54_lut.h @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#pragma once + + +// 0x00 ~ 0xff blink 1 time ~ 256 times to refresh +#define SSD1681_WAVESHARE_1IN54_REFRESH_TIME 0x01 +#define SSD1681_WAVESHARE_1IN54_V2_LUT_FULL_REFRESH ((uint8_t[]) { \ + /* LUT 0 VS Group 0~11 */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 1 VS Group 0~11 */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 2 VS Group 0~11, keep the same as LUT0 for Black-White e-Paper */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 3 VS Group 0~11, keep the same as LUT1 for Black-White e-Paper */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 4 VS Group 0~11, seems useless, just keep all zero */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + /* Only Group0~2 are used */ \ + /* Group 0 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 1 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0xA, 0x2, 0x0, 0xA, 0x2, 0x0, SSD1681_WAVESHARE_1IN54_REFRESH_TIME, \ + /* Group 2 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 3 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 4 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 5 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 6 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 7 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 8 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 9 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 10 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 11 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, \ + /* --- Other register params, do not transfer together with data above */ \ + 0x22, 0x17, 0x41, 0x0, 0x32, 0x20 \ +}) + +#define SSD1681_WAVESHARE_1IN54_V2_LUT_FAST_REFRESH ((uint8_t[]) { \ + /* LUT 0 VS Group 0~11 */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 1 VS Group 0~11 */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 2 VS Group 0~11, keep the same as LUT0 for Black-White e-Paper */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 3 VS Group 0~11, keep the same as LUT1 for Black-White e-Paper */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 4 VS Group 0~11, seems useless, just keep all zero */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + /* Only Group0~2 are used */ \ + /* Group 0 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 1 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 2 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 3 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 4 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 5 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 6 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 7 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 8 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 9 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 10 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 11 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, \ + /* --- Other register params, do not transfer together with data above */ \ + 0x22, 0x17, 0x41, 0x0, 0x32, 0x20 \ +}) + +// NOTE: After several refreshes using SSD1681_WAVESHARE_1IN54_V2_LUT_FAST_REFRESH, you may notice the WHITE color +// goes GRAY and contrast decrease a lot. Use the LUT below to avoid that issue. +// NOTE: The LUT below will have the source output "keep previous output before power off", so the service life may be affected. +#define SSD1681_WAVESHARE_1IN54_V2_LUT_FAST_REFRESH_KEEP ((uint8_t[]) { \ + /* LUT 0 VS Group 0~11 */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 1 VS Group 0~11 */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 2 VS Group 0~11, keep the same as LUT0 for Black-White e-Paper */ \ + 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 3 VS Group 0~11, keep the same as LUT1 for Black-White e-Paper */ \ + 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* LUT 4 VS Group 0~11, seems useless, just keep all zero */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + /* Only Group0~2 are used */ \ + /* Group 0 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 1 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 2 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 3 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 4 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 5 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 6 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 7 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 8 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 9 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 10 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* Group 11 TP[*A] TP[*B] SR[*AB] TP[*C] TP[*D] SR[*CD] RP[*] */ \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, \ + /* --- */ \ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0, \ + /* --- Other register params, do not transfer together with data above */ \ + 0x07, 0x17, 0x41, 0x0, 0x32, 0x20 \ +}) diff --git a/components/lcd/esp_lcd_ssd1681/include/esp_lcd_panel_ssd1681.h b/components/lcd/esp_lcd_ssd1681/include/esp_lcd_panel_ssd1681.h index 8cc357458..6c9922503 100644 --- a/components/lcd/esp_lcd_ssd1681/include/esp_lcd_panel_ssd1681.h +++ b/components/lcd/esp_lcd_ssd1681/include/esp_lcd_panel_ssd1681.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +40,8 @@ typedef struct { int busy_gpio_num; /*!< GPIO num of the BUSY pin */ bool non_copy_mode; /*!< If the bitmap would be copied or not. * Image rotation and mirror is limited when enabling. */ + int display_x; + int display_y; } esp_lcd_ssd1681_config_t; /**