/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++)
count[len] = 0; for (sym = 0; sym < codes; sym++)
count[lens[sym]]++;
/* bound code lengths, force root to be within code lengths */
root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */
here.op = (unsignedchar)64; /* invalid code marker */
here.bits = (unsignedchar)1;
here.val = (unsignedshort)0;
*(*table)++ = here; /* make a table to force an error */
*(*table)++ = here;
*bits = 1; return0; /* no symbols, but wait for decoding to report error */
} for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min;
/* check for an over-subscribed or incomplete set of lengths */
left = 1; for (len = 1; len <= MAXBITS; len++) {
left <<= 1;
left -= count[len]; if (left < 0) return -1; /* over-subscribed */
} if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0; for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + count[len];
/* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsignedshort)sym;
/* set up for code type */ switch (type) { case CODES:
base = extra = work; /* dummy value--not used */
match = 20; break; case LENS:
base = lbase;
extra = lext;
match = 257; break; default: /* DISTS */
base = dbase;
extra = dext;
match = 0;
}
/* initialize state for loop */
huff = 0; /* starting code */
sym = 0; /* starting code symbol */
len = min; /* starting code length */
next = *table; /* current table to fill in */
curr = root; /* current table index bits */
drop = 0; /* current bits to drop from code for index */
low = (unsigned)(-1); /* trigger new sub-table when len > root */
used = 1U << root; /* use root table entries */
mask = used - 1; /* mask for comparing low */
/* check available table space */ if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used > ENOUGH_DISTS)) return1;
/* process all codes and make table entries */ for (;;) { /* create table entry */
here.bits = (unsignedchar)(len - drop); if (work[sym] + 1U < match) {
here.op = (unsignedchar)0;
here.val = work[sym];
} elseif (work[sym] >= match) {
here.op = (unsignedchar)(extra[work[sym] - match]);
here.val = base[work[sym] - match];
} else {
here.op = (unsignedchar)(32 + 64); /* end of block */
here.val = 0;
}
/* replicate for those indices with low len bits equal to huff */
incr = 1U << (len - drop);
fill = 1U << curr;
min = fill; /* save offset to next table */ do {
fill -= incr;
next[(huff >> drop) + fill] = here;
} while (fill != 0);
/* go to next symbol, update count, len */
sym++; if (--(count[len]) == 0) { if (len == max) break;
len = lens[work[sym]];
}
/* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0)
drop = root;
/* increment past last table */
next += min; /* here min is 1 << curr */
/* determine length of next table */
curr = len - drop;
left = (int)(1 << curr); while (curr + drop < max) {
left -= count[curr + drop]; if (left <= 0) break;
curr++;
left <<= 1;
}
/* check for enough space */
used += 1U << curr; if ((type == LENS && used > ENOUGH_LENS) ||
(type == DISTS && used > ENOUGH_DISTS)) return1;
/* point entry in root table to sub-table */
low = huff & mask;
(*table)[low].op = (unsignedchar)curr;
(*table)[low].bits = (unsignedchar)root;
(*table)[low].val = (unsignedshort)(next - *table);
}
}
/* fill in remaining table entry if code is incomplete (guaranteed to have atmostoneremainingentry,sinceifthecodeisincomplete,the
maximum code length that was allowed to get this far is one bit) */ if (huff != 0) {
here.op = (unsignedchar)64; /* invalid code marker */
here.bits = (unsignedchar)(len - drop);
here.val = (unsignedshort)0;
next[huff] = here;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.