Home | History | Annotate | Download | only in core
      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 
     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 
     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