Подготовка растровых картинок для индикатора OLED WEX025664 Печать
Добавил(а) microsin   

Индикатор OLED WEX025664 (работающий на основе контроллера SSD1322) позволяет отображать картинки с глубиной яркости 4 бита (16 градаций серого). Для редактирования и подготовки таких картинок можно использовать Photoshop.

[Как получить картинку с градациями серого]

Сначала картинку надо преобразовать в монохромный режим с градациями серого (если она не в этом формате) - это можно сделать через меню Image -> Mode -> Grayscale. Это важный шаг, потому что цветную картинку нельзя сохранить в формат BMP с малым количеством градаций яркости 4 бита.

Photoshop make picture Grayscale

Затем нужно сохранить её в формат BMP, с градациями яркости 4 бита на точку, для чего зайдите в меню File, далее выберите Save As... -> из выпадающего списка Format: выберите BMP и нажмите кнопку Сохранить. Появится окошко, которое позволяет выбрать опции сохранения. Выберите режим сохранения в формате 4 Bit, как показано на этом скриншоте:

Photoshop save picture grayscale 4bit

Если Ваш индикатор поддерживает уровни яркости больше 4 бит на точку, то можно выбрать формат 8 бит на точку, но тогда картинки будут занимать довольно много места в памяти. Для OLED WEX025664 подойдет формат Greyscale 4 bit, либо монохромный формат (1 бит на точку).

[Как получить монохромную картинку]

В Photoshop выберите в меню File -> New, введите нужные размеры картинки в поля Width и Height, в выпадающем списке выберите Bitmap, 1 bit, нажмите OK.

Photoshop make picture Monochrome

Теперь Вы можете нарисовать картинку, либо методом Copy-Paste вставить в нее любое графическое изображение, даже цветное. Вставленная картинка автоматически станет монохромной. Ниже показан пример такой вставки.

Photoshop picture Monochrome example

Характерные точки, которые видны на картинке, говорит нам о том, что для преобразования полутонов в монохром применялся дизериг (dithering).

[Преобразование BMP-картинки в HEX-дамп]

Чтобы можно было использовать полученную картинку в программе микроконтроллера, её нужно из формата BMP преобразовать в массив двоичных данных, например так:

const char MyPicture [] =
{
   /* 65x64-greyscale-4bit.bmp */
   'B', 'M', 0x78,0x09,0x00,0x00,0x00,0x00,
   0x00,0x00,0x76,0x00,0x00,0x00,0x28,0x00,
   ...
   0x01,0x11,0x10,0x00,0x66,0x66,0x00,0x00
};

Для преобразования можно использовать утилиту bmptoc с опцией -noheader, пример создания дампа файла 65x64-greyscale-4bit.bmp:

bmptoc.exe 65x64-greyscale-4bit.bmp -noheader

В результате в консоль выведется HEX-дамп всего файла вместе с заголовком:

0x42,0x4D,0x78,0x09,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x41,0x00,0x00,0x00,0x40,0x00,
0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,
...
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
0x01,0x11,0x10,0x00,0x66,0x66,0x00,0x00,

Теперь эти данные можно скопипастить с массив модуля на языке C и использовать в своей программе.

Исходный код утилиты bmptoc и скомпилированный бинарник можно скачать по ссылкам в статье [4]. В этой же статье Вы найдете описание других утилит для преобразования двоичного файла в HEX-дамп и обратно.

[Как отобразить монохромную картинку на экране OLED]

Вывести данные монохромного растра на индикатор можно с помощью функции drawBitmap библиотеки u8glib.

Функция drawBitmap [2] рисует растровую картинку (bitmap) в указанной позиции (x, y) экрана. Указанная позиция соответствует левому верхнему краю картинки. Напомню, что такой отсчет координат является общепринятым для вывода на графические индикаторы, т. е. координата х растет от 0 слева направо (x=0 соответствует крайней левой границе экрана), а координата y растет сверху вниз (y=0 соответствует крайней верхней границе экрана). Части отображаемой растровой картинки могут выходить за пределы границ экрана дисплея.

Растр указан как массив графических данных bitmap. Очищенный бит означает, что точку засвечивать не нужно. Установленный бит в массиве означает, что в этой точке нужно записать точку с текущим индексом цвета. Для монохромных дисплеев индекс 0 цвета обычно очищает (гасит) точку, и индекс цвета 1 установит (зажжет) точку экрана.

Функцию drawBitmap следует использовать точно так же, как и все другие графические функции библиотеки u8glib - внутри цикла Picture Loop [3] (пример см. ниже).

Прототипы функции вывода картинки на языке C++:

void U8GLIB::drawBitmap(u8g_uint_t x,
                        u8g_uint_t y,
                        u8g_uint_t cnt,
                        u8g_uint_t h,
                        const uint8_t *bitmap);
void U8GLIB::drawBitmapP(u8g_uint_t x,
                         u8g_uint_t y,
                         u8g_uint_t cnt,
                         u8g_uint_t h,
                         const u8g_pgm_uint8_t *bitmap);

Прототипы тех же функций на языке C:

void u8g_DrawBitmap(u8g_t *u8g,
                     u8g_uint_t x,
                     u8g_uint_t y,
                     u8g_uint_t cnt,
                     u8g_uint_t h,
                     const uint8_t *bitmap);
void u8g_DrawBitmapP(u8g_t *u8g,
                      u8g_uint_t x,
                      u8g_uint_t y,
                      u8g_uint_t cnt,
                      u8g_uint_t h,
                      const u8g_pgm_uint8_t *bitmap);

Примечание: суффикс P у функции относится главным образом для архитектуры AVR, чтобы картинку можно было поместить не в оперативной памяти, а в памяти программ PROGMEM (т. е. FLASH). Причина такого синтаксиса кроется в адаптации компилятора GCC к Гарвардской архитектуре процессоров AVR.

[Аргументы]

u8g: указатель на структуру u8g библиотеки (этот параметр используется только в интерфейсе языка C).
x: позиция X (левая позиция начала картинки на экране).
y: позиция Y (верхняя позиция начала картинки на экране).
cnt: количество байт картинки в горизонтальном направлении. Ширина картинки будет cnt*8.
h: высота картинки в точках.

[Пример (для Arduino)]

// Обмен через SPI: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8
U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8);
 
const uint8_t rook_bitmap[] U8G_PROGMEM = {
  0x00,         // 00000000 
  0x55,         // 01010101
  0x7f,         // 01111111
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x7f          // 01111111
};
 
void draw(void) {
  // Здесь вставляются графические команды для полной перерисовки
  //  всего изображения индикатора:
  u8g.drawBitmapP(0, 0, 1, 8, rook_bitmap);
}
 
void setup(void) {
}
 
void loop(void) {
  // Цикл графики picture loop.
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // После задержки в 1 секунду картинка будет
  //  перерисована заново.
  delay(1000);
}

u8glib drawBitmap

