File Coverage

cruncher.c
Criterion Covered Total %
statement 152 193 78.7
branch 61 72 84.7
condition n/a
subroutine n/a
pod n/a
total 213 265 80.3


line stmt bran cond sub pod time code
1             #include "cruncher.h"
2             #include
3              
4             //#define DEBUG
5              
6             #define max_offs 0x129f // 12bit offset limit. $129f
7             #define max_offs_short 0x054f // 10bit offset limit. $054f
8              
9             uint offsTab[4] = {5,2,2,3};
10             uint offsTabShort[4] = {4,2,2,2};
11              
12             byte *ibuf;
13             byte obuf[memSize];
14             uint ibufSize;
15             int get; //points to in[]
16             uint put; //points to out[]
17              
18             _bool copyFlag;
19             byte curByte;
20             byte curCnt;
21             uint plainLen;
22              
23             _bool errorFlag;
24              
25             #define cleanDecrLen 0x110
26             byte cleanDecrCode[cleanDecrLen] = {
27             0x0B, 0x08, 0x00, 0x00, 0x9E, 0x32, 0x30, 0x36, 0x31, 0x00, 0x00, 0x00, 0x78, 0xA9, 0x34, 0x85,
28             0x01, 0xA2, 0x3D, 0xBD, 0x1F, 0x08, 0x95, 0x06, 0xCA, 0x10, 0xF8, 0x4C, 0x08, 0x00, 0x00, 0x00,
29             0xA0, 0xFF, 0xB9, 0x00, 0x00, 0x99, 0x00, 0xFF, 0x88, 0xD0, 0xF7, 0xB1, 0x0B, 0x91, 0x0E, 0xC6,
30             0x0F, 0xC6, 0x0C, 0xA5, 0x0C, 0xC9, 0x08, 0xB0, 0xE7, 0xB9, 0x5D, 0x08, 0x99, 0x34, 0x03, 0xC8,
31             0xC0, 0xB4, 0x90, 0xF5, 0xA0, 0x02, 0xB1, 0x06, 0x99, 0x03, 0x00, 0x88, 0x10, 0xF8, 0x18, 0xA9,
32             0x03, 0x65, 0x06, 0x85, 0x06, 0x90, 0x02, 0xE6, 0x07, 0x4C, 0x34, 0x03, 0x20, 0xB8, 0x03, 0x08,
33             0xA9, 0x01, 0x20, 0xB8, 0x03, 0x90, 0x06, 0x20, 0xB8, 0x03, 0x2A, 0x10, 0xF5, 0x28, 0xB0, 0x18,
34             0x85, 0x02, 0xA0, 0x00, 0xB1, 0x06, 0x91, 0x04, 0xC8, 0xC4, 0x02, 0xD0, 0xF7, 0xA2, 0x02, 0x20,
35             0xD1, 0x03, 0xC8, 0xF0, 0xD7, 0x38, 0xB0, 0xD7, 0x69, 0x00, 0xF0, 0x4C, 0x85, 0x02, 0xC9, 0x03,
36             0xA9, 0x00, 0x85, 0x08, 0x85, 0x09, 0x2A, 0x20, 0xB8, 0x03, 0x2A, 0x20, 0xB8, 0x03, 0x2A, 0xAA,
37             0xBC, 0xE0, 0x03, 0x20, 0xB8, 0x03, 0x26, 0x08, 0x26, 0x09, 0x88, 0xD0, 0xF6, 0x8A, 0xCA, 0x29,
38             0x03, 0xF0, 0x08, 0xE6, 0x08, 0xD0, 0xE9, 0xE6, 0x09, 0xD0, 0xE5, 0x38, 0xA5, 0x04, 0xE5, 0x08,
39             0x85, 0x08, 0xA5, 0x05, 0xE5, 0x09, 0x85, 0x09, 0xB1, 0x08, 0x91, 0x04, 0xC8, 0xC4, 0x02, 0xD0,
40             0xF7, 0xA2, 0x00, 0x20, 0xD1, 0x03, 0x30, 0x84, 0xA9, 0x37, 0x85, 0x01, 0x58, 0x4C, 0x00, 0x00,
41             0x06, 0x03, 0xD0, 0x14, 0x48, 0x98, 0x48, 0xA0, 0x00, 0xB1, 0x06, 0xE6, 0x06, 0xD0, 0x02, 0xE6,
42             0x07, 0x38, 0x2A, 0x85, 0x03, 0x68, 0xA8, 0x68, 0x60, 0x18, 0x98, 0x75, 0x04, 0x95, 0x04, 0x90,
43             0x02, 0xF6, 0x05, 0xCA, 0xCA, 0x10, 0xF2, 0x60, 0x04, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x03 };
44              
45             #define normalDecrLen 0x11a
46             byte normalDecrCode[normalDecrLen] = {
47             0x0B, 0x08, 0x00, 0x00, 0x9E, 0x32, 0x30, 0x36, 0x31, 0x00, 0x00, 0x00, 0x78, 0xA9, 0x34, 0x85,
48             0x01, 0xA2, 0x3B, 0xBD, 0x1F, 0x08, 0x95, 0x06, 0xCA, 0x10, 0xF8, 0x4C, 0x08, 0x00, 0x00, 0x00,
49             0xA0, 0xFF, 0xB9, 0x00, 0x00, 0x99, 0x00, 0xFF, 0x88, 0xD0, 0xF7, 0xB1, 0x0B, 0x91, 0x0E, 0xC6,
50             0x0F, 0xC6, 0x0C, 0xA5, 0x0C, 0xC9, 0x08, 0xB0, 0xE7, 0xB9, 0x5B, 0x08, 0x99, 0x34, 0x03, 0xC8,
51             0xD0, 0xF7, 0xA0, 0x02, 0xB1, 0x06, 0x99, 0x03, 0x00, 0x88, 0x10, 0xF8, 0x18, 0xA9, 0x03, 0x65,
52             0x06, 0x85, 0x06, 0x90, 0x02, 0xE6, 0x07, 0x4C, 0x34, 0x03, 0x20, 0xB8, 0x03, 0x08, 0xA9, 0x01,
53             0x20, 0xB8, 0x03, 0x90, 0x06, 0x20, 0xB8, 0x03, 0x2A, 0x10, 0xF5, 0x28, 0xB0, 0x18, 0x85, 0x02,
54             0xA0, 0x00, 0xB1, 0x06, 0x91, 0x04, 0xC8, 0xC4, 0x02, 0xD0, 0xF7, 0xA2, 0x02, 0x20, 0xDD, 0x03,
55             0xC8, 0xF0, 0xD7, 0x38, 0xB0, 0xD7, 0x69, 0x00, 0xF0, 0x4C, 0x85, 0x02, 0xC9, 0x03, 0xA9, 0x00,
56             0x85, 0x08, 0x85, 0x09, 0x2A, 0x20, 0xB8, 0x03, 0x2A, 0x20, 0xB8, 0x03, 0x2A, 0xAA, 0xBC, 0xEC,
57             0x03, 0x20, 0xB8, 0x03, 0x26, 0x08, 0x26, 0x09, 0x88, 0xD0, 0xF6, 0x8A, 0xCA, 0x29, 0x03, 0xF0,
58             0x08, 0xE6, 0x08, 0xD0, 0xE9, 0xE6, 0x09, 0xD0, 0xE5, 0x38, 0xA5, 0x04, 0xE5, 0x08, 0x85, 0x08,
59             0xA5, 0x05, 0xE5, 0x09, 0x85, 0x09, 0xB1, 0x08, 0x91, 0x04, 0xC8, 0xC4, 0x02, 0xD0, 0xF7, 0xA2,
60             0x00, 0x20, 0xDD, 0x03, 0x30, 0x84, 0xA9, 0x37, 0x85, 0x01, 0x58, 0x4C, 0x00, 0x00, 0x06, 0x03,
61             0xD0, 0x20, 0x48, 0x98, 0x48, 0xA0, 0x00, 0xB1, 0x06, 0xE6, 0x06, 0xD0, 0x02, 0xE6, 0x07, 0x38,
62             0x2A, 0x85, 0x03, 0xA9, 0x05, 0xE6, 0x01, 0x8D, 0x20, 0xD0, 0x8C, 0x20, 0xD0, 0xC6, 0x01, 0x68,
63             0xA8, 0x68, 0x60, 0x18, 0x98, 0x75, 0x04, 0x95, 0x04, 0x90, 0x02, 0xF6, 0x05, 0xCA, 0xCA, 0x10,
64             0xF2, 0x60, 0x04, 0x02, 0x02, 0x02, 0x05, 0x02, 0x02, 0x03 };
65              
66             #define loadInitDecrLen 0x168
67             byte loadInitDecrCode[loadInitDecrLen] = {
68             0x0B, 0x08, 0x00, 0x00, 0x9E, 0x32, 0x30, 0x36, 0x34, 0x00, 0x00, 0x00, 0x4c, 0x3c, 0x08, 0xa5,
69             0xba, 0x20, 0xb1, 0xff, 0xa9, 0x6f, 0x20, 0x93, 0xff, 0xa9, 0x49, 0x20, 0xa8, 0xff, 0x20, 0xae,
70             0xff, 0xa5, 0xba, 0x20, 0xb1, 0xff, 0xa9, 0x6f, 0x20, 0x93, 0xff, 0xa2, 0x00, 0xbd, 0x43, 0x09,
71             0x20, 0xa8, 0xff, 0xe8, 0xe0, 0x26, 0x90, 0xf5, 0x20, 0xae, 0xff, 0xa9, 0x00, 0x8d, 0x11, 0xd0,
72             0x8d, 0x20, 0xd0, 0x78, 0xA9, 0x34, 0x85, 0x01, 0xA2, 0x3B, 0xBD, 0x56, 0x08, 0x95, 0x06, 0xCA,
73             0x10, 0xF8, 0x4C, 0x08, 0x00, 0x00, 0x00, 0xA0, 0xFF, 0xB9, 0x00, 0x00, 0x99, 0x00, 0xFF, 0x88,
74             0xD0, 0xF7, 0xB1, 0x0B, 0x91, 0x0E, 0xC6, 0x0F, 0xC6, 0x0C, 0xA5, 0x0C, 0xC9, 0x08, 0xB0, 0xE7,
75             0xB9, 0x92, 0x08, 0x99, 0x34, 0x03, 0xC8, 0xD0, 0xF7, 0xA0, 0x02, 0xB1, 0x06, 0x99, 0x03, 0x00,
76             0x88, 0x10, 0xF8, 0x18, 0xA9, 0x03, 0x65, 0x06, 0x85, 0x06, 0x90, 0x02, 0xE6, 0x07, 0x4C, 0x34,
77             0x03, 0x20, 0xB5, 0x03, 0x08, 0xA9, 0x01, 0x20, 0xB5, 0x03, 0x90, 0x06, 0x20, 0xB5, 0x03, 0x2A,
78             0x10, 0xF5, 0x28, 0xB0, 0x18, 0x85, 0x02, 0xA0, 0x00, 0xB1, 0x06, 0x91, 0x04, 0xC8, 0xC4, 0x02,
79             0xD0, 0xF7, 0xA2, 0x02, 0x20, 0xce, 0x03, 0xC8, 0xF0, 0xD7, 0x38, 0xB0, 0xD7, 0x69, 0x00, 0xF0,
80             0x4C, 0x85, 0x02, 0xC9, 0x03, 0xA9, 0x00, 0x85, 0x08, 0x85, 0x09, 0x2A, 0x20, 0xB5, 0x03, 0x2A,
81             0x20, 0xB5, 0x03, 0x2A, 0xAA, 0xBC, 0xdd, 0x03, 0x20, 0xB5, 0x03, 0x26, 0x08, 0x26, 0x09, 0x88,
82             0xD0, 0xF6, 0x8A, 0xCA, 0x29, 0x03, 0xF0, 0x08, 0xE6, 0x08, 0xD0, 0xE9, 0xE6, 0x09, 0xD0, 0xE5,
83             0x38, 0xA5, 0x04, 0xE5, 0x08, 0x85, 0x08, 0xA5, 0x05, 0xE5, 0x09, 0x85, 0x09, 0xB1, 0x08, 0x91,
84             0x04, 0xC8, 0xC4, 0x02, 0xD0, 0xF7, 0xA2, 0x00, 0x20, 0xce, 0x03, 0x30, 0x84, 0xe6, 0x01, 0x4C,
85             0x00, 0x00, 0x06, 0x03, 0xD0, 0x14, 0x48, 0x98, 0x48, 0xA0, 0x00, 0xB1, 0x06, 0xE6, 0x06, 0xD0,
86             0x02, 0xE6, 0x07, 0x38, 0x2A, 0x85, 0x03, 0x68, 0xA8, 0x68, 0x60, 0x18, 0x98, 0x75, 0x04, 0x95,
87             0x04, 0x90, 0x02, 0xF6, 0x05, 0xCA, 0xCA, 0x10, 0xF2, 0x60, 0x04, 0x02, 0x02, 0x02, 0x05, 0x02,
88             0x02, 0x03, 0x4d, 0x2d, 0x45, 0x0f, 0x02, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0x12,
89             0x0f, 0xa2, 0x09, 0xbd, 0x05, 0x02, 0x95, 0x00, 0xca, 0x10, 0xf8, 0xa9, 0x01, 0xaa, 0xd5, 0x00,
90             0xd0, 0xfc, 0xca, 0x10, 0xf9, 0x4c, 0x73, 0x03 };
91              
92 17           void init(File *aSource)
93             {
94 17           get = ibufSize - 1;
95 17           put = memSize - 1;
96 17           curByte = 0;
97 17           curCnt = 8;
98              
99 17           plainLen = 0;
100 17           }
101              
102 30478           static inline void out(byte b)
103             {
104             #ifdef DEBUG
105             printf("%i", b);
106             #endif
107              
108 30478           curByte >>= 1;
109 30478           curByte |= (b << 7);
110 30478 100         if((--curCnt) == 0) {
111             #ifdef DEBUG
112             printf("|");
113             #endif
114 3801           obuf[put] = curByte;
115 3801 50         if(put == 0) {
116 0           printf("Error (C-1): Packed file too large.\n");
117 0           put = memSize - 1; // Avoid more damage..
118 0           errorFlag = _true;
119             }
120 3801           --put;
121              
122 3801           curCnt = 8;
123 3801           curByte = 0;
124             }
125 30478           }
126              
127 2633           static inline void outLen(byte b)
128             {
129             #ifdef DEBUG
130             printf(";");
131             #endif
132              
133 2633 100         if(b < 0x80)
134 2523           out(0);
135              
136 8499 100         while(b > 1) {
137 5866           out(b & 1);
138 5866           out(1);
139 5866           b >>= 1;
140             }
141 2633           }
142              
143 25           static inline void outCopyFlag()
144             {
145 25 50         if(copyFlag == 1) {
146 25           out(1);
147 25           copyFlag = 0;
148             }
149 25           }
150              
151 64271           _bool scan(uint *theMatchLen, uint *theMatchOffset)
152             {
153             uint scn;
154 64271           uint matchLen = 0;
155 64271           uint matchOffset = 0;
156              
157 64271 100         if(get < 2) {
158 25           return _false;
159             }
160              
161 64246           scn = get - 1;
162              
163 64246           register byte first = ibuf[get];
164 64246           register byte second = ibuf[get - 1];
165              
166 294987979 100         while(((get - scn) <= max_offs) &&
    100          
167             (scn > 0)){
168 294923733 100         if((ibuf[scn] == first) &&
    100          
169 1149583           (ibuf[scn - 1] == second)) {
170 4365           uint len = 2;
171 4382 50         while((len < 255) &&
    100          
172 4376 100         (scn >= len) &&
173 4376           (ibuf[scn - len] == ibuf[get - len])) {
174 17           ++len;
175             };
176              
177 4365 100         if(len > matchLen) {
178 4220           matchLen = len;
179 4220           matchOffset = get - scn;
180             }
181             }
182 294923733           --scn;
183             };
184              
185 64246 100         if((matchLen > 2) ||
    100          
186 4207 100         ((matchLen == 2) && (matchOffset <= max_offs_short))) {
187 1307           *theMatchLen = matchLen;
188 1307           *theMatchOffset = matchOffset;
189 1307           return _true;
190             }
191             else {
192 62939           return _false;
193             }
194             }
195              
196 1307           void copy(uint matchLen, uint matchOffset)
197             {
198 1307           uint i = 0;
199              
200 1307           copyFlag = 1;
201              
202             #ifdef DEBUG
203             printf("C(%i, %i) ", matchLen, matchOffset);
204             #endif
205              
206             // Put copy offset.
207 4819 50         while(i < 4) {
208             uint b;
209 4819 100         if(matchLen == 2) {
210 4774           b = offsTabShort[i];
211             }
212             else {
213 45           b = offsTab[i];
214             }
215 17094 100         while(b > 0) {
216 12275           out(matchOffset & 1);
217 12275           matchOffset >>= 1;
218 12275           --b;
219             };
220              
221 4819 100         if(matchOffset == 0)
222 1307           break;
223              
224 3512           --matchOffset;
225 3512           ++i;
226             };
227              
228             // Put copy offset size.
229 1307           out(i & 1);
230 1307           out((i >> 1) & 1);
231              
232             // Put copy length.
233 1307           outLen(matchLen - 1);
234              
235 1307           get -= matchLen;
236 1307           }
237              
238 1324           void flush()
239             {
240             // Exit if there is nothing to flush.
241 1324 100         if(plainLen == 0) {
242 25           outCopyFlag();
243 25           return;
244             }
245              
246             #ifdef DEBUG
247             printf("P(%i) ", plainLen);
248             #endif
249              
250             // Put extra copy-bit if necessary.
251 1299 50         if((plainLen % 255) == 0) {
252 0           outCopyFlag();
253             }
254              
255             // Put plain data.
256 2608 100         while(plainLen > 0) {
257             uint i;
258 1309           uint len = ((plainLen - 1) % 255) + 1;
259              
260 1309 100         if(put < len) {
261 1           printf("Error (C-2): Packed file too large.\n");
262 1           put = memSize - 1; // Avoid more damage..
263 1           errorFlag = _true;
264             }
265              
266             // Copy the data.
267 64273 100         for(i = 0; i < len; ++i) {
268 62964           obuf[put - i] = ibuf[get + plainLen - i];
269             }
270              
271 1309           plainLen -= len;
272 1309           put -= len;
273              
274             // Put plain length.
275 1309           outLen(len);
276              
277             // Put plain-bit.
278 1309           out(0);
279             };
280              
281 1299           plainLen = 0;
282             }
283              
284              
285 17           _bool crunch(File *aSource, File *aTarget, uint startAdress, uint theDecrType, _bool isRelocated)
286             {
287             uint i;
288             uint theMatchLen, theMatchOffset;
289             uint packLen, decrLen;
290             byte *target;
291             _bool attachDecr;
292              
293 17           errorFlag = _false;
294              
295 17           switch(theDecrType) {
296             case noDecr:
297 16           attachDecr = _false;
298 16           decrLen = 0;
299 16           break;
300             case normalDecr:
301 1           attachDecr = _true;
302 1           decrLen = normalDecrLen;
303 1           break;
304             case cleanDecr:
305 0           attachDecr = _true;
306 0           decrLen = cleanDecrLen;
307 0           break;
308             case loadInitDecr:
309 0           attachDecr = _true;
310 0           decrLen = loadInitDecrLen;
311 0           break;
312             }
313              
314 17           ibufSize = aSource->size - 2;
315 17           ibuf = (byte *)malloc(ibufSize);
316 65610 100         for(i = 0; i < ibufSize; ++i) {
317 65593           ibuf[i] = aSource->data[i + 2];
318             }
319              
320 17           init(aSource);
321              
322 17           outLen(0xff); // Put end of file.
323 17           copyFlag = 1;
324              
325             #ifdef DEBUG
326             printf(".");
327             #endif
328              
329 64288 100         while(get >= 0) {
330 64271 100         if(scan(&theMatchLen, &theMatchOffset)) {
331 1307           flush();
332 1307           copy(theMatchLen, theMatchOffset);
333             }
334             else {
335 62964           ++plainLen;
336 62964           --get;
337             }
338             };
339 17           flush();
340              
341 17 100         if(errorFlag == _true) {
342 1           return _false;
343             }
344              
345             //Copy obuf into aTarget!!
346 16           packLen = memSize - put - 1;
347              
348             #ifdef DEBUG
349             printf("\nsize = %i\n", packLen);
350             #endif
351              
352 16           aTarget->size = packLen + decrLen + 5;
353 16           aTarget->data = (byte *)malloc(aTarget->size);
354 16 50         if(aTarget->data == NULL) {
355 0           printf("Error (C-3): Out of memory.\n");
356 0           return _false;
357             }
358              
359 16           target = aTarget->data + decrLen + 2;
360              
361 16           target[0] = (curByte | (1 << (curCnt - 1)));
362 16           target[1] = aSource->data[0];
363 16           target[2] = aSource->data[1];
364              
365 96 100         for(i = 0; i < packLen; ++i) {
366 80           target[i + 3] = obuf[put + i + 1];
367             }
368              
369 16           switch(theDecrType) {
370             case noDecr: {
371             uint packStart;
372 15 50         if(isRelocated)
373 0           packStart = startAdress;
374             else
375 15           packStart = 0xfffa;
376 15           packStart -= (packLen + 3);
377 15           aTarget->data[0] = packStart & 0xff;
378 15           aTarget->data[1] = packStart >> 8;
379 15           break;
380             }
381             case cleanDecr: {
382 0           uint packStart = 0xfffd - packLen;
383 0           uint trnsStart = 0x0814 + packLen;
384 0           cleanDecrCode[0x1e] = packStart & 0xff;
385 0           cleanDecrCode[0x1f] = packStart >> 8;
386 0           cleanDecrCode[0x23] = trnsStart & 0xff;
387 0           cleanDecrCode[0x24] = trnsStart >> 8;
388 0           cleanDecrCode[0xde] = startAdress & 0xff;
389 0           cleanDecrCode[0xdf] = startAdress >> 8;
390              
391 0           target = aTarget->data + 2;
392 0 0         for(i = 0; i < decrLen; ++i) {
393 0           target[i] = cleanDecrCode[i];
394             }
395              
396 0           aTarget->data[0] = 0x01;
397 0           aTarget->data[1] = 0x08;
398 0           break;
399             }
400             case normalDecr: {
401 1           uint packStart = 0xfffd - packLen;
402 1           uint trnsStart = 0x081e + packLen;
403 1           normalDecrCode[0x1e] = packStart & 0xff;
404 1           normalDecrCode[0x1f] = packStart >> 8;
405 1           normalDecrCode[0x23] = trnsStart & 0xff;
406 1           normalDecrCode[0x24] = trnsStart >> 8;
407 1           normalDecrCode[0xdc] = startAdress & 0xff;
408 1           normalDecrCode[0xdd] = startAdress >> 8;
409              
410 1           target = aTarget->data + 2;
411 283 100         for(i = 0; i < decrLen; ++i) {
412 282           target[i] = normalDecrCode[i];
413             }
414              
415 1           aTarget->data[0] = 0x01;
416 1           aTarget->data[1] = 0x08;
417 1           break;
418             }
419             case loadInitDecr: {
420 0           uint packStart = 0xfffd - packLen;
421 0           uint trnsStart = 0x086c + packLen;
422 0           loadInitDecrCode[0x55] = packStart & 0xff;
423 0           loadInitDecrCode[0x56] = packStart >> 8;
424 0           loadInitDecrCode[0x5a] = trnsStart & 0xff;
425 0           loadInitDecrCode[0x5b] = trnsStart >> 8;
426 0           loadInitDecrCode[0x110] = startAdress & 0xff;
427 0           loadInitDecrCode[0x111] = startAdress >> 8;
428              
429 0           target = aTarget->data + 2;
430 0 0         for(i = 0; i < decrLen; ++i) {
431 0           target[i] = loadInitDecrCode[i];
432             }
433              
434 0           aTarget->data[0] = 0x01;
435 0           aTarget->data[1] = 0x08;
436 0           break;
437             }
438             }
439              
440 16           free(ibuf);
441              
442 17           return _true;
443             }