GxEPD2_WiFi_Buffered.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. void drawBitmapFrom_HTTP_ToBuffer(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
  2. {
  3. WiFiClient client;
  4. bool connection_ok = false;
  5. bool valid = false; // valid format to be handled
  6. bool flip = true; // bitmap is stored bottom-to-top
  7. bool has_multicolors = (display.epd2.panel == GxEPD2::ACeP565) || (display.epd2.panel == GxEPD2::GDEY073D46)|| (display.epd2.panel == GxEPD2::GDEP073E01);
  8. uint32_t startTime = millis();
  9. if ((x >= display.width()) || (y >= display.height())) return;
  10. display.fillScreen(GxEPD_WHITE);
  11. Serial.print("connecting to "); Serial.println(host);
  12. if (!client.connect(host, httpPort))
  13. {
  14. Serial.println("connection failed");
  15. return;
  16. }
  17. Serial.print("requesting URL: ");
  18. Serial.println(String("http://") + host + path + filename);
  19. client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
  20. "Host: " + host + "\r\n" +
  21. "User-Agent: GxEPD2_WiFi_Example\r\n" +
  22. "Connection: close\r\n\r\n");
  23. Serial.println("request sent");
  24. while (client.connected())
  25. {
  26. String line = client.readStringUntil('\n');
  27. if (!connection_ok)
  28. {
  29. connection_ok = line.startsWith("HTTP/1.1 200 OK");
  30. if (connection_ok) Serial.println(line);
  31. }
  32. if (!connection_ok) Serial.println(line);
  33. if (line == "\r")
  34. {
  35. Serial.println("headers received");
  36. break;
  37. }
  38. }
  39. if (!connection_ok) return;
  40. // Parse BMP header
  41. if (read16(client) == 0x4D42) // BMP signature
  42. {
  43. uint32_t fileSize = read32(client);
  44. uint32_t creatorBytes = read32(client); (void)creatorBytes; //unused
  45. uint32_t imageOffset = read32(client); // Start of image data
  46. uint32_t headerSize = read32(client);
  47. uint32_t width = read32(client);
  48. int32_t height = (int32_t) read32(client);
  49. uint16_t planes = read16(client);
  50. uint16_t depth = read16(client); // bits per pixel
  51. uint32_t format = read32(client);
  52. uint32_t bytes_read = 7 * 4 + 3 * 2; // read so far
  53. if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
  54. {
  55. Serial.print("File size: "); Serial.println(fileSize);
  56. Serial.print("Image Offset: "); Serial.println(imageOffset);
  57. Serial.print("Header size: "); Serial.println(headerSize);
  58. Serial.print("Bit Depth: "); Serial.println(depth);
  59. Serial.print("Image size: ");
  60. Serial.print(width);
  61. Serial.print('x');
  62. Serial.println(abs(height));
  63. // BMP rows are padded (if needed) to 4-byte boundary
  64. uint32_t rowSize = (width * depth / 8 + 3) & ~3;
  65. if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
  66. if (height < 0)
  67. {
  68. height = -height;
  69. flip = false;
  70. }
  71. uint16_t w = width;
  72. uint16_t h = height;
  73. if ((x + w - 1) >= display.width()) w = display.width() - x;
  74. if ((y + h - 1) >= display.height()) h = display.height() - y;
  75. //if (w <= max_row_width) // handle with direct drawing
  76. {
  77. valid = true;
  78. uint8_t bitmask = 0xFF;
  79. uint8_t bitshift = 8 - depth;
  80. uint16_t red, green, blue;
  81. bool whitish = false;
  82. bool colored = false;
  83. if (depth == 1) with_color = false;
  84. if (depth <= 8)
  85. {
  86. if (depth < 8) bitmask >>= depth;
  87. bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
  88. for (uint16_t pn = 0; pn < (1 << depth); pn++)
  89. {
  90. blue = client.read();
  91. green = client.read();
  92. red = client.read();
  93. client.read();
  94. bytes_read += 4;
  95. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  96. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  97. if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
  98. mono_palette_buffer[pn / 8] |= whitish << pn % 8;
  99. if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
  100. color_palette_buffer[pn / 8] |= colored << pn % 8;
  101. //Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
  102. //Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
  103. rgb_palette_buffer[pn] = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  104. }
  105. }
  106. uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
  107. bytes_read += skip(client, rowPosition - bytes_read);
  108. for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
  109. {
  110. if (!connection_ok || !(client.connected() || client.available())) break;
  111. delay(1); // yield() to avoid WDT
  112. uint32_t in_remain = rowSize;
  113. uint32_t in_idx = 0;
  114. uint32_t in_bytes = 0;
  115. uint8_t in_byte = 0; // for depth <= 8
  116. uint8_t in_bits = 0; // for depth <= 8
  117. uint16_t color = GxEPD_WHITE;
  118. for (uint16_t col = 0; col < w; col++) // for each pixel
  119. {
  120. yield();
  121. if (!connection_ok || !(client.connected() || client.available())) break;
  122. // Time to read more pixel data?
  123. if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
  124. {
  125. uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
  126. uint32_t got = read8n(client, input_buffer, get);
  127. while ((got < get) && connection_ok)
  128. {
  129. //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
  130. uint32_t gotmore = read8n(client, input_buffer + got, get - got);
  131. got += gotmore;
  132. connection_ok = gotmore > 0;
  133. }
  134. in_bytes = got;
  135. in_remain -= got;
  136. bytes_read += got;
  137. in_idx = 0;
  138. }
  139. if (!connection_ok)
  140. {
  141. Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
  142. break;
  143. }
  144. switch (depth)
  145. {
  146. case 32:
  147. blue = input_buffer[in_idx++];
  148. green = input_buffer[in_idx++];
  149. red = input_buffer[in_idx++];
  150. in_idx++; // skip alpha
  151. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  152. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  153. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  154. break;
  155. case 24:
  156. blue = input_buffer[in_idx++];
  157. green = input_buffer[in_idx++];
  158. red = input_buffer[in_idx++];
  159. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  160. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  161. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  162. break;
  163. case 16:
  164. {
  165. uint8_t lsb = input_buffer[in_idx++];
  166. uint8_t msb = input_buffer[in_idx++];
  167. if (format == 0) // 555
  168. {
  169. blue = (lsb & 0x1F) << 3;
  170. green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
  171. red = (msb & 0x7C) << 1;
  172. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  173. }
  174. else // 565
  175. {
  176. blue = (lsb & 0x1F) << 3;
  177. green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
  178. red = (msb & 0xF8);
  179. color = (msb << 8) | lsb;
  180. }
  181. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  182. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  183. }
  184. break;
  185. case 1:
  186. case 2:
  187. case 4:
  188. case 8:
  189. {
  190. if (0 == in_bits)
  191. {
  192. in_byte = input_buffer[in_idx++];
  193. in_bits = 8;
  194. }
  195. uint16_t pn = (in_byte >> bitshift) & bitmask;
  196. whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
  197. colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
  198. in_byte <<= depth;
  199. in_bits -= depth;
  200. color = rgb_palette_buffer[pn];
  201. }
  202. break;
  203. }
  204. if (with_color && has_multicolors)
  205. {
  206. // keep color
  207. }
  208. else if (whitish)
  209. {
  210. color = GxEPD_WHITE;
  211. }
  212. else if (colored && with_color)
  213. {
  214. color = GxEPD_COLORED;
  215. }
  216. else
  217. {
  218. color = GxEPD_BLACK;
  219. }
  220. uint16_t yrow = y + (flip ? h - row - 1 : row);
  221. display.drawPixel(x + col, yrow, color);
  222. } // end pixel
  223. } // end line
  224. }
  225. Serial.print("bytes read "); Serial.println(bytes_read);
  226. }
  227. }
  228. Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
  229. client.stop();
  230. if (!valid)
  231. {
  232. Serial.println("bitmap format not handled.");
  233. }
  234. }
  235. void showBitmapFrom_HTTP_Buffered(const char* host, const char* path, const char* filename, int16_t x, int16_t y, bool with_color)
  236. {
  237. Serial.println(); Serial.print("downloading file \""); Serial.print(filename); Serial.println("\"");
  238. display.setFullWindow();
  239. display.firstPage();
  240. do
  241. {
  242. drawBitmapFrom_HTTP_ToBuffer(host, path, filename, x, y, with_color);
  243. }
  244. while (display.nextPage());
  245. }
  246. void drawBitmapFrom_HTTPS_ToBuffer(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
  247. {
  248. // Use WiFiClientSecure class to create TLS connection
  249. #if defined (ESP8266)
  250. BearSSL::WiFiClientSecure client;
  251. BearSSL::X509List cert(certificate ? certificate : certificate_rawcontent);
  252. #else
  253. WiFiClientSecure client;
  254. #endif
  255. bool connection_ok = false;
  256. bool valid = false; // valid format to be handled
  257. bool flip = true; // bitmap is stored bottom-to-top
  258. bool has_multicolors = (display.epd2.panel == GxEPD2::ACeP565) || (display.epd2.panel == GxEPD2::GDEY073D46)|| (display.epd2.panel == GxEPD2::GDEP073E01);
  259. uint32_t startTime = millis();
  260. if ((x >= display.width()) || (y >= display.height())) return;
  261. display.fillScreen(GxEPD_WHITE);
  262. Serial.print("connecting to "); Serial.println(host);
  263. #if defined (ESP8266)
  264. if (certificate) client.setTrustAnchors(&cert);
  265. else if (fingerprint) client.setFingerprint(fingerprint);
  266. else client.setInsecure();
  267. #elif defined (ESP32)
  268. if (certificate) client.setCACert(certificate);
  269. #endif
  270. if (!client.connect(host, httpsPort))
  271. {
  272. Serial.println("connection failed");
  273. return;
  274. }
  275. Serial.print("requesting URL: ");
  276. Serial.println(String("https://") + host + path + filename);
  277. client.print(String("GET ") + path + filename + " HTTP/1.1\r\n" +
  278. "Host: " + host + "\r\n" +
  279. "User-Agent: GxEPD2_WiFi_Example\r\n" +
  280. "Connection: close\r\n\r\n");
  281. Serial.println("request sent");
  282. while (client.connected())
  283. {
  284. String line = client.readStringUntil('\n');
  285. if (!connection_ok)
  286. {
  287. connection_ok = line.startsWith("HTTP/1.1 200 OK");
  288. if (connection_ok) Serial.println(line);
  289. }
  290. if (!connection_ok) Serial.println(line);
  291. if (line == "\r")
  292. {
  293. Serial.println("headers received");
  294. break;
  295. }
  296. }
  297. if (!connection_ok) return;
  298. // Parse BMP header
  299. uint16_t signature = 0;
  300. for (int16_t i = 0; i < 50; i++)
  301. {
  302. if (!client.available()) delay(100);
  303. else signature = read16(client);
  304. if (signature == 0x4D42) break;
  305. }
  306. if (signature == 0x4D42) // BMP signature
  307. {
  308. uint32_t fileSize = read32(client);
  309. uint32_t creatorBytes = read32(client); (void)creatorBytes; //unused
  310. uint32_t imageOffset = read32(client); // Start of image data
  311. uint32_t headerSize = read32(client);
  312. uint32_t width = read32(client);
  313. int32_t height = (int32_t) read32(client);
  314. uint16_t planes = read16(client);
  315. uint16_t depth = read16(client); // bits per pixel
  316. uint32_t format = read32(client);
  317. uint32_t bytes_read = 7 * 4 + 3 * 2; // read so far
  318. if ((planes == 1) && ((format == 0) || (format == 3))) // uncompressed is handled, 565 also
  319. {
  320. Serial.print("File size: "); Serial.println(fileSize);
  321. Serial.print("Image Offset: "); Serial.println(imageOffset);
  322. Serial.print("Header size: "); Serial.println(headerSize);
  323. Serial.print("Bit Depth: "); Serial.println(depth);
  324. Serial.print("Image size: ");
  325. Serial.print(width);
  326. Serial.print('x');
  327. Serial.println(abs(height));
  328. // BMP rows are padded (if needed) to 4-byte boundary
  329. uint32_t rowSize = (width * depth / 8 + 3) & ~3;
  330. if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
  331. if (height < 0)
  332. {
  333. height = -height;
  334. flip = false;
  335. }
  336. uint16_t w = width;
  337. uint16_t h = height;
  338. if ((x + w - 1) >= display.width()) w = display.width() - x;
  339. if ((y + h - 1) >= display.height()) h = display.height() - y;
  340. //if (w <= max_row_width) // handle with direct drawing
  341. {
  342. valid = true;
  343. uint8_t bitmask = 0xFF;
  344. uint8_t bitshift = 8 - depth;
  345. uint16_t red, green, blue;
  346. bool whitish = false;
  347. bool colored = false;
  348. if (depth == 1) with_color = false;
  349. if (depth <= 8)
  350. {
  351. if (depth < 8) bitmask >>= depth;
  352. //bytes_read += skip(client, 54 - bytes_read); //palette is always @ 54
  353. bytes_read += skip(client, imageOffset - (4 << depth) - bytes_read); // 54 for regular, diff for colorsimportant
  354. for (uint16_t pn = 0; pn < (1 << depth); pn++)
  355. {
  356. blue = client.read();
  357. green = client.read();
  358. red = client.read();
  359. client.read();
  360. bytes_read += 4;
  361. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  362. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  363. if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
  364. mono_palette_buffer[pn / 8] |= whitish << pn % 8;
  365. if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
  366. color_palette_buffer[pn / 8] |= colored << pn % 8;
  367. //Serial.print("0x00"); Serial.print(red, HEX); Serial.print(green, HEX); Serial.print(blue, HEX);
  368. //Serial.print(" : "); Serial.print(whitish); Serial.print(", "); Serial.println(colored);
  369. rgb_palette_buffer[pn] = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  370. }
  371. }
  372. uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
  373. //Serial.print("skip "); Serial.println(rowPosition - bytes_read);
  374. bytes_read += skip(client, rowPosition - bytes_read);
  375. for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) // for each line
  376. {
  377. if (!connection_ok || !(client.connected() || client.available())) break;
  378. delay(1); // yield() to avoid WDT
  379. uint32_t in_remain = rowSize;
  380. uint32_t in_idx = 0;
  381. uint32_t in_bytes = 0;
  382. uint8_t in_byte = 0; // for depth <= 8
  383. uint8_t in_bits = 0; // for depth <= 8
  384. uint16_t color = GxEPD_WHITE;
  385. for (uint16_t col = 0; col < w; col++) // for each pixel
  386. {
  387. yield();
  388. if (!connection_ok || !(client.connected() || client.available())) break;
  389. // Time to read more pixel data?
  390. if (in_idx >= in_bytes) // ok, exact match for 24bit also (size IS multiple of 3)
  391. {
  392. uint32_t get = in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain;
  393. uint32_t got = read8n(client, input_buffer, get);
  394. while ((got < get) && connection_ok)
  395. {
  396. //Serial.print("got "); Serial.print(got); Serial.print(" < "); Serial.print(get); Serial.print(" @ "); Serial.println(bytes_read);
  397. uint32_t gotmore = read8n(client, input_buffer + got, get - got);
  398. got += gotmore;
  399. connection_ok = gotmore > 0;
  400. }
  401. in_bytes = got;
  402. in_remain -= got;
  403. bytes_read += got;
  404. in_idx = 0;
  405. }
  406. if (!connection_ok)
  407. {
  408. Serial.print("Error: got no more after "); Serial.print(bytes_read); Serial.println(" bytes read!");
  409. break;
  410. }
  411. switch (depth)
  412. {
  413. case 32:
  414. blue = input_buffer[in_idx++];
  415. green = input_buffer[in_idx++];
  416. red = input_buffer[in_idx++];
  417. in_idx++; // skip alpha
  418. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  419. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  420. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  421. break;
  422. case 24:
  423. blue = input_buffer[in_idx++];
  424. green = input_buffer[in_idx++];
  425. red = input_buffer[in_idx++];
  426. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  427. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  428. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  429. break;
  430. case 16:
  431. {
  432. uint8_t lsb = input_buffer[in_idx++];
  433. uint8_t msb = input_buffer[in_idx++];
  434. if (format == 0) // 555
  435. {
  436. blue = (lsb & 0x1F) << 3;
  437. green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
  438. red = (msb & 0x7C) << 1;
  439. color = ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | ((blue & 0xF8) >> 3);
  440. }
  441. else // 565
  442. {
  443. blue = (lsb & 0x1F) << 3;
  444. green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
  445. red = (msb & 0xF8);
  446. color = (msb << 8) | lsb;
  447. }
  448. whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
  449. colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
  450. }
  451. break;
  452. case 1:
  453. case 2:
  454. case 4:
  455. case 8:
  456. {
  457. if (0 == in_bits)
  458. {
  459. in_byte = input_buffer[in_idx++];
  460. in_bits = 8;
  461. }
  462. uint16_t pn = (in_byte >> bitshift) & bitmask;
  463. whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
  464. colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
  465. in_byte <<= depth;
  466. in_bits -= depth;
  467. color = rgb_palette_buffer[pn];
  468. }
  469. break;
  470. }
  471. if (with_color && has_multicolors)
  472. {
  473. // keep color
  474. }
  475. else if (whitish)
  476. {
  477. color = GxEPD_WHITE;
  478. }
  479. else if (colored && with_color)
  480. {
  481. color = GxEPD_COLORED;
  482. }
  483. else
  484. {
  485. color = GxEPD_BLACK;
  486. }
  487. uint16_t yrow = y + (flip ? h - row - 1 : row);
  488. display.drawPixel(x + col, yrow, color);
  489. } // end pixel
  490. } // end line
  491. }
  492. Serial.print("bytes read "); Serial.println(bytes_read);
  493. }
  494. }
  495. Serial.print("loaded in "); Serial.print(millis() - startTime); Serial.println(" ms");
  496. client.stop();
  497. if (!valid)
  498. {
  499. Serial.println("bitmap format not handled.");
  500. }
  501. }
  502. void showBitmapFrom_HTTPS_Buffered(const char* host, const char* path, const char* filename, const char* fingerprint, int16_t x, int16_t y, bool with_color, const char* certificate)
  503. {
  504. Serial.println(); Serial.print("downloading file \""); Serial.print(filename); Serial.println("\"");
  505. display.setFullWindow();
  506. display.firstPage();
  507. do
  508. {
  509. drawBitmapFrom_HTTPS_ToBuffer(host, path, filename, fingerprint, x, y, with_color, certificate);
  510. }
  511. while (display.nextPage());
  512. }