123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- #ifdef STATIC
- #define PREBOOT
- #else
- #include <linux/decompress/bunzip2.h>
- #endif
- #include <linux/decompress/mm.h>
- #ifndef INT_MAX
- #define INT_MAX 0x7fffffff
- #endif
- #define MAX_GROUPS 6
- #define GROUP_SIZE 50
- #define MAX_HUFCODE_BITS 20
- #define MAX_SYMBOLS 258
- #define SYMBOL_RUNA 0
- #define SYMBOL_RUNB 1
- #define RETVAL_OK 0
- #define RETVAL_LAST_BLOCK (-1)
- #define RETVAL_NOT_BZIP_DATA (-2)
- #define RETVAL_UNEXPECTED_INPUT_EOF (-3)
- #define RETVAL_UNEXPECTED_OUTPUT_EOF (-4)
- #define RETVAL_DATA_ERROR (-5)
- #define RETVAL_OUT_OF_MEMORY (-6)
- #define RETVAL_OBSOLETE_INPUT (-7)
- #define BZIP2_IOBUF_SIZE 4096
- struct group_data {
-
- int limit[MAX_HUFCODE_BITS+1];
- int base[MAX_HUFCODE_BITS];
- int permute[MAX_SYMBOLS];
- int minLen, maxLen;
- };
- struct bunzip_data {
-
- int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
-
- long (*fill)(void*, unsigned long);
- long inbufCount, inbufPos ;
- unsigned char *inbuf ;
- unsigned int inbufBitCount, inbufBits;
-
- unsigned int crc32Table[256], headerCRC, totalCRC, writeCRC;
-
- unsigned int *dbuf, dbufSize;
-
- unsigned char selectors[32768];
- struct group_data groups[MAX_GROUPS];
- int io_error;
- int byteCount[256];
- unsigned char symToByte[256], mtfSymbol[256];
- };
- static unsigned int INIT get_bits(struct bunzip_data *bd, char bits_wanted)
- {
- unsigned int bits = 0;
-
- while (bd->inbufBitCount < bits_wanted) {
-
- if (bd->inbufPos == bd->inbufCount) {
- if (bd->io_error)
- return 0;
- bd->inbufCount = bd->fill(bd->inbuf, BZIP2_IOBUF_SIZE);
- if (bd->inbufCount <= 0) {
- bd->io_error = RETVAL_UNEXPECTED_INPUT_EOF;
- return 0;
- }
- bd->inbufPos = 0;
- }
-
- if (bd->inbufBitCount >= 24) {
- bits = bd->inbufBits&((1 << bd->inbufBitCount)-1);
- bits_wanted -= bd->inbufBitCount;
- bits <<= bits_wanted;
- bd->inbufBitCount = 0;
- }
-
- bd->inbufBits = (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
- bd->inbufBitCount += 8;
- }
-
- bd->inbufBitCount -= bits_wanted;
- bits |= (bd->inbufBits >> bd->inbufBitCount)&((1 << bits_wanted)-1);
- return bits;
- }
- static int INIT get_next_block(struct bunzip_data *bd)
- {
- struct group_data *hufGroup = NULL;
- int *base = NULL;
- int *limit = NULL;
- int dbufCount, nextSym, dbufSize, groupCount, selector,
- i, j, k, t, runPos, symCount, symTotal, nSelectors, *byteCount;
- unsigned char uc, *symToByte, *mtfSymbol, *selectors;
- unsigned int *dbuf, origPtr;
- dbuf = bd->dbuf;
- dbufSize = bd->dbufSize;
- selectors = bd->selectors;
- byteCount = bd->byteCount;
- symToByte = bd->symToByte;
- mtfSymbol = bd->mtfSymbol;
-
- i = get_bits(bd, 24);
- j = get_bits(bd, 24);
- bd->headerCRC = get_bits(bd, 32);
- if ((i == 0x177245) && (j == 0x385090))
- return RETVAL_LAST_BLOCK;
- if ((i != 0x314159) || (j != 0x265359))
- return RETVAL_NOT_BZIP_DATA;
-
- if (get_bits(bd, 1))
- return RETVAL_OBSOLETE_INPUT;
- origPtr = get_bits(bd, 24);
- if (origPtr >= dbufSize)
- return RETVAL_DATA_ERROR;
-
- t = get_bits(bd, 16);
- symTotal = 0;
- for (i = 0; i < 16; i++) {
- if (t&(1 << (15-i))) {
- k = get_bits(bd, 16);
- for (j = 0; j < 16; j++)
- if (k&(1 << (15-j)))
- symToByte[symTotal++] = (16*i)+j;
- }
- }
-
- groupCount = get_bits(bd, 3);
- if (groupCount < 2 || groupCount > MAX_GROUPS)
- return RETVAL_DATA_ERROR;
-
- nSelectors = get_bits(bd, 15);
- if (!nSelectors)
- return RETVAL_DATA_ERROR;
- for (i = 0; i < groupCount; i++)
- mtfSymbol[i] = i;
- for (i = 0; i < nSelectors; i++) {
-
- for (j = 0; get_bits(bd, 1); j++)
- if (j >= groupCount)
- return RETVAL_DATA_ERROR;
-
- uc = mtfSymbol[j];
- for (; j; j--)
- mtfSymbol[j] = mtfSymbol[j-1];
- mtfSymbol[0] = selectors[i] = uc;
- }
-
- symCount = symTotal+2;
- for (j = 0; j < groupCount; j++) {
- unsigned char length[MAX_SYMBOLS], temp[MAX_HUFCODE_BITS+1];
- int minLen, maxLen, pp;
-
- t = get_bits(bd, 5)-1;
- for (i = 0; i < symCount; i++) {
- for (;;) {
- if (((unsigned)t) > (MAX_HUFCODE_BITS-1))
- return RETVAL_DATA_ERROR;
-
- k = get_bits(bd, 2);
- if (k < 2) {
- bd->inbufBitCount++;
- break;
- }
-
- t += (((k+1)&2)-1);
- }
-
- length[i] = t+1;
- }
-
- minLen = maxLen = length[0];
- for (i = 1; i < symCount; i++) {
- if (length[i] > maxLen)
- maxLen = length[i];
- else if (length[i] < minLen)
- minLen = length[i];
- }
-
- hufGroup = bd->groups+j;
- hufGroup->minLen = minLen;
- hufGroup->maxLen = maxLen;
-
- base = hufGroup->base-1;
- limit = hufGroup->limit-1;
-
- pp = 0;
- for (i = minLen; i <= maxLen; i++) {
- temp[i] = limit[i] = 0;
- for (t = 0; t < symCount; t++)
- if (length[t] == i)
- hufGroup->permute[pp++] = t;
- }
-
- for (i = 0; i < symCount; i++)
- temp[length[i]]++;
-
- pp = t = 0;
- for (i = minLen; i < maxLen; i++) {
- pp += temp[i];
-
- limit[i] = (pp << (maxLen - i)) - 1;
- pp <<= 1;
- base[i+1] = pp-(t += temp[i]);
- }
- limit[maxLen+1] = INT_MAX;
- limit[maxLen] = pp+temp[maxLen]-1;
- base[minLen] = 0;
- }
-
-
- for (i = 0; i < 256; i++) {
- byteCount[i] = 0;
- mtfSymbol[i] = (unsigned char)i;
- }
-
- runPos = dbufCount = symCount = selector = 0;
- for (;;) {
-
- if (!(symCount--)) {
- symCount = GROUP_SIZE-1;
- if (selector >= nSelectors)
- return RETVAL_DATA_ERROR;
- hufGroup = bd->groups+selectors[selector++];
- base = hufGroup->base-1;
- limit = hufGroup->limit-1;
- }
-
-
- while (bd->inbufBitCount < hufGroup->maxLen) {
- if (bd->inbufPos == bd->inbufCount) {
- j = get_bits(bd, hufGroup->maxLen);
- goto got_huff_bits;
- }
- bd->inbufBits =
- (bd->inbufBits << 8)|bd->inbuf[bd->inbufPos++];
- bd->inbufBitCount += 8;
- };
- bd->inbufBitCount -= hufGroup->maxLen;
- j = (bd->inbufBits >> bd->inbufBitCount)&
- ((1 << hufGroup->maxLen)-1);
- got_huff_bits:
-
- i = hufGroup->minLen;
- while (j > limit[i])
- ++i;
- bd->inbufBitCount += (hufGroup->maxLen - i);
-
- if ((i > hufGroup->maxLen)
- || (((unsigned)(j = (j>>(hufGroup->maxLen-i))-base[i]))
- >= MAX_SYMBOLS))
- return RETVAL_DATA_ERROR;
- nextSym = hufGroup->permute[j];
-
- if (((unsigned)nextSym) <= SYMBOL_RUNB) {
-
- if (!runPos) {
- runPos = 1;
- t = 0;
- }
-
- t += (runPos << nextSym);
-
- runPos <<= 1;
- continue;
- }
-
- if (runPos) {
- runPos = 0;
- if (dbufCount+t >= dbufSize)
- return RETVAL_DATA_ERROR;
- uc = symToByte[mtfSymbol[0]];
- byteCount[uc] += t;
- while (t--)
- dbuf[dbufCount++] = uc;
- }
-
- if (nextSym > symTotal)
- break;
-
- if (dbufCount >= dbufSize)
- return RETVAL_DATA_ERROR;
- i = nextSym - 1;
- uc = mtfSymbol[i];
-
- do {
- mtfSymbol[i] = mtfSymbol[i-1];
- } while (--i);
- mtfSymbol[0] = uc;
- uc = symToByte[uc];
-
- byteCount[uc]++;
- dbuf[dbufCount++] = (unsigned int)uc;
- }
-
-
- j = 0;
- for (i = 0; i < 256; i++) {
- k = j+byteCount[i];
- byteCount[i] = j;
- j = k;
- }
-
- for (i = 0; i < dbufCount; i++) {
- uc = (unsigned char)(dbuf[i] & 0xff);
- dbuf[byteCount[uc]] |= (i << 8);
- byteCount[uc]++;
- }
-
- if (dbufCount) {
- if (origPtr >= dbufCount)
- return RETVAL_DATA_ERROR;
- bd->writePos = dbuf[origPtr];
- bd->writeCurrent = (unsigned char)(bd->writePos&0xff);
- bd->writePos >>= 8;
- bd->writeRunCountdown = 5;
- }
- bd->writeCount = dbufCount;
- return RETVAL_OK;
- }
- static int INIT read_bunzip(struct bunzip_data *bd, char *outbuf, int len)
- {
- const unsigned int *dbuf;
- int pos, xcurrent, previous, gotcount;
-
- if (bd->writeCount < 0)
- return bd->writeCount;
- gotcount = 0;
- dbuf = bd->dbuf;
- pos = bd->writePos;
- xcurrent = bd->writeCurrent;
-
- if (bd->writeCopies) {
-
- --bd->writeCopies;
-
- for (;;) {
-
- if (gotcount >= len) {
- bd->writePos = pos;
- bd->writeCurrent = xcurrent;
- bd->writeCopies++;
- return len;
- }
-
- outbuf[gotcount++] = xcurrent;
- bd->writeCRC = (((bd->writeCRC) << 8)
- ^bd->crc32Table[((bd->writeCRC) >> 24)
- ^xcurrent]);
-
- if (bd->writeCopies) {
- --bd->writeCopies;
- continue;
- }
- decode_next_byte:
- if (!bd->writeCount--)
- break;
-
- previous = xcurrent;
- pos = dbuf[pos];
- xcurrent = pos&0xff;
- pos >>= 8;
-
- if (--bd->writeRunCountdown) {
- if (xcurrent != previous)
- bd->writeRunCountdown = 4;
- } else {
-
- bd->writeCopies = xcurrent;
- xcurrent = previous;
- bd->writeRunCountdown = 5;
-
- if (!bd->writeCopies)
- goto decode_next_byte;
-
- --bd->writeCopies;
- }
- }
-
- bd->writeCRC = ~bd->writeCRC;
- bd->totalCRC = ((bd->totalCRC << 1) |
- (bd->totalCRC >> 31)) ^ bd->writeCRC;
-
- if (bd->writeCRC != bd->headerCRC) {
- bd->totalCRC = bd->headerCRC+1;
- return RETVAL_LAST_BLOCK;
- }
- }
-
-
- previous = get_next_block(bd);
- if (previous) {
- bd->writeCount = previous;
- return (previous != RETVAL_LAST_BLOCK) ? previous : gotcount;
- }
- bd->writeCRC = 0xffffffffUL;
- pos = bd->writePos;
- xcurrent = bd->writeCurrent;
- goto decode_next_byte;
- }
- static long INIT nofill(void *buf, unsigned long len)
- {
- return -1;
- }
- static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, long len,
- long (*fill)(void*, unsigned long))
- {
- struct bunzip_data *bd;
- unsigned int i, j, c;
- const unsigned int BZh0 =
- (((unsigned int)'B') << 24)+(((unsigned int)'Z') << 16)
- +(((unsigned int)'h') << 8)+(unsigned int)'0';
-
- i = sizeof(struct bunzip_data);
-
- bd = *bdp = malloc(i);
- if (!bd)
- return RETVAL_OUT_OF_MEMORY;
- memset(bd, 0, sizeof(struct bunzip_data));
-
- bd->inbuf = inbuf;
- bd->inbufCount = len;
- if (fill != NULL)
- bd->fill = fill;
- else
- bd->fill = nofill;
-
- for (i = 0; i < 256; i++) {
- c = i << 24;
- for (j = 8; j; j--)
- c = c&0x80000000 ? (c << 1)^0x04c11db7 : (c << 1);
- bd->crc32Table[i] = c;
- }
-
- i = get_bits(bd, 32);
- if (((unsigned int)(i-BZh0-1)) >= 9)
- return RETVAL_NOT_BZIP_DATA;
-
- bd->dbufSize = 100000*(i-BZh0);
- bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
- if (!bd->dbuf)
- return RETVAL_OUT_OF_MEMORY;
- return RETVAL_OK;
- }
- STATIC int INIT bunzip2(unsigned char *buf, long len,
- long (*fill)(void*, unsigned long),
- long (*flush)(void*, unsigned long),
- unsigned char *outbuf,
- long *pos,
- void(*error)(char *x))
- {
- struct bunzip_data *bd;
- int i = -1;
- unsigned char *inbuf;
- if (flush)
- outbuf = malloc(BZIP2_IOBUF_SIZE);
- if (!outbuf) {
- error("Could not allocate output buffer");
- return RETVAL_OUT_OF_MEMORY;
- }
- if (buf)
- inbuf = buf;
- else
- inbuf = malloc(BZIP2_IOBUF_SIZE);
- if (!inbuf) {
- error("Could not allocate input buffer");
- i = RETVAL_OUT_OF_MEMORY;
- goto exit_0;
- }
- i = start_bunzip(&bd, inbuf, len, fill);
- if (!i) {
- for (;;) {
- i = read_bunzip(bd, outbuf, BZIP2_IOBUF_SIZE);
- if (i <= 0)
- break;
- if (!flush)
- outbuf += i;
- else
- if (i != flush(outbuf, i)) {
- i = RETVAL_UNEXPECTED_OUTPUT_EOF;
- break;
- }
- }
- }
-
- if (i == RETVAL_LAST_BLOCK) {
- if (bd->headerCRC != bd->totalCRC)
- error("Data integrity error when decompressing.");
- else
- i = RETVAL_OK;
- } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
- error("Compressed file ends unexpectedly");
- }
- if (!bd)
- goto exit_1;
- if (bd->dbuf)
- large_free(bd->dbuf);
- if (pos)
- *pos = bd->inbufPos;
- free(bd);
- exit_1:
- if (!buf)
- free(inbuf);
- exit_0:
- if (flush)
- free(outbuf);
- return i;
- }
- #ifdef PREBOOT
- STATIC int INIT __decompress(unsigned char *buf, long len,
- long (*fill)(void*, unsigned long),
- long (*flush)(void*, unsigned long),
- unsigned char *outbuf, long olen,
- long *pos,
- void (*error)(char *x))
- {
- return bunzip2(buf, len - 4, fill, flush, outbuf, pos, error);
- }
- #endif
|