Adding upstream version 4.00~pre55+dfsg.
[syslinux-debian/hramrach.git] / core / rllpack.c
blobbb9f046c40fe66828218d5b52cb6ec41e6b09080
1 /* ----------------------------------------------------------------------- *
3 * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
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.
12 * ----------------------------------------------------------------------- */
15 * rllpack.inc
17 * Very simple RLL compressor/decompressor, used to pack binary structures
18 * together.
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
26 * These structures are stored *in reverse order* in high memory.
27 * High memory pointers point to one byte beyond the end.
30 #include <com32.h>
31 #include <stddef.h>
32 #include <string.h>
34 void rllpack(com32sys_t * regs)
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;
43 vrun = (size_t)-1;
44 while (cnt) {
45 c = *i;
47 run = 1;
48 tcnt = (cnt > 8191) ? 8191 : cnt;
49 while (run < tcnt && i[run] == c)
50 run++;
52 if (run < 3) {
53 if (vrun >= 128) {
54 hdr = --o;
55 vrun = 0;
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);
68 *--o = c;
69 vrun = (size_t)-1;
70 i += run;
71 cnt -= run;
74 *--o = 0;
76 regs->esi.l = (size_t)i;
77 regs->edi.l = (size_t)o;
80 void rllunpack(com32sys_t * regs)
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;
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;
102 regs->esi.l = (size_t)i;
103 regs->ecx.l = (size_t)o - regs->edi.l;
104 regs->edi.l = (size_t)o;