1+ /* *************************************************************************************
2+ INCLUDE
3+ **************************************************************************************/
4+
5+ #include " lzssEncode.h"
6+
7+ #include < stdlib.h>
8+ #include < stdint.h>
9+
10+ #include < MKRNB.h>
11+
12+ /* *************************************************************************************
13+ DEFINE
14+ **************************************************************************************/
15+
16+ #define EI 11 /* typically 10..13 */
17+ #define EJ 4 /* typically 4..5 */
18+ #define P 1 /* If match length <= P then output one character */
19+ #define N (1 << EI) /* buffer size */
20+ #define F ((1 << EJ) + 1 ) /* lookahead buffer size */
21+
22+ #define LZSS_EOF (-1 )
23+
24+ #define FPUTC_BUF_SIZE (512 )
25+ #define FGETC_BUF_SIZE (512 )
26+
27+ /* *************************************************************************************
28+ GLOBAL VARIABLES
29+ **************************************************************************************/
30+
31+ extern NBFileUtils fileUtils;
32+ extern const char * UPDATE_FILE_NAME_LZSS;
33+
34+ int bit_buffer = 0 , bit_mask = 128 ;
35+ unsigned long textcount = 0 ;
36+ unsigned char buffer[N * 2 ];
37+
38+ static char write_buf[FPUTC_BUF_SIZE];
39+ static size_t write_buf_num_bytes = 0 ;
40+ static size_t bytes_written_fputc = 0 ;
41+
42+ bool append = false ;
43+ bool endOfFile = false ;
44+
45+ /* *************************************************************************************
46+ PUBLIC FUNCTIONS
47+ **************************************************************************************/
48+
49+ void lzss_flush ()
50+ {
51+ bytes_written_fputc += write_buf_num_bytes;
52+
53+ fileUtils.downloadFile (UPDATE_FILE_NAME_LZSS, write_buf, write_buf_num_bytes, append); // UPDATE.BIN.LZSS
54+ append = true ;
55+
56+ write_buf_num_bytes = 0 ;
57+ }
58+
59+ /* *************************************************************************************
60+ PRIVATE FUNCTIONS
61+ **************************************************************************************/
62+
63+ void lzss_fputc (int const c)
64+ {
65+ /* Buffer the compressed data into a buffer so
66+ * we can perform block writes and don't need to
67+ * write every byte singly on the modem
68+ */
69+ write_buf[write_buf_num_bytes] = static_cast <char >(c);
70+ write_buf_num_bytes++;
71+
72+ /* The write buffer is full of compressed
73+ * data, write it to the modem now.
74+ */
75+ if (write_buf_num_bytes == FPUTC_BUF_SIZE || endOfFile)
76+ lzss_flush ();
77+ }
78+
79+ /* *************************************************************************************
80+ LZSS FUNCTIONS
81+ **************************************************************************************/
82+
83+ void putbit1 (void )
84+ {
85+ bit_buffer |= bit_mask;
86+ if ((bit_mask >>= 1 ) == 0 ) {
87+ lzss_fputc (bit_buffer);
88+ bit_buffer = 0 ; bit_mask = 128 ;
89+ }
90+ }
91+
92+ void putbit0 (void )
93+ {
94+ if ((bit_mask >>= 1 ) == 0 ) {
95+ lzss_fputc (bit_buffer);
96+ bit_buffer = 0 ; bit_mask = 128 ;
97+ }
98+ }
99+
100+ void flush_bit_buffer (void )
101+ {
102+ if (bit_mask != 128 ) {
103+ lzss_fputc (bit_buffer);
104+ }
105+ }
106+
107+ void output1 (int c)
108+ {
109+ int mask;
110+
111+ putbit1 ();
112+ mask = 256 ;
113+ while (mask >>= 1 ) {
114+ if (c & mask) putbit1 ();
115+ else putbit0 ();
116+ }
117+ }
118+
119+ void output2 (int x, int y)
120+ {
121+ int mask;
122+
123+ putbit0 ();
124+ mask = N;
125+ while (mask >>= 1 ) {
126+ if (x & mask) putbit1 ();
127+ else putbit0 ();
128+ }
129+ mask = (1 << EJ);
130+ while (mask >>= 1 ) {
131+ if (y & mask) putbit1 ();
132+ else putbit0 ();
133+ }
134+ }
135+
136+ int lzss_encode (const char buf_in[], uint32_t size)
137+ {
138+ int i, j, f1, x, y, r, s, bufferend, c;
139+
140+ for (i = 0 ; i < N - F; i++) buffer[i] = ' ' ;
141+ for (i = N - F; i < N * 2 ; i++) {
142+ if (textcount >= size) {
143+ endOfFile = true ;
144+ break ;
145+ } else {
146+ buffer[i] = buf_in[textcount];
147+ textcount++;
148+ }
149+ }
150+ bufferend = i; r = N - F; s = 0 ;
151+ while (r < bufferend) {
152+ f1 = (F <= bufferend - r) ? F : bufferend - r;
153+ x = 0 ; y = 1 ; c = buffer[r];
154+ for (i = r - 1 ; i >= s; i--)
155+ if (buffer[i] == c) {
156+ for (j = 1 ; j < f1; j++)
157+ if (buffer[i + j] != buffer[r + j]) break ;
158+ if (j > y) {
159+ x = i; y = j;
160+ }
161+ }
162+ if (y <= P) { y = 1 ; output1 (c); }
163+ else output2 (x & (N - 1 ), y - 2 );
164+ r += y; s += y;
165+ if (r >= N * 2 - F) {
166+ for (i = 0 ; i < N; i++) buffer[i] = buffer[i + N];
167+ bufferend -= N; r -= N; s -= N;
168+ while (bufferend < N * 2 ) {
169+ if (textcount >= size) {
170+ endOfFile = true ;
171+ break ;
172+ } else {
173+ buffer[bufferend++] = buf_in[textcount];
174+ textcount++;
175+ }
176+ }
177+ }
178+ }
179+ flush_bit_buffer ();
180+
181+ return bytes_written_fputc;
182+ }
0 commit comments