My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

heatshrink_decoder.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "../../inc/MarlinConfigPre.h"
  23. #if ENABLED(BINARY_FILE_TRANSFER)
  24. /**
  25. * libs/heatshrink/heatshrink_decoder.cpp
  26. */
  27. #include "heatshrink_decoder.h"
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #pragma GCC optimize ("O3")
  31. /* States for the polling state machine. */
  32. typedef enum {
  33. HSDS_TAG_BIT, /* tag bit */
  34. HSDS_YIELD_LITERAL, /* ready to yield literal byte */
  35. HSDS_BACKREF_INDEX_MSB, /* most significant byte of index */
  36. HSDS_BACKREF_INDEX_LSB, /* least significant byte of index */
  37. HSDS_BACKREF_COUNT_MSB, /* most significant byte of count */
  38. HSDS_BACKREF_COUNT_LSB, /* least significant byte of count */
  39. HSDS_YIELD_BACKREF /* ready to yield back-reference */
  40. } HSD_state;
  41. #if HEATSHRINK_DEBUGGING_LOGS
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <assert.h>
  45. #define LOG(...) fprintf(stderr, __VA_ARGS__)
  46. #define ASSERT(X) assert(X)
  47. static const char *state_names[] = {
  48. "tag_bit",
  49. "yield_literal",
  50. "backref_index_msb",
  51. "backref_index_lsb",
  52. "backref_count_msb",
  53. "backref_count_lsb",
  54. "yield_backref"
  55. };
  56. #else
  57. #define LOG(...) /* no-op */
  58. #define ASSERT(X) /* no-op */
  59. #endif
  60. typedef struct {
  61. uint8_t *buf; /* output buffer */
  62. size_t buf_size; /* buffer size */
  63. size_t *output_size; /* bytes pushed to buffer, so far */
  64. } output_info;
  65. #define NO_BITS ((uint16_t)-1)
  66. /* Forward references. */
  67. static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count);
  68. static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte);
  69. #if HEATSHRINK_DYNAMIC_ALLOC
  70. heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, uint8_t window_sz2, uint8_t lookahead_sz2) {
  71. if ((window_sz2 < HEATSHRINK_MIN_WINDOW_BITS) ||
  72. (window_sz2 > HEATSHRINK_MAX_WINDOW_BITS) ||
  73. (input_buffer_size == 0) ||
  74. (lookahead_sz2 < HEATSHRINK_MIN_LOOKAHEAD_BITS) ||
  75. (lookahead_sz2 >= window_sz2)) {
  76. return nullptr;
  77. }
  78. size_t buffers_sz = (1 << window_sz2) + input_buffer_size;
  79. size_t sz = sizeof(heatshrink_decoder) + buffers_sz;
  80. heatshrink_decoder *hsd = HEATSHRINK_MALLOC(sz);
  81. if (!hsd) return nullptr;
  82. hsd->input_buffer_size = input_buffer_size;
  83. hsd->window_sz2 = window_sz2;
  84. hsd->lookahead_sz2 = lookahead_sz2;
  85. heatshrink_decoder_reset(hsd);
  86. LOG("-- allocated decoder with buffer size of %zu (%zu + %u + %u)\n",
  87. sz, sizeof(heatshrink_decoder), (1 << window_sz2), input_buffer_size);
  88. return hsd;
  89. }
  90. void heatshrink_decoder_free(heatshrink_decoder *hsd) {
  91. size_t buffers_sz = (1 << hsd->window_sz2) + hsd->input_buffer_size;
  92. size_t sz = sizeof(heatshrink_decoder) + buffers_sz;
  93. HEATSHRINK_FREE(hsd, sz);
  94. (void)sz; /* may not be used by free */
  95. }
  96. #endif
  97. void heatshrink_decoder_reset(heatshrink_decoder *hsd) {
  98. size_t buf_sz = 1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd);
  99. size_t input_sz = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd);
  100. memset(hsd->buffers, 0, buf_sz + input_sz);
  101. hsd->state = HSDS_TAG_BIT;
  102. hsd->input_size = 0;
  103. hsd->input_index = 0;
  104. hsd->bit_index = 0x00;
  105. hsd->current_byte = 0x00;
  106. hsd->output_count = 0;
  107. hsd->output_index = 0;
  108. hsd->head_index = 0;
  109. }
  110. /* Copy SIZE bytes into the decoder's input buffer, if it will fit. */
  111. HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd,
  112. uint8_t *in_buf, size_t size, size_t *input_size) {
  113. if (!hsd || !in_buf || !input_size)
  114. return HSDR_SINK_ERROR_NULL;
  115. size_t rem = HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd) - hsd->input_size;
  116. if (rem == 0) {
  117. *input_size = 0;
  118. return HSDR_SINK_FULL;
  119. }
  120. size = rem < size ? rem : size;
  121. LOG("-- sinking %zd bytes\n", size);
  122. /* copy into input buffer (at head of buffers) */
  123. memcpy(&hsd->buffers[hsd->input_size], in_buf, size);
  124. hsd->input_size += size;
  125. *input_size = size;
  126. return HSDR_SINK_OK;
  127. }
  128. /*****************
  129. * Decompression *
  130. *****************/
  131. #define BACKREF_COUNT_BITS(HSD) (HEATSHRINK_DECODER_LOOKAHEAD_BITS(HSD))
  132. #define BACKREF_INDEX_BITS(HSD) (HEATSHRINK_DECODER_WINDOW_BITS(HSD))
  133. // States
  134. static HSD_state st_tag_bit(heatshrink_decoder *hsd);
  135. static HSD_state st_yield_literal(heatshrink_decoder *hsd, output_info *oi);
  136. static HSD_state st_backref_index_msb(heatshrink_decoder *hsd);
  137. static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd);
  138. static HSD_state st_backref_count_msb(heatshrink_decoder *hsd);
  139. static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd);
  140. static HSD_state st_yield_backref(heatshrink_decoder *hsd, output_info *oi);
  141. HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, uint8_t *out_buf, size_t out_buf_size, size_t *output_size) {
  142. if (!hsd || !out_buf || !output_size)
  143. return HSDR_POLL_ERROR_NULL;
  144. *output_size = 0;
  145. output_info oi;
  146. oi.buf = out_buf;
  147. oi.buf_size = out_buf_size;
  148. oi.output_size = output_size;
  149. while (1) {
  150. LOG("-- poll, state is %d (%s), input_size %d\n", hsd->state, state_names[hsd->state], hsd->input_size);
  151. uint8_t in_state = hsd->state;
  152. switch (in_state) {
  153. case HSDS_TAG_BIT:
  154. hsd->state = st_tag_bit(hsd);
  155. break;
  156. case HSDS_YIELD_LITERAL:
  157. hsd->state = st_yield_literal(hsd, &oi);
  158. break;
  159. case HSDS_BACKREF_INDEX_MSB:
  160. hsd->state = st_backref_index_msb(hsd);
  161. break;
  162. case HSDS_BACKREF_INDEX_LSB:
  163. hsd->state = st_backref_index_lsb(hsd);
  164. break;
  165. case HSDS_BACKREF_COUNT_MSB:
  166. hsd->state = st_backref_count_msb(hsd);
  167. break;
  168. case HSDS_BACKREF_COUNT_LSB:
  169. hsd->state = st_backref_count_lsb(hsd);
  170. break;
  171. case HSDS_YIELD_BACKREF:
  172. hsd->state = st_yield_backref(hsd, &oi);
  173. break;
  174. default:
  175. return HSDR_POLL_ERROR_UNKNOWN;
  176. }
  177. // If the current state cannot advance, check if input or output
  178. // buffer are exhausted.
  179. if (hsd->state == in_state)
  180. return (*output_size == out_buf_size) ? HSDR_POLL_MORE : HSDR_POLL_EMPTY;
  181. }
  182. }
  183. static HSD_state st_tag_bit(heatshrink_decoder *hsd) {
  184. uint32_t bits = get_bits(hsd, 1); // get tag bit
  185. if (bits == NO_BITS)
  186. return HSDS_TAG_BIT;
  187. else if (bits)
  188. return HSDS_YIELD_LITERAL;
  189. else if (HEATSHRINK_DECODER_WINDOW_BITS(hsd) > 8)
  190. return HSDS_BACKREF_INDEX_MSB;
  191. else {
  192. hsd->output_index = 0;
  193. return HSDS_BACKREF_INDEX_LSB;
  194. }
  195. }
  196. static HSD_state st_yield_literal(heatshrink_decoder *hsd, output_info *oi) {
  197. /* Emit a repeated section from the window buffer, and add it (again)
  198. * to the window buffer. (Note that the repetition can include
  199. * itself.)*/
  200. if (*oi->output_size < oi->buf_size) {
  201. uint16_t byte = get_bits(hsd, 8);
  202. if (byte == NO_BITS) { return HSDS_YIELD_LITERAL; } /* out of input */
  203. uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)];
  204. uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1;
  205. uint8_t c = byte & 0xFF;
  206. LOG("-- emitting literal byte 0x%02x ('%c')\n", c, isprint(c) ? c : '.');
  207. buf[hsd->head_index++ & mask] = c;
  208. push_byte(hsd, oi, c);
  209. return HSDS_TAG_BIT;
  210. }
  211. return HSDS_YIELD_LITERAL;
  212. }
  213. static HSD_state st_backref_index_msb(heatshrink_decoder *hsd) {
  214. uint8_t bit_ct = BACKREF_INDEX_BITS(hsd);
  215. ASSERT(bit_ct > 8);
  216. uint16_t bits = get_bits(hsd, bit_ct - 8);
  217. LOG("-- backref index (msb), got 0x%04x (+1)\n", bits);
  218. if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_MSB; }
  219. hsd->output_index = bits << 8;
  220. return HSDS_BACKREF_INDEX_LSB;
  221. }
  222. static HSD_state st_backref_index_lsb(heatshrink_decoder *hsd) {
  223. uint8_t bit_ct = BACKREF_INDEX_BITS(hsd);
  224. uint16_t bits = get_bits(hsd, bit_ct < 8 ? bit_ct : 8);
  225. LOG("-- backref index (lsb), got 0x%04x (+1)\n", bits);
  226. if (bits == NO_BITS) { return HSDS_BACKREF_INDEX_LSB; }
  227. hsd->output_index |= bits;
  228. hsd->output_index++;
  229. uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
  230. hsd->output_count = 0;
  231. return (br_bit_ct > 8) ? HSDS_BACKREF_COUNT_MSB : HSDS_BACKREF_COUNT_LSB;
  232. }
  233. static HSD_state st_backref_count_msb(heatshrink_decoder *hsd) {
  234. uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
  235. ASSERT(br_bit_ct > 8);
  236. uint16_t bits = get_bits(hsd, br_bit_ct - 8);
  237. LOG("-- backref count (msb), got 0x%04x (+1)\n", bits);
  238. if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_MSB; }
  239. hsd->output_count = bits << 8;
  240. return HSDS_BACKREF_COUNT_LSB;
  241. }
  242. static HSD_state st_backref_count_lsb(heatshrink_decoder *hsd) {
  243. uint8_t br_bit_ct = BACKREF_COUNT_BITS(hsd);
  244. uint16_t bits = get_bits(hsd, br_bit_ct < 8 ? br_bit_ct : 8);
  245. LOG("-- backref count (lsb), got 0x%04x (+1)\n", bits);
  246. if (bits == NO_BITS) { return HSDS_BACKREF_COUNT_LSB; }
  247. hsd->output_count |= bits;
  248. hsd->output_count++;
  249. return HSDS_YIELD_BACKREF;
  250. }
  251. static HSD_state st_yield_backref(heatshrink_decoder *hsd, output_info *oi) {
  252. size_t count = oi->buf_size - *oi->output_size;
  253. if (count > 0) {
  254. size_t i = 0;
  255. if (hsd->output_count < count) count = hsd->output_count;
  256. uint8_t *buf = &hsd->buffers[HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(hsd)];
  257. uint16_t mask = (1 << HEATSHRINK_DECODER_WINDOW_BITS(hsd)) - 1;
  258. uint16_t neg_offset = hsd->output_index;
  259. LOG("-- emitting %zu bytes from -%u bytes back\n", count, neg_offset);
  260. ASSERT(neg_offset <= mask + 1);
  261. ASSERT(count <= (size_t)(1 << BACKREF_COUNT_BITS(hsd)));
  262. for (i = 0; i < count; i++) {
  263. uint8_t c = buf[(hsd->head_index - neg_offset) & mask];
  264. push_byte(hsd, oi, c);
  265. buf[hsd->head_index & mask] = c;
  266. hsd->head_index++;
  267. LOG(" -- ++ 0x%02x\n", c);
  268. }
  269. hsd->output_count -= count;
  270. if (hsd->output_count == 0) { return HSDS_TAG_BIT; }
  271. }
  272. return HSDS_YIELD_BACKREF;
  273. }
  274. /* Get the next COUNT bits from the input buffer, saving incremental progress.
  275. * Returns NO_BITS on end of input, or if more than 15 bits are requested. */
  276. static uint16_t get_bits(heatshrink_decoder *hsd, uint8_t count) {
  277. uint16_t accumulator = 0;
  278. int i = 0;
  279. if (count > 15) return NO_BITS;
  280. LOG("-- popping %u bit(s)\n", count);
  281. /* If we aren't able to get COUNT bits, suspend immediately, because we
  282. * don't track how many bits of COUNT we've accumulated before suspend. */
  283. if (hsd->input_size == 0 && hsd->bit_index < (1 << (count - 1))) return NO_BITS;
  284. for (i = 0; i < count; i++) {
  285. if (hsd->bit_index == 0x00) {
  286. if (hsd->input_size == 0) {
  287. LOG(" -- out of bits, suspending w/ accumulator of %u (0x%02x)\n", accumulator, accumulator);
  288. return NO_BITS;
  289. }
  290. hsd->current_byte = hsd->buffers[hsd->input_index++];
  291. LOG(" -- pulled byte 0x%02x\n", hsd->current_byte);
  292. if (hsd->input_index == hsd->input_size) {
  293. hsd->input_index = 0; /* input is exhausted */
  294. hsd->input_size = 0;
  295. }
  296. hsd->bit_index = 0x80;
  297. }
  298. accumulator <<= 1;
  299. if (hsd->current_byte & hsd->bit_index) {
  300. accumulator |= 0x01;
  301. if (0) {
  302. LOG(" -- got 1, accumulator 0x%04x, bit_index 0x%02x\n",
  303. accumulator, hsd->bit_index);
  304. }
  305. }
  306. else if (0) {
  307. LOG(" -- got 0, accumulator 0x%04x, bit_index 0x%02x\n",
  308. accumulator, hsd->bit_index);
  309. }
  310. hsd->bit_index >>= 1;
  311. }
  312. if (count > 1) LOG(" -- accumulated %08x\n", accumulator);
  313. return accumulator;
  314. }
  315. HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd) {
  316. if (!hsd) return HSDR_FINISH_ERROR_NULL;
  317. switch (hsd->state) {
  318. case HSDS_TAG_BIT:
  319. return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
  320. /* If we want to finish with no input, but are in these states, it's
  321. * because the 0-bit padding to the last byte looks like a backref
  322. * marker bit followed by all 0s for index and count bits. */
  323. case HSDS_BACKREF_INDEX_LSB:
  324. case HSDS_BACKREF_INDEX_MSB:
  325. case HSDS_BACKREF_COUNT_LSB:
  326. case HSDS_BACKREF_COUNT_MSB:
  327. return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
  328. /* If the output stream is padded with 0xFFs (possibly due to being in
  329. * flash memory), also explicitly check the input size rather than
  330. * uselessly returning MORE but yielding 0 bytes when polling. */
  331. case HSDS_YIELD_LITERAL:
  332. return hsd->input_size == 0 ? HSDR_FINISH_DONE : HSDR_FINISH_MORE;
  333. default: return HSDR_FINISH_MORE;
  334. }
  335. }
  336. static void push_byte(heatshrink_decoder *hsd, output_info *oi, uint8_t byte) {
  337. LOG(" -- pushing byte: 0x%02x ('%c')\n", byte, isprint(byte) ? byte : '.');
  338. oi->buf[(*oi->output_size)++] = byte;
  339. (void)hsd;
  340. }
  341. #endif // BINARY_FILE_TRANSFER