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