Процедура drawXBM рисует XBM Bitmap. Позиция (x, y) соответствует левому верхнему краю картинки. XBM содержит монохромную картинку, 1-bit bitmap. Эта процедура будет рисовать только те точки, у которых биты в растре установлены в 1. Для рисования точки используется текущий индекс цвета (установленный функцией setColorIndex). Точки, биты которых равны 0, не рисуются (они прозрачные).

Функцию drawXBM следует использовать точно так же, как и все другие графические функции библиотеки u8glib - внутри цикла Picture Loop [3] (пример см. ниже).

Прототипы функции на языке C++:

void U8GLIB::drawXBM(u8g_uint_t x,
                     u8g_uint_t y,
                     u8g_uint_t w,
                     u8g_uint_t h,
                     const uint8_t *bitmap);
void U8GLIB::drawXBMP(u8g_uint_t x,
                      u8g_uint_t y,
                      u8g_uint_t w,
                      u8g_uint_t h,
                      const u8g_pgm_uint8_t *bitmap);

Прототипы тех же функции на языке C:

void u8g_DrawXBM(u8g_t *u8g,
                 u8g_uint_t x,
                 u8g_uint_t y,
                 u8g_uint_t w,
                 u8g_uint_t h,
                 const uint8_t *bitmap);
void u8g_DrawXBMP(u8g_t *u8g,
                  u8g_uint_t x,
                  u8g_uint_t y,
                  u8g_uint_t w,
                  u8g_uint_t h,
                  const u8g_pgm_uint8_t *bitmap);

[Аргументы]

u8g: указатель на структуру u8g библиотеки (этот параметр используется только в интерфейсе языка C).
x: позиция X (левая позиция начала картинки на экране).
y: позиция Y (верхняя позиция начала картинки на экране).
w: ширина картинки в точках.
h: высота картинки в точках.
bitmap: указатель на начало массива растровой графики.

[Как использовать функцию DrawXBM]

Множество инструментов обработки графики могут сохранить растровую картинку в формат XBM. Результат будет выглядеть примерно как в этом примере:

#define u8g_logo_width 38
#define u8g_logo_height 24
static unsigned char u8g_logo_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0xe0,
   ...
   0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f
};

Чтобы нарисовать эту картинку относительно левого верхнего края экрана (точка с координатами 0, 0) используйте функцию drawXBM следующим образом:

u8g.drawXBM(0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);

Примечание: для архитектуры AVR хорошей идеей будет разместить картинку не в оперативной памяти, а в памяти программ PROGMEM. Для этого нужно переопределить массив графики с атрибутом U8G_PROGMEM:

static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
   ...

С этой модификацией нужно использовать вариант функции DrawXBM с суффиксом P:

u8g.drawXBMP(0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);

u8glib drawXBM

[Как вывести картинку с градациями яркости (Grayscale)]

К сожалению, функции drawBitmap и drawXBM позволяют выводить монохромные картинки, и не обрабатывают заголовки данных файла BMP. Поэтому картинку с градациями серого вывести с помощью них не получится. В принципе это можно понять - библиотека u8glib в основном предназначена для микроконтроллеров с малым объемом памяти.

Если памяти достаточно, то картинку можно вывести с помощью несложного дополнительного кода. В этом примере я покажу как вывести картинку размером 256x64 точки в формате 4 бита на точку на индикатор OLED WEX025664 [5]. Это очень удобный формат, потому что растр, который хранится в данных файла BMP, полностью совпадает с организацией памяти индикатора. Так что почти не нужны никакие перекодировки данных, потому можно сразу отправить дамп растра на индикатор строка за строкой.

Давайте рассмотрим внутренний формат картинки BMP с градациями серого 4 бита на точку, разрешение 256 x 64 точки (совпадает с разрешением индикатора WEX025664), размером 8312 байт. Вот пример такой такой картинки, которую будем выводить на экран WEX025664:

256x64 greyscale 4bit

Этот файл картинки BMP состоит из 3 структур, расположенных друг за другом (BITMAPFILEHEADER, BITMAPINFO, BITMAPCOLORTABLE), за которыми сразу идут данные растра картинки.

Дамп был подготовлен программой xxd [4], это порт одноименной утилиты с Linux:

xxd 256x64-greyscale-4bit.bmp

Отдельными цветами на дампе выделены структуры BITMAPFILEHEADER, BITMAPINFO, BITMAPCOLORTABLE. Эти три структуры составляют информационный заголовок файла (см. ниже во врезке), в котором закодированы все параметры картинки. Сразу после заголовка идут данные растра (эти байты на дампе не выделены цветом).

В данном примере каждая точка кодируется 4 битами (16 градаций яркости), поэтому на одну точку приходится 1 тетрада байта, и 1 байт кодирует 2 точки. Первыми в растре идут 128 байт нижней строки картинки, т. е. строка 63, если считать от нуля, за ней 128 байт 62-й строки, и так далее до конца файла, последние 128 байт (до байт выравнивания) кодируют самую верхнюю строку картинки.

