|
5 | 5 | #include "lzss.h"
|
6 | 6 |
|
7 | 7 | #include <stdlib.h>
|
8 |
| -#include <stdint.h> |
9 |
| - |
10 |
| -/************************************************************************************** |
11 |
| - DEFINE |
12 |
| - **************************************************************************************/ |
13 |
| - |
14 |
| -#define EI 11 /* typically 10..13 */ |
15 |
| -#define EJ 4 /* typically 4..5 */ |
16 |
| -#define P 1 /* If match length <= P then output one character */ |
17 |
| -#define N (1 << EI) /* buffer size */ |
18 |
| -#define F ((1 << EJ) + 1) /* lookahead buffer size */ |
19 |
| - |
20 |
| -#define LZSS_EOF (-1) |
21 |
| - |
22 |
| -#define FPUTC_BUF_SIZE (64) |
23 |
| -#define FGETC_BUF_SIZE (64) |
24 | 8 |
|
25 | 9 | /**************************************************************************************
|
26 | 10 | GLOBAL VARIABLES
|
27 | 11 | **************************************************************************************/
|
28 | 12 |
|
29 |
| -static uint32_t LZSS_FILE_SIZE = 0; |
30 |
| -static FILE * update_file = 0; |
31 |
| -static FILE * target_file = 0; |
32 |
| - |
33 |
| -int bit_buffer = 0, bit_mask = 128; |
34 |
| -unsigned char buffer[N * 2]; |
| 13 | +static FILE * update_file = nullptr; |
| 14 | +static FILE * target_file = nullptr; |
35 | 15 |
|
36 |
| -static char write_buf[FPUTC_BUF_SIZE]; |
37 |
| -static size_t write_buf_num_bytes = 0; |
38 |
| -static size_t bytes_written_fputc = 0; |
39 |
| -static ArduinoPortentaOtaWatchdogResetFuncPointer wdog_feed_func = 0; |
| 16 | +static ArduinoPortentaOtaWatchdogResetFuncPointer wdog_feed_func = nullptr; |
| 17 | +static LZSSDecoder* decoder = nullptr; |
40 | 18 |
|
41 | 19 | /**************************************************************************************
|
42 | 20 | PUBLIC FUNCTIONS
|
43 | 21 | **************************************************************************************/
|
44 | 22 |
|
45 |
| -void lzss_init(FILE * update_file_ptr, FILE * target_file_ptr, uint32_t const lzss_file_size, ArduinoPortentaOtaWatchdogResetFuncPointer wdog_feed_func_ptr) |
46 |
| -{ |
47 |
| - update_file = update_file_ptr; |
48 |
| - target_file = target_file_ptr; |
49 |
| - LZSS_FILE_SIZE = lzss_file_size; |
50 |
| - wdog_feed_func = wdog_feed_func_ptr; |
51 |
| -} |
52 |
| - |
53 |
| -void lzss_flush() |
54 |
| -{ |
55 |
| - bytes_written_fputc += write_buf_num_bytes; |
56 |
| - |
57 |
| - if (wdog_feed_func) |
58 |
| - wdog_feed_func(); |
59 |
| - |
60 |
| - fwrite(write_buf, 1, write_buf_num_bytes, target_file); |
61 |
| - |
62 |
| - write_buf_num_bytes = 0; |
63 |
| -} |
64 |
| - |
65 |
| -/************************************************************************************** |
66 |
| - PRIVATE FUNCTIONS |
67 |
| - **************************************************************************************/ |
| 23 | +void lzss_init( |
| 24 | + FILE * update_file_ptr, |
| 25 | + FILE * target_file_ptr, |
| 26 | + uint32_t const lzss_file_size, |
| 27 | + ArduinoPortentaOtaWatchdogResetFuncPointer wdog_feed_func_ptr) { |
| 28 | + update_file = update_file_ptr; |
| 29 | + target_file = target_file_ptr; |
| 30 | + wdog_feed_func = wdog_feed_func_ptr; |
| 31 | + |
| 32 | + if(decoder != nullptr) { |
| 33 | + delete decoder; |
| 34 | + decoder = nullptr; |
| 35 | + } |
68 | 36 |
|
69 |
| -void lzss_fputc(int const c) |
70 |
| -{ |
71 |
| - /* Buffer the decompressed data into a buffer so |
72 |
| - * we can perform block writes and don't need to |
73 |
| - * write every byte singly on the flash (which |
74 |
| - * wouldn't be possible anyway). |
75 |
| - */ |
76 |
| - write_buf[write_buf_num_bytes] = static_cast<char>(c); |
77 |
| - write_buf_num_bytes++; |
78 |
| - |
79 |
| - /* The write buffer is full of decompressed |
80 |
| - * data, write it to the flash now. |
81 |
| - */ |
82 |
| - if (write_buf_num_bytes == FPUTC_BUF_SIZE) |
83 |
| - lzss_flush(); |
| 37 | + decoder = new LZSSDecoder( |
| 38 | + [target_file](const uint8_t c) { |
| 39 | + fwrite(&c, 1, 1, target_file); |
| 40 | + } |
| 41 | + ); |
84 | 42 | }
|
85 | 43 |
|
86 |
| -int lzss_fgetc() |
87 |
| -{ |
88 |
| - static uint8_t read_buf[FGETC_BUF_SIZE]; |
89 |
| - static size_t read_buf_pos = FGETC_BUF_SIZE; |
90 |
| - static size_t bytes_read_fgetc = 0; |
91 |
| - static size_t bytes_read_from_modem = 0; |
92 |
| - |
93 |
| - /* lzss_file_size is set within SSUBoot:main |
94 |
| - * and contains the size of the LZSS file. Once |
95 |
| - * all those bytes have been read its time to return |
96 |
| - * LZSS_EOF in order to signal that the end of |
97 |
| - * the file has been reached. |
98 |
| - */ |
99 |
| - if (bytes_read_fgetc == LZSS_FILE_SIZE) |
100 |
| - return LZSS_EOF; |
101 |
| - |
102 |
| - /* If there is no data left to be read from the read buffer |
103 |
| - * than read a new block and store it into the read buffer. |
104 |
| - */ |
105 |
| - if (read_buf_pos == FGETC_BUF_SIZE) |
106 |
| - { |
107 |
| - /* Read the next block from the flash memory. */ |
108 |
| - bytes_read_from_modem += fread(read_buf, 1, FGETC_BUF_SIZE, update_file); |
109 |
| - /* Reset the read buffer position. */ |
110 |
| - read_buf_pos = 0; |
111 |
| - } |
112 |
| - |
113 |
| - uint8_t const c = read_buf[read_buf_pos]; |
114 |
| - read_buf_pos++; |
115 |
| - bytes_read_fgetc++; |
116 |
| - |
117 |
| - return c; |
| 44 | +void lzss_flush() { |
| 45 | + fflush(target_file); |
118 | 46 | }
|
119 | 47 |
|
120 |
| -/************************************************************************************** |
121 |
| - LZSS FUNCTIONS |
122 |
| - **************************************************************************************/ |
123 |
| - |
124 |
| -int getbit(int n) /* get n bits */ |
125 |
| -{ |
126 |
| - int i, x; |
127 |
| - static int buf, mask = 0; |
128 |
| - |
129 |
| - x = 0; |
130 |
| - for (i = 0; i < n; i++) { |
131 |
| - if (mask == 0) { |
132 |
| - if ((buf = lzss_fgetc()) == LZSS_EOF) return LZSS_EOF; |
133 |
| - mask = 128; |
134 |
| - } |
135 |
| - x <<= 1; |
136 |
| - if (buf & mask) x++; |
137 |
| - mask >>= 1; |
| 48 | +void lzss_decode() { |
| 49 | + if(decoder == nullptr) { |
| 50 | + return; |
138 | 51 | }
|
139 |
| - return x; |
140 |
| -} |
| 52 | + const size_t buf_size = 64; |
| 53 | + uint8_t buffer[buf_size]; |
| 54 | + size_t res = 0; |
141 | 55 |
|
142 |
| -void lzss_decode(void) |
143 |
| -{ |
144 |
| - int i, j, k, r, c; |
145 |
| - |
146 |
| - for (i = 0; i < N - F; i++) buffer[i] = ' '; |
147 |
| - r = N - F; |
148 |
| - while ((c = getbit(1)) != LZSS_EOF) { |
149 |
| - if (c) { |
150 |
| - if ((c = getbit(8)) == LZSS_EOF) break; |
151 |
| - lzss_fputc(c); |
152 |
| - buffer[r++] = c; r &= (N - 1); |
153 |
| - } else { |
154 |
| - if ((i = getbit(EI)) == LZSS_EOF) break; |
155 |
| - if ((j = getbit(EJ)) == LZSS_EOF) break; |
156 |
| - for (k = 0; k <= j + 1; k++) { |
157 |
| - c = buffer[(i + k) & (N - 1)]; |
158 |
| - lzss_fputc(c); |
159 |
| - buffer[r++] = c; r &= (N - 1); |
160 |
| - } |
| 56 | + do { |
| 57 | + if(wdog_feed_func) { |
| 58 | + wdog_feed_func(); |
161 | 59 | }
|
162 |
| - } |
| 60 | + res = fread(buffer, sizeof(uint8_t), buf_size, update_file); |
| 61 | + decoder->decompress(buffer, res); |
| 62 | + } while(res == buf_size); |
163 | 63 | }
|
164 | 64 |
|
165 | 65 |
|
|
0 commit comments