• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
4  *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
9  *   Boston MA 02110-1301, USA; either version 2 of the License, or
10  *   (at your option) any later version; incorporated herein by reference.
11  *
12  * ----------------------------------------------------------------------- */
13 
14 /*
15  * rllpack.inc
16  *
17  * Very simple RLL compressor/decompressor, used to pack binary structures
18  * together.
19  *
20  * Format of leading byte
21  * 1-128	= x verbatim bytes follow
22  * 129-223	= (x-126) times subsequent byte
23  * 224-255	= (x-224)*256+(next byte) times the following byte
24  * 0		= end of data
25  *
26  * These structures are stored *in reverse order* in high memory.
27  * High memory pointers point to one byte beyond the end.
28  */
29 
30 #include <com32.h>
31 #include <stddef.h>
32 #include <string.h>
33 
rllpack(com32sys_t * regs)34 void rllpack(com32sys_t * regs)
35 {
36     uint8_t *i = (uint8_t *) (regs->esi.l);
37     uint8_t *o = (uint8_t *) (regs->edi.l);
38     size_t cnt = regs->ecx.l;
39     size_t run, vrun, tcnt;
40     uint8_t *hdr = NULL;
41     uint8_t c;
42 
43     vrun = (size_t)-1;
44     while (cnt) {
45 	c = *i;
46 
47 	run = 1;
48 	tcnt = (cnt > 8191) ? 8191 : cnt;
49 	while (run < tcnt && i[run] == c)
50 	    run++;
51 
52 	if (run < 3) {
53 	    if (vrun >= 128) {
54 		hdr = --o;
55 		vrun = 0;
56 	    }
57 	    *--o = c;
58 	    *hdr = ++vrun;
59 	    i++;
60 	    cnt--;
61 	} else {
62 	    if (run < 224 - 126) {
63 		*--o = run + 126;
64 	    } else {
65 		o -= 2;
66 		*(uint16_t *) o = run + (224 << 8);
67 	    }
68 	    *--o = c;
69 	    vrun = (size_t)-1;
70 	    i += run;
71 	    cnt -= run;
72 	}
73     }
74     *--o = 0;
75 
76     regs->esi.l = (size_t)i;
77     regs->edi.l = (size_t)o;
78 }
79 
rllunpack(com32sys_t * regs)80 void rllunpack(com32sys_t * regs)
81 {
82     uint8_t *i = (uint8_t *) regs->esi.l;
83     uint8_t *o = (uint8_t *) regs->edi.l;
84     uint8_t c;
85     size_t n;
86 
87     while ((c = *--i)) {
88 	if (c <= 128) {
89 	    while (c--)
90 		*o++ = *--i;
91 	} else {
92 	    if (c < 224)
93 		n = c - 126;
94 	    else
95 		n = ((c - 224) << 8) + *--i;
96 	    c = *--i;
97 	    while (n--)
98 		*o++ = c;
99 	}
100     }
101 
102     regs->esi.l = (size_t)i;
103     regs->ecx.l = (size_t)o - regs->edi.l;
104     regs->edi.l = (size_t)o;
105 }
106