0000000: 424d 7820 0000 0000 0000 7600 0000 2800  BMx ......v...(.
0000010: 0000 0001 0000 4000 0000 0100 0400 0000  ......@.........
0000020: 0000 0220 0000 ad1b 0000 ad1b 0000 0000  ... ............
0000030: 0000 0000 0000 0000 0000 1111 1100 2222  ..............""
0000040: 2200 3333 3300 4444 4400 5555 5500 6666  ".333.DDD.UUU.ff
0000050: 6600 7777 7700 8888 8800 9999 9900 aaaa  f.www...........
0000060: aa00 bbbb bb00 cccc cc00 dddd dd00 eeee  ................
0000070: ee00 ffff ff00 8889 9988 9988 8998 8899  ................
0000080: 9999 aa99 9999 9999 9999 8667 5333 1000  ...........gS3..
0000090: 0000 0000 0000 0000 0000 0011 1111 1111  ................
00000a0: 1111 1111 1111 1111 1111 1110 0111 1111  ................
00000b0: 0000 0000 0000 0000 0001 1000 0279 ab96  .............y..
00000c0: 8754 3222 2333 3333 3334 4455 5666 6677  .T2"#33334DUVffw
00000d0: 7778 8899 9999 9999 9999 9999 8877 7777  wx...........www
00000e0: 6666 6666 6555 5556 5667 7677 7766 6666  ffffeUUVVgvwwfff
00000f0: 6666 6666 6666 9999 8998 9888 8988 9889  ffffff..........
0000100: 9999 9999 9999 9999 9999 8666 5433 2000  ...........fT3 .
0000110: 0000 0000 0000 0000 0000 0011 1111 1111  ................
0000120: 1111 1111 1111 1111 0111 1110 0111 1110  ................
0000130: 0000 0000 0000 0000 0001 1000 0379 aa86  .............y..
0000140: 8532 2233 3344 4444 4444 4565 5666 7777  .2"33DDDDDEeVfww
0000150: 7788 8999 9999 9999 9999 9988 7777 7777  w...........wwww
0000160: 7666 6666 5555 5556 6677 7777 7666 6666  vfffUUUVfwwwvfff
0000170: 6666 6666 6666 8888 8988 8898 8988 8888  ffffff..........
0000180: 999a 9999 9999 9999 9999 8656 5433 2000  ...........VT3 .
0000190: 0000 0000 0000 0000 0000 0011 1111 1111  ................
00001a0: 1111 1111 1111 1011 1111 1111 1111 0000  ................
00001b0: 0000 0000 0000 0000 0001 0000 1479 aa86  .............y..
00001c0: 6323 3333 4444 4444 4444 5566 6667 7777  c#33DDDDDDUffgww
00001d0: 8889 99aa aaaa a9aa 99a9 9877 7778 8877  ...........wwx.w
00001e0: 7777 6665 5555 5456 7777 7777 7666 6666  wwfeUUTVwwwwvfff
00001f0: 6666 6666 6666 8888 8888 8999 8888 8888  ffffff..........
0000200: 8999 9999 9999 9999 9999 9657 6433 3100  ...........Wd31.
0000210: 0000 0000 0000 0000 0000 0111 1111 1111  ................
0000220: 1111 1111 0111 1111 1110 1111 1100 0000  ................
0000230: 0000 0000 0000 0000 0001 0000 1589 aa74  ...............t
0000240: 4233 4444 4555 5555 5555 6666 6667 7889  B3DDEUUUUUfffgx.
0000250: 9999 aaaa aaaa 99aa 9a98 7777 7778 8877  ..........wwwx.w
0000260: 7777 6666 5555 5456 7777 7777 7667 7766  wwffUUTVwwwwvgwf
0000270: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000280: 8999 9999 9999 9999 9999 9647 6543 3200  ...........GeC2.
0000290: 0000 0000 0000 0000 0000 1101 1111 1111  ................
00002a0: 1111 0000 1110 0101 1110 0100 0000 0000  ................
00002b0: 0000 0000 0000 0000 0011 0000 2688 aa63  ............&..c
00002c0: 3344 4555 5666 6666 6666 6777 7778 889a  3DEUVfffffgwwx..
00002d0: aaaa aaaa aaa9 9999 9876 7777 7777 7777  .........vwwwwww
00002e0: 7777 7666 6555 5567 7777 7777 7666 6666  wwvfeUUgwwwwvfff
00002f0: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000300: 8899 9999 9999 9999 9999 9746 6544 3310  ...........FeD3.
0000310: 0000 0000 0000 0000 0000 1100 0011 1111  ................
0000320: 1000 0000 0000 0000 0100 0000 0000 0000  ................
0000330: 0000 0000 0000 0000 0010 0000 3689 a954  ............6..T
0000340: 4455 5666 6777 7776 6777 7778 8888 889a  DUVfgwwvgwwx....
0000350: aaaa aaaa aaa9 aa98 7656 6666 6666 7777  ........vVffffww
0000360: 7777 7667 7665 5677 7777 7766 6666 6666  wwvgveVwwwwfffff
0000370: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000380: 8789 9999 9999 9999 9999 9856 6544 4320  ...........VeDC
0000390: 0000 0000 0000 0000 0000 0000 0001 1111  ................
00003a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00003b0: 0000 0000 0000 0000 0000 0001 4789 9855  ............G..U
00003c0: 6666 6777 8899 9988 8888 8888 8999 999a  ffgw............
00003d0: aaaa aaaa aa9a 9865 5555 6666 6777 7777  .......eUUffgwww
00003e0: 7778 8887 7766 6677 7767 7666 6666 6666  wx..wffwwgvfffff
00003f0: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000400: 8878 9999 9999 9999 9999 9955 6554 4331  .x.........UeTC1
0000410: 0000 0000 0000 0000 0000 0000 0000 1111  ................
0000420: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000430: 0000 0000 0000 0000 0000 0002 5789 9767  ............W..g
0000440: 7777 8889 aaaa aaa9 9999 9999 9999 aa9a  ww..............
0000450: aaaa aaaa aa97 5444 4555 6677 7888 8888  ......TDEUfwx...
0000460: 8889 9988 7777 6766 7766 6666 6666 6666  ....wwgfwfffffff
0000470: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000480: 8887 8999 9999 9999 9999 9965 6654 4342  ...........efTCB
0000490: 0000 0000 0000 0000 0000 0000 0001 1110  ................
00004a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00004b0: 0000 0000 0000 0000 0000 0013 6789 8789  ............g...
00004c0: 9999 aaab bbbb baaa aaa9 9999 9aaa aaaa  ................
00004d0: aaaa aaaa 9754 3444 5555 6666 6677 7878  .....T4DUUfffwxx
00004e0: 8889 9988 7777 7766 6766 6666 6666 6666  ....wwwfgfffffff
00004f0: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000500: 8888 7899 9999 9999 9999 9975 7654 4443  ..x........uvTDC
0000510: 2000 0000 0000 0000 0000 0010 0000 1100   ...............
0000520: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000530: 0000 0000 0000 0000 0000 0014 6789 8899  ............g...
0000540: abbb bbcc ccbb bbbb bbaa aaaa aaaa aaaa  ................
0000550: aaaa aa98 6444 4555 5556 6666 6677 7777  ....dDEUUVfffwww
0000560: 7777 7777 7777 7766 6666 6666 6666 6666  wwwwwwwfffffffff
0000570: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000580: 8888 7789 9999 9999 9988 9985 7664 4444  ..w.........vdDD
0000590: 3100 0000 0000 0000 0000 0000 0000 0000  1...............
00005a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00005b0: 0000 0000 0000 0000 0000 0035 6889 8998  ...........5h...
00005c0: 9aaa aabb cccc cccb bbbb bbba aaaa 99aa  ................
00005d0: aaaa 9876 5445 6666 6667 7777 7777 7777  ...vTEfffgwwwwww
00005e0: 7777 7776 6776 6666 6666 6666 6666 6666  wwwvgvffffffffff
00005f0: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000600: 8888 8779 9999 9999 9998 8996 6765 4444  ...y........geDD
0000610: 4200 0000 0000 0000 0000 0000 0000 0000  B...............
0000620: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000630: 0000 0000 0000 0000 0000 0245 7898 8a99  ...........Ex...
0000640: 9aaa aaab bbcc cccc cbbb bbba aaaa a9aa  ................
0000650: aa99 8877 6545 6777 7777 7777 7777 7777  ...weEgwwwwwwwww
0000660: 7777 7766 6776 6666 6666 6666 6666 6666  wwwfgvffffffffff
0000670: 6666 6666 6666 8888 8888 8888 8888 8888  ffffff..........
0000680: 8887 8878 8999 9999 9999 8896 5765 5444  ...x........WeTD
0000690: 4320 0000 0000 0000 0000 0000 0000 0000  C ..............
00006a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00006b0: 0000 0000 0000 0000 0000 1356 7897 7abb  ...........Vx.z.
00006c0: bbbc cccc cbcc cccc bbbb bbbb aaaa abcc  ................
00006d0: ba98 8887 6545 6777 7777 7777 7777 7777  ....eEgwwwwwwwww
00006e0: 6666 6666 6776 6666 6666 6666 6666 6666  ffffgvffffffffff
00006f0: 6666 6666 6666 8888 8888 8888 8788 8888  ffffff..........
0000700: 8888 7887 7899 9999 9999 8898 5666 5444  ..x.x.......VfTD
0000710: 4431 0000 0000 0000 0000 0000 0000 0000  D1..............
0000720: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000730: 0000 0000 0000 0000 0000 2456 7887 7acc  ..........$Vx.z.
0000740: dddd ddcc cccc ccba aaaa aaa9 9988 8cdd  ................
0000750: cb99 9887 6644 6777 7777 7777 7777 7777  ....fDgwwwwwwwww
0000760: 7666 6666 6666 6666 6666 6666 6666 6666  vfffffffffffffff
0000770: 6666 6666 6656 8888 8888 8887 7887 7788  fffffV......x.w.
0000780: 8888 7777 7789 9999 9999 9889 5566 6544  ..www.......UfeD
0000790: 4443 1000 0000 0000 0000 0000 0000 0000  DC..............
00007a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00007b0: 0000 0000 0000 0000 0001 3456 7887 79bd  ..........4Vx.y.
00007c0: dddd cccc ccbb aa98 8888 8887 7777 7add  ............wwz.
00007d0: cba9 9887 6544 5777 7777 7667 7777 7777  ....eDWwwwvgwwww
00007e0: 7666 7666 6666 6666 6666 6666 6666 6666  vfvfffffffffffff
00007f0: 6666 6666 6655 8877 7877 8877 7877 7778  fffffU.wxw.wxwwx
0000800: 8787 7778 8778 9999 9999 9989 7576 6544  ..wx.x......uveD
0000810: 4444 2100 0000 0000 0000 0000 0000 0000  DD!.............
0000820: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000830: 0000 0000 0000 0000 0012 4567 8876 779b  ..........Eg.vw.
0000840: bccc cccb ba99 8777 7777 7777 7777 79cd  .......wwwwwwwy.
0000850: cca9 8777 6554 4677 7677 7667 7777 7777  ...weTFwvwvgwwww
0000860: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000870: 6666 6566 6555 7777 7777 7877 7777 7777  ffefeUwwwwxwwwww
0000880: 7877 7877 8777 8899 9989 9998 9666 6654  xwxw.w.......ffT
0000890: 4444 4210 0000 0000 0000 0000 0000 0000  DDB.............
00008a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00008b0: 0000 0000 0000 0000 0023 5567 8756 7788  .........#Ug.Vw.
00008c0: 99aa aa99 8877 7777 7777 7777 7777 77bd  .....wwwwwwwwww.
00008d0: dcb8 7766 6555 4567 7777 7777 7766 6666  ..wfeUEgwwwwwfff
00008e0: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
00008f0: 6555 5555 5555 7777 7777 7777 7777 7777  eUUUUUwwwwwwwwww
0000900: 7777 7777 7877 7788 8999 8899 9756 6655  wwwwxww......VfU
0000910: 4444 4421 0000 0000 0000 0000 0000 0000  DDD!............
0000920: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000930: 0000 0000 0000 0000 0134 5678 8666 7777  .........4Vx.fww
0000940: 7778 8877 7777 7777 7777 7777 7777 77ad  wx.wwwwwwwwwwww.
0000950: dcb9 7666 6555 4467 7777 7777 7766 6666  ..vfeUDgwwwwwfff
0000960: 6666 6666 6666 6666 6666 6665 6666 6555  fffffffffffeffeU
0000970: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000980: 7777 7777 7777 7778 8899 9989 9956 7665  wwwwwwwx.....Vve
0000990: 5544 4432 1000 0000 0000 0000 0000 0000  UDD2............
00009a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00009b0: 0000 0000 0000 0000 1344 5678 7667 7777  .........DVxvgww
00009c0: 7777 7777 7777 7777 7777 7777 7777 778c  wwwwwwwwwwwwwww.
00009d0: dcba 9867 6554 4456 6666 6666 6666 6666  ...geTDVffffffff
00009e0: 6666 6666 6666 6666 6666 6666 5665 5555  ffffffffffffVeUU
00009f0: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000a00: 7777 7777 7777 7766 7898 8889 8a85 6666  wwwwwwwfx.....ff
0000a10: 5554 4444 2100 0000 0000 0000 0000 0000  UTDD!...........
0000a20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000a30: 0000 0000 0000 0001 3455 5677 6677 7777  ........4UVwfwww
0000a40: 7777 7777 7777 7777 7777 7777 7777 777a  wwwwwwwwwwwwwwwz
0000a50: dcca a986 6655 4456 6666 6666 6666 6666  ....fUDVffffffff
0000a60: 6666 6666 6666 6666 6666 6666 6666 5555  ffffffffffffffUU
0000a70: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000a80: 7777 7777 7777 7776 6788 9999 89a5 5766  wwwwwwwvg.....Wf
0000a90: 6555 4444 4210 0000 0000 0000 0000 0000  eUDDB...........
0000aa0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000ab0: 0000 0000 0000 0013 3456 6676 6777 7777  ........4Vfvgwww
0000ac0: 7777 7777 7777 7777 7777 7777 7777 7768  wwwwwwwwwwwwwwwh
0000ad0: cdcb 9997 6665 5446 6666 6666 6666 6666  ....feTFffffffff
0000ae0: 6666 6666 6666 6666 6666 6666 6665 5555  fffffffffffffeUU
0000af0: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000b00: 7777 7777 7777 7777 6678 8889 9898 5666  wwwwwwwwfx....Vf
0000b10: 6555 5555 4431 0000 0000 0000 0000 0000  eUUUD1..........
0000b20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000b30: 0000 0000 0000 0124 4455 6775 6777 7777  .......$DUgugwww
0000b40: 7777 7777 7777 7777 7777 7777 7767 7767  wwwwwwwwwwwwwgwg
0000b50: bdcc 9888 6665 5445 6666 6666 6666 6666  ....feTEffffffff
0000b60: 6666 6666 6666 6666 6666 5556 5555 5555  ffffffffffUVUUUU
0000b70: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000b80: 7777 7777 7777 7677 6666 7888 8889 7566  wwwwwwvwffx...uf
0000b90: 6655 5544 5543 1100 0000 0000 0000 0000  fUUDUC..........
0000ba0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000bb0: 0000 0000 0000 1344 4556 7755 7776 7777  .......DEVwUwvww
0000bc0: 7777 7777 7777 6667 7666 6666 6666 6666  wwwwwwfgvfffffff
0000bd0: 9ddc b978 7765 5544 6666 6666 6666 6666  ...xweUDffffffff
0000be0: 6666 6666 6666 6655 5555 5555 5555 5555  fffffffUUUUUUUUU
0000bf0: 5555 5555 5555 7777 7777 7777 7777 7777  UUUUUUwwwwwwwwww
0000c00: 7777 7777 7677 7666 6766 6788 7889 9567  wwwwvwvfgfg.x..g
0000c10: 6665 5555 4554 3210 0000 0000 0000 0000  feUUET2.........
0000c20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000c30: 0000 0000 0001 3444 5566 7656 7777 7777  ......4DUfvVwwww
0000c40: 7677 7777 6777 6666 6666 6666 6666 6666  vwwwgwffffffffff
0000c50: 7cdc ca87 7765 5544 5666 6666 6666 6666  |...weUDVfffffff
0000c60: 6666 6666 6655 5555 5555 5555 5555 5555  fffffUUUUUUUUUUU
0000c70: 5555 5555 5555 6677 7767 7777 7777 7777  UUUUUUfwwgwwwwww
0000c80: 7777 7777 6666 6666 6667 6666 7888 9756  wwwwfffffgffx..V
0000c90: 7666 5555 5555 4431 1000 0000 0000 0000  vfUUUUD1........
0000ca0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000cb0: 0000 0000 0123 4445 5567 6566 6777 7766  .....#DEUgefgwwf
0000cc0: 6667 7666 7666 6666 6666 6666 6666 6666  fgvfvfffffffffff
0000cd0: 6adc bb97 7766 5544 5666 6666 6666 6666  j...wfUDVfffffff
0000ce0: 6655 5565 5556 5555 5555 5555 5555 5555  fUUeUVUUUUUUUUUU
0000cf0: 5555 5555 5555 6666 6666 6677 6666 7777  UUUUUUfffffwffww
0000d00: 7777 6666 6666 6666 6666 7766 6777 8a65  wwffffffffwfgw.e
0000d10: 6776 6555 5555 4543 2100 0000 0000 0000  gveUUUEC!.......
0000d20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000d30: 0000 0000 1344 4455 5666 5666 6667 6666  .....DDUVfVffgff
0000d40: 6667 7666 6666 6666 6666 6666 6666 6666  fgvfffffffffffff
0000d50: 68cd cba8 7666 5544 5566 6666 6666 6666  h...vfUDUfffffff
0000d60: 6655 5555 5555 5555 5555 5555 5555 5555  fUUUUUUUUUUUUUUU
0000d70: 5555 5555 5555 6666 6666 6676 6666 6666  UUUUUUfffffvffff
0000d80: 6666 6666 6666 6666 6666 6676 6667 7895  fffffffffffvfgx.
0000d90: 5776 6655 5555 5554 4321 0000 0000 0000  WvfUUUUTC!......
0000da0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000db0: 0000 0012 3444 4555 6764 5666 6666 6666  ....4DEUgdVfffff
0000dc0: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000dd0: 67bd cbb9 7666 5554 4566 6666 5655 5555  g...vfUTEfffVUUU
0000de0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0000df0: 5555 5555 5555 6666 6666 6666 6666 6666  UUUUUUffffffffff
0000e00: 6666 6666 6666 6666 6666 6666 6665 6688  fffffffffffffef.
0000e10: 4576 6665 5555 5555 5443 2100 0000 0000  EvfeUUUUTC!.....
0000e20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000e30: 0000 1234 4444 4556 6645 6676 6666 6666  ...4DDEVfEfvffff
0000e40: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000e50: 669d dcba 8766 6554 4555 5555 5555 5555  f....feTEUUUUUUU
0000e60: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0000e70: 5555 5555 4544 6666 6666 6666 6666 6666  UUUUEDffffffffff
0000e80: 6666 6666 6666 6666 6666 6666 6666 5558  ffffffffffffffUX
0000e90: 9456 7666 5555 5555 5554 4321 0000 0000  .VvfUUUUUTC!....
0000ea0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000eb0: 0012 3444 4445 5566 6456 7666 6666 6666  ..4DDEUfdVvfffff
0000ec0: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000ed0: 667b dcba 9766 6555 4456 5555 5555 5555  f{...feUDVUUUUUU
0000ee0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0000ef0: 5545 5445 4444 6666 6666 6666 6666 6666  UETEDDffffffffff
0000f00: 6666 6666 6666 6666 6666 6666 6666 6656  fffffffffffffffV
0000f10: 8856 7666 6655 5555 5555 5443 2110 0000  .VvffUUUUUTC!...
0000f20: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000f30: 1234 4444 4455 5565 4466 6666 6666 6666  .4DDDUUeDfffffff
0000f40: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000f50: 666a ddbb a866 6555 4456 5555 5555 5555  fj...feUDVUUUUUU
0000f60: 5555 5555 5555 5555 5555 5555 5555 5554  UUUUUUUUUUUUUUUT
0000f70: 5444 4444 4444 6666 6666 6666 6666 6666  TDDDDDffffffffff
0000f80: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000f90: 5884 6766 6665 5555 5555 5554 4432 1100  X.gffeUUUUUTD2..
0000fa0: 0000 0000 0000 0000 0000 0000 0000 1123  ...............#
0000fb0: 3444 4444 4455 5653 5666 6666 6666 6666  4DDDDUVSVfffffff
0000fc0: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0000fd0: 6668 cdcb a876 6655 4445 5555 5555 5555  fh...vfUDEUUUUUU
0000fe0: 5555 5555 5555 5555 5555 5555 5555 4555  UUUUUUUUUUUUUUEU
0000ff0: 4444 4444 4444 6666 6666 6666 6666 6666  DDDDDDffffffffff
0001000: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0001010: 6688 5676 6666 6555 5555 5555 5554 4321  f.VvffeUUUUUUTC!
0001020: 1110 0000 0000 0000 0000 0000 0112 3344  ..............3D
0001030: 4444 4455 5555 6544 6666 6666 6666 6666  DDDUUUeDffffffff
0001040: 6666 6666 6666 6666 6666 6666 6666 6566  ffffffffffffffef
0001050: 6666 bdcb a977 6655 4444 5555 5555 5555  ff...wfUDDUUUUUU
0001060: 5555 5555 5555 5555 5555 5555 5555 4555  UUUUUUUUUUUUUUEU
0001070: 5445 4444 4444 6665 6665 6666 6666 6666  TEDDDDfefeffffff
0001080: 6666 6666 6666 6666 6666 6666 6666 6666  ffffffffffffffff
0001090: 6668 9557 7666 6655 5555 5555 5555 5544  fh.WvffUUUUUUUUD
00010a0: 3322 2111 1100 0000 0001 1122 3344 4454  3"!........"3DDT
00010b0: 4444 4455 5556 5356 6666 6666 6666 6666  DDDUUVSVffffffff
00010c0: 6666 6666 6665 5566 6665 5555 5555 5555  fffffeUffeUUUUUU
00010d0: 5565 9ddc b987 6555 4444 5555 5555 5555  Ue....eUDDUUUUUU
00010e0: 5555 5555 5555 5555 5555 5555 5544 4444  UUUUUUUUUUUUUDDD
00010f0: 4444 4444 4444 5555 5655 5555 5565 5566  DDDDDDUUVUUUUeUf
0001100: 6666 6666 6666 6666 6666 6666 6666 6665  fffffffffffffffe
0001110: 6656 8965 6766 6666 6555 5555 5555 5555  fV.egfffeUUUUUUU
0001120: 5544 4433 3322 2222 2233 3444 4555 4444  UDD33""""34DEUDD
0001130: 4454 5555 5564 4556 6666 6666 6666 6666  DTUUUdEVffffffff
0001140: 6565 5555 6555 5555 5555 5555 5555 5555  eeUUeUUUUUUUUUUU
0001150: 5555 7bdc b987 7655 4434 5555 5555 5555  UU{...vUD4UUUUUU
0001160: 5555 5555 5555 5555 5555 4554 4444 4444  UUUUUUUUUUETDDDD
0001170: 4444 4444 4444 5555 5555 5555 5555 5555  DDDDDDUUUUUUUUUU
0001180: 5556 5656 5666 6666 6666 6666 6666 6655  UVVVVffffffffffU
0001190: 5566 5896 5676 6666 6666 5555 5555 5555  UfX.VvffffUUUUUU
00011a0: 5555 5555 5544 5555 5554 5555 5555 4555  UUUUUDUUUTUUUUEU
00011b0: 5555 5555 6544 5665 5656 6666 5666 5555  UUUUeDVeVVffVfUU
00011c0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
00011d0: 5555 69dc ca97 7654 4433 4555 5555 5555  UUi...vTD3EUUUUU
00011e0: 5555 4555 5555 5545 5544 4454 4444 4444  UUEUUUUEUDDTDDDD
00011f0: 4444 4444 4444 5555 5555 5555 5555 5555  DDDDDDUUUUUUUUUU
0001200: 5555 5555 5566 5666 6656 5556 5666 5655  UUUUUfVffVUVVfVU
0001210: 6666 5569 7456 6766 6666 6555 5555 5555  ffUitVgfffeUUUUU
0001220: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001230: 5555 5556 4355 6665 6655 5555 5555 5555  UUUVCUfefUUUUUUU
0001240: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001250: 5555 57cd cb97 7654 4433 3555 5555 5555  UUW...vTD35UUUUU
0001260: 5555 5554 4554 4444 4444 4444 4444 4444  UUUTETDDDDDDDDDD
0001270: 4444 4444 4444 5555 5555 5555 5555 5555  DDDDDDUUUUUUUUUU
0001280: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001290: 5665 6555 7754 6776 6666 6666 6555 5555  VeeUwTgvffffeUUU
00012a0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
00012b0: 5555 6554 4565 5655 5555 5555 5555 5555  UUeTEeVUUUUUUUUU
00012c0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
00012d0: 5555 56ad cba8 7653 3332 3454 5555 5545  UUV...vS324TUUUE
00012e0: 5555 5554 4554 4444 4444 4444 4444 4444  UUUTETDDDDDDDDDD
00012f0: 4444 4444 4444 5555 5555 5555 5555 5555  DDDDDDUUUUUUUUUU
0001300: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001310: 5555 5555 6776 5567 6666 6666 6666 6555  UUUUgvUgffffffeU
0001320: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001330: 5556 5444 5656 5555 5555 5555 5555 5555  UVTDVVUUUUUUUUUU
0001340: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001350: 5555 558d cb98 7642 1221 2354 5444 4445  UUU...vB.!#TTDDE
0001360: 5555 4544 4444 4444 4444 4444 4444 4444  UUEDDDDDDDDDDDDD
0001370: 4444 4444 4444 5455 5555 5555 5555 5555  DDDDDDTUUUUUUUUU
0001380: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001390: 5555 5555 5567 7545 7776 6666 6666 6666  UUUUUguEwvffffff
00013a0: 6666 5555 5555 5555 5555 5555 5555 6556  ffUUUUUUUUUUUUeV
00013b0: 6554 4455 5555 5555 5555 5555 5555 5555  eTDUUUUUUUUUUUUU
00013c0: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
00013d0: 5555 556b db97 6543 2110 1355 5444 4444  UUUk..eC!..UTDDD
00013e0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00013f0: 4444 4444 4444 4444 4444 4445 5555 5555  DDDDDDDDDDDEUUUU
0001400: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001410: 5555 5555 5555 6776 5667 7666 6666 6666  UUUUUUgvVgvfffff
0001420: 6666 6666 6666 6666 6666 6666 6656 6666  fffffffffffffVff
0001430: 5444 5555 5555 5555 5555 5555 5555 5555  TDUUUUUUUUUUUUUU
0001440: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001450: 5555 4559 dc96 6432 1000 1344 4444 4444  UUEY..d2...DDDDD
0001460: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001470: 4444 4444 4444 4444 4444 4444 4455 4554  DDDDDDDDDDDDDUET
0001480: 4445 5555 5555 4555 5555 5555 5555 5555  DEUUUUEUUUUUUUUU
0001490: 5555 5555 5555 4567 6555 6766 6666 6666  UUUUUUEgeUgfffff
00014a0: 6666 6666 6666 6666 6666 6666 6566 6554  ffffffffffffefeT
00014b0: 4455 5545 5555 5555 5555 5555 5555 5555  DUUEUUUUUUUUUUUU
00014c0: 5555 5555 5555 5555 5545 5555 5555 5554  UUUUUUUUUEUUUUUT
00014d0: 4445 4546 cc86 5421 1001 1244 4444 4444  DEEF..T!...DDDDD
00014e0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00014f0: 4444 3333 3333 4444 4444 4444 4444 4444  DD3333DDDDDDDDDD
0001500: 4444 4445 4454 4455 5555 5555 5555 5555  DDDEDTDUUUUUUUUU
0001510: 5555 5555 5555 5555 6666 5566 6766 6666  UUUUUUUUffUfgfff
0001520: 6666 6666 6666 6666 6666 6666 6665 5555  fffffffffffffeUU
0001530: 5555 5555 5555 5555 5555 5555 5555 5555  UUUUUUUUUUUUUUUU
0001540: 5555 5555 5555 5555 5545 5555 5555 5544  UUUUUUUUUEUUUUUD
0001550: 4454 5445 9b86 5312 3212 2234 4444 4444  DTTE..S.2."4DDDD
0001560: 4444 4444 4444 4444 4444 4444 4444 4443  DDDDDDDDDDDDDDDC
0001570: 3333 3333 3333 4444 4444 4444 4444 4444  333333DDDDDDDDDD
0001580: 4444 4544 4455 5454 4555 5555 5555 5555  DDEDDUTTEUUUUUUU
0001590: 5555 5555 5555 5555 5556 6655 6566 6666  UUUUUUUUUVfUefff
00015a0: 6666 6666 6666 6666 6666 6666 5655 5555  ffffffffffffVUUU
00015b0: 5455 5555 5555 5555 5555 5555 5555 5555  TUUUUUUUUUUUUUUU
00015c0: 5555 5554 5555 5555 5555 4444 4444 4444  UUUTUUUUUUDDDDDD
00015d0: 4545 4444 6888 7412 2223 3224 4444 4444  EEDDh.t."#2$DDDD
00015e0: 4444 4444 4444 4444 4444 4433 3333 3333  DDDDDDDDDDD33333
00015f0: 3333 3333 3333 4444 4444 4444 4444 4444  333333DDDDDDDDDD
0001600: 4444 4444 4444 4444 4444 5444 4445 5455  DDDDDDDDDDTDDETU
0001610: 5555 5555 5554 5554 5445 5556 6655 5666  UUUUUTUTTEUVfUVf
0001620: 6666 6666 6666 6666 6666 6555 5555 5544  ffffffffffeUUUUD
0001630: 4454 5544 5555 5445 5555 4554 5454 5455  DTUDUUTEUUETTTTU
0001640: 5555 4444 4444 4454 5454 4444 4444 4444  UUDDDDDTTTDDDDDD
0001650: 4444 4444 5569 9666 1135 4334 4444 4444  DDDDUi.f.5C4DDDD
0001660: 4444 4444 4444 4444 4344 4333 3333 3333  DDDDDDDDCDC33333
0001670: 3333 3333 3333 4444 4444 4444 4444 4444  333333DDDDDDDDDD
0001680: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001690: 4444 4444 4444 5554 4554 4444 5666 6556  DDDDDDUTETDDVfeV
00016a0: 6666 6666 6666 6666 6665 5555 5555 5444  fffffffffeUUUUTD
00016b0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00016c0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00016d0: 4444 4444 4469 b878 4344 4334 4444 4444  DDDDDi.xCDC4DDDD
00016e0: 4434 4444 4433 3333 3333 3333 3333 3333  D4DDD33333333333
00016f0: 3333 3333 3333 4444 4444 4444 4444 4444  333333DDDDDDDDDD
0001700: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001710: 4444 4444 4444 4454 5444 4444 4445 5556  DDDDDDDTTDDDDEUV
0001720: 6666 6666 6666 6666 5555 5544 4444 4444  ffffffffUUUDDDDD
0001730: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001740: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001750: 4444 4444 445a c725 6421 2124 4444 4444  DDDDDZ.%d!!$DDDD
0001760: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001770: 3333 3333 3333 4443 4444 4444 4444 4444  333333DCDDDDDDDD
0001780: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001790: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00017a0: 4455 5555 5555 5554 4444 4444 4454 4444  DUUUUUUTDDDDDTDD
00017b0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00017c0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00017d0: 4444 4444 4449 b968 8531 0013 4344 4433  DDDDDI.h.1..CDD3
00017e0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
00017f0: 3333 3333 3333 3333 3333 3434 4344 4444  333333333344CDDD
0001800: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001810: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001820: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001830: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001840: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001850: 4444 4444 4449 cb98 8741 0002 4333 4333  DDDDDI...A..C3C3
0001860: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001870: 3333 3333 3333 3333 3333 3333 3333 3334  3333333333333334
0001880: 4444 4344 4444 4444 4444 4444 4444 4444  DDCDDDDDDDDDDDDD
0001890: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00018a0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00018b0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00018c0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00018d0: 4444 4444 4447 cca7 3221 0002 4333 3333  DDDDDG..2!..C333
00018e0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
00018f0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001900: 3333 3333 3334 4334 4444 4444 4444 4444  333334C4DDDDDDDD
0001910: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001920: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001930: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001940: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001950: 4444 4434 4445 aa86 1001 1002 3333 3333  DDD4DE......3333
0001960: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001970: 3333 3333 3233 3333 3333 3333 3333 3333  3333233333333333
0001980: 3333 3333 3333 3333 3333 3344 4443 4444  33333333333DDCDD
0001990: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00019a0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00019b0: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
00019c0: 4444 4444 4444 4444 4444 4444 4444 4333  DDDDDDDDDDDDDDC3
00019d0: 4333 3333 4434 6744 2112 1002 3333 3333  C333D4gD!...3333
00019e0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
00019f0: 3333 3332 2222 3333 3333 3333 3333 3333  3332""3333333333
0001a00: 3333 3333 3333 3333 3333 3333 3333 3444  333333333333334D
0001a10: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001a20: 4444 4444 4444 4444 4443 4444 4444 4444  DDDDDDDDDCDDDDDD
0001a30: 4444 4444 4444 4444 4444 4444 4444 4444  DDDDDDDDDDDDDDDD
0001a40: 4444 4443 3333 3333 3444 4333 3333 3333  DDDC33334DC33333
0001a50: 3333 3333 3333 4765 4333 1012 3333 3333  333333GeC3..3333
0001a60: 3333 3333 3333 3333 3333 3333 3323 3222  3333333333333#2"
0001a70: 2222 2222 2222 3333 3333 3333 3333 3333  """"""3333333333
0001a80: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001a90: 3343 3434 4444 4433 4444 4433 4444 4433  3C44DDD3DDD3DDD3
0001aa0: 3444 4333 3444 4344 4433 3344 4444 4344  4DC34DCDD33DDDCD
0001ab0: 4434 4444 4444 4334 4444 4444 4343 3333  D4DDDDC4DDDDCC33
0001ac0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001ad0: 3333 3333 3333 4676 6421 0023 3333 3333  333333Fvd!.#3333
0001ae0: 3333 3333 3333 2223 3222 2222 2222 2222  333333"#2"""""""
0001af0: 2222 2222 2222 3333 3333 3333 3333 3333  """"""3333333333
0001b00: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001b10: 3333 3333 3334 4433 3343 4333 3333 3333  333334D33CC33333
0001b20: 3333 3333 3333 3333 3333 3334 4444 3334  333333333334DD34
0001b30: 4333 3333 3333 3333 3344 4333 3333 3333  C33333333DC33333
0001b40: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001b50: 3333 3333 3333 3466 3221 0143 3333 3333  3333334f2!.C3333
0001b60: 3332 2333 3333 2222 2222 2222 2222 2222  32#333""""""""""
0001b70: 2222 2222 2222 2332 3333 3333 3333 3333  """"""#233333333
0001b80: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001b90: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001ba0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001bb0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001bc0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001bd0: 3333 3333 3333 3356 5222 2233 3333 3322  3333333VR""3333"
0001be0: 2332 2222 2222 2222 2222 2222 2222 2222  #2""""""""""""""
0001bf0: 2222 2222 2222 2222 2222 3333 3333 3333  """"""""""333333
0001c00: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c10: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c20: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c30: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c40: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c50: 3333 3333 3333 3333 4433 4323 3222 3222  33333333D3C#2"2"
0001c60: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001c70: 2222 2222 2222 2222 2222 2223 3322 3333  """""""""""#3"33
0001c80: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001c90: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001ca0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001cb0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001cc0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001cd0: 3333 3333 3333 3322 2344 4332 2222 2222  3333333"#DC2""""
0001ce0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001cf0: 2222 2222 2222 2222 2222 2222 2222 2233  """""""""""""""3
0001d00: 3333 2333 3333 3333 3333 3333 3333 3333  33#3333333333333
0001d10: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001d20: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001d30: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001d40: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001d50: 3333 3333 3333 3322 2233 3332 2222 2222  3333333""332""""
0001d60: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001d70: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001d80: 2222 2222 2233 3333 3333 3333 3333 3332  """""33333333332
0001d90: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001da0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001db0: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001dc0: 3333 3333 3333 3333 3333 3333 3332 3223  333333333333322#
0001dd0: 3322 3333 3333 2222 2222 2222 2222 2222  3"3333""""""""""
0001de0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001df0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001e00: 2222 2222 2233 3333 2333 3233 3332 3322  """""333#323323"
0001e10: 3333 3333 3333 3333 3333 2333 3333 3233  3333333333#33323
0001e20: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001e30: 3333 3333 3333 3333 3333 3333 3333 3333  3333333333333333
0001e40: 3333 3333 3332 2233 3322 3333 3223 3222  333332"33"332#2"
0001e50: 2222 2333 3332 2222 2222 2222 2222 2222  ""#332""""""""""
0001e60: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001e70: 2222 2222 2212 2222 2222 2222 2222 2222  """"".""""""""""
0001e80: 2222 2222 3322 3322 2222 2222 2222 2222  """"3"3"""""""""
0001e90: 2232 3333 3333 3333 3333 2233 3322 2222  "233333333"33"""
0001ea0: 2333 3333 3333 3333 3333 3333 3323 3333  #333333333333#33
0001eb0: 3233 2223 2233 2233 3222 2232 2223 2233  23"#"3"32""2"#"3
0001ec0: 3222 3323 2222 2222 2222 2222 2222 2222  2"3#""""""""""""
0001ed0: 2222 2333 3322 2222 2222 2222 2222 2222  ""#33"""""""""""
0001ee0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001ef0: 2221 1121 1111 2222 2222 2222 2222 2222  "!.!..""""""""""
0001f00: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001f10: 2223 3332 3222 3322 2222 2223 3322 2222  "#322"3""""#3"""
0001f20: 2222 3332 2222 2222 2222 3322 2223 3322  ""32""""""3""#3"
0001f30: 2223 2222 2222 2222 2222 2222 2222 2222  "#""""""""""""""
0001f40: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001f50: 2222 2333 3222 2222 2222 2222 2222 2222  ""#32"""""""""""
0001f60: 2222 2222 2222 2222 2222 1222 2222 1221  """""""""".""".!
0001f70: 2211 1111 1111 2222 2222 2222 2222 2222  ".....""""""""""
0001f80: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001f90: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001fa0: 2222 2222 2222 2222 2222 2332 2222 2222  """"""""""#2""""
0001fb0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001fc0: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0001fd0: 2222 2333 3222 2222 2222 2222 2222 2222  ""#32"""""""""""
0001fe0: 2222 2222 2222 2222 2222 1222 2112 1111  """"""""""."!...
0001ff0: 1211 1111 1111 2222 2222 2222 2222 2222  ......""""""""""
0002000: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0002010: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0002020: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0002030: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0002040: 2222 2222 2222 2222 2222 2222 2222 2222  """"""""""""""""
0002050: 2222 2333 2222 2222 2222 2222 2222 2222  ""#3""""""""""""
0002060: 2222 2221 2221 1111 1111 1111 1111 1111  """!"!..........
0002070: 1111 1111 1111 0000                      ........

Серым цветом в конце файла выделены 2 байта выравнивания размера файла.

Примечание: по стандарту принято, что размер файла BMP должен быть всегда выровнен на 4 байта, т. е. количество байт в файле должно нацело делиться на 4.

#ifndef __BMP__
#define __BMP__
 
#pragma pack(1)
struct BITMAPFILEHEADER {
   unsigned short type;
   unsigned int fileSize;
   unsigned short reserved1;
   unsigned short reserved2;
   unsigned int offset;
};
#pragma pack()
 
#pragma pack(1)
struct BITMAPINFO {
   unsigned int headerSize;
   unsigned int width;
   unsigned int height;
   unsigned short planes;
   unsigned short bits;
   unsigned int compression;
   unsigned int imageSize;
   unsigned int xresolution;
   unsigned int yresolution;
   unsigned int ncolours;
   unsigned int importantcolours;
};
#pragma pack()
 
struct BITMAPCOLORTABLE {
   int magnitude [16];
};
 
#pragma pack(1)
struct BMPHeader {
   BITMAPFILEHEADER bmpfh;
   BITMAPINFO bmpinfo;
   BITMAPCOLORTABLE colortable;
};
#pragma pack()
 
// Магический префикс файла BMP ('BM').
#define BMP_TYPE        0x4D42
 
#endif //#ifndef __BMP__

Примечание: директивы #pragma pack(1) нужны для того, чтобы структура в памяти была упакованной, т. е. без пустот на байты выравнивания.

Так как структуры BITMAPFILEHEADER, BITMAPINFO, BITMAPCOLORTABLE идут в памяти друг за другом, то они для удобства программирования объединены вместе в одну структуру BMPHeader.

Код предназначен для вывода не сжатой картинки BMP размером 256x64 точки в формате 4 бита на точку (16 градаций яркости) на индикатор OLED WEX025664. Таким образом, картинка полностью вписывается в границы экрана индикатора. Для данных растра индикатора предназначен буфер ScreenData.

#define WIDTH 256
#define HEIGHT 64
#define PIXELS_PER_BYTE 2
#define BYTES_PER_LINE (WIDTH/PIXELS_PER_BYTE)
#define SCREEN_BUFFER_SIZE (BYTES_PER_LINE*HEIGHT)
 
extern section ("sdram0") uint8_t ScreenData[SCREEN_BUFFER_SIZE];
 
void drawBMP (const u8 *bmpdata)
{
   bmpdata += sizeof(BMPHeader);
   
   for (int y=HEIGHT-1;y>=0;y--)
   {
      memcpy(&ScreenData[y*BYTES_PER_LINE],
             bmpdata,
             BYTES_PER_LINE);
      bmpdata += BYTES_PER_LINE;
   }
}
 
void UpdateScreenDMA (void)
{
   *pSPI1_CTL = SPE|MSTR|CPOL|CPHA|TDBR_CORE;
   u8g_dev_ssd1322_prepare_screen(&u8gval, u8gval.dev);
   *pSPI1_CTL = SPE|MSTR|CPOL|CPHA|TDBR_DMA;
   *pDMA14_START_ADDR = ScreenData;
   *pDMA14_X_COUNT = SCREEN_BUFFER_SIZE;
   *pDMA14_X_MODIFY = 1;
   *pDMA14_IRQ_STATUS = *pDMA14_IRQ_STATUS & DMA_DONE;
   *pDMA14_CONFIG = FLOW_STOP|NDSIZE_0|WDSIZE_8|DMAEN;
}

Процедура drawBMP на входе принимает указатель bmpdata на сырые данные файла BMP вместе с заголовком. Поэтому для получения адреса данных растра к указателю просто добавляется размер структуры заголовка BMPheader (см. во врезке выше). Цикл построчно копирует данные растра в буфер индикатора, начиная от самой нижней строки картинки.

Процедура UpdateScreenDMA передает данные буфера в индикатор через SPI с использованием DMA (процессор Blackfin ADSP-BF538).

Вот так выглядит файл 256x64-greyscale-4bit.bmp на индикаторе OLED WEX025664:

OLED WEX025664 greyscale picture example

[Ссылки]

1. SSD1322: контроллер/драйвер для дисплеев OLED/PLED.
2. drawBitmap site:code.google.com.
3. u8glib: что такое Picture Loop.
4. Утилиты для конвертации двоичных файлов в текст HEX дампа.