source: bootcd/isolinux/syslinux-6.03/core/rllpack.c @ e16e8f2

Last change on this file since e16e8f2 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 2.3 KB
Line 
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
34void 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
80void 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}
Note: See TracBrowser for help on using the repository browser.