6 * This function reads the header at the beginning of src and writes
7 * the compressed and decompressed size to compressedSize and
10 * The header consists of 16 bytes: 8 bytes each in little-endian format
11 * of the compressed size and the decompressed size.
13 void LDM_readHeader(const void *src, U64 *compressedSize,
14 U64 *decompressedSize) {
15 const BYTE *ip = (const BYTE *)src;
16 *compressedSize = MEM_readLE64(ip);
17 *decompressedSize = MEM_readLE64(ip + 8);
21 * Writes the 16-byte header (8-bytes each of the compressedSize and
22 * decompressedSize in little-endian format) to memPtr.
24 void LDM_writeHeader(void *memPtr, U64 compressedSize,
25 U64 decompressedSize) {
26 MEM_writeLE64(memPtr, compressedSize);
27 MEM_writeLE64((BYTE *)memPtr + 8, decompressedSize);
31 size_t compressedSize;
32 size_t maxDecompressedSize;
34 const BYTE *ibase; /* Base of input */
35 const BYTE *ip; /* Current input position */
36 const BYTE *iend; /* End of source */
38 const BYTE *obase; /* Base of output */
39 BYTE *op; /* Current output position */
40 const BYTE *oend; /* End of output */
43 void LDM_initializeDCtx(LDM_DCtx *dctx,
44 const void *src, size_t compressedSize,
45 void *dst, size_t maxDecompressedSize) {
46 dctx->compressedSize = compressedSize;
47 dctx->maxDecompressedSize = maxDecompressedSize;
50 dctx->ip = (const BYTE *)src;
51 dctx->iend = dctx->ip + dctx->compressedSize;
53 dctx->oend = dctx->op + dctx->maxDecompressedSize;
56 size_t LDM_decompress(const void *src, size_t compressedSize,
57 void *dst, size_t maxDecompressedSize) {
60 LDM_initializeDCtx(&dctx, src, compressedSize, dst, maxDecompressedSize);
62 while (dctx.ip < dctx.iend) {
65 size_t length, offset;
67 /* Get the literal length. */
68 const unsigned token = *(dctx.ip)++;
69 if ((length = (token >> ML_BITS)) == RUN_MASK) {
77 /* Copy the literals. */
78 cpy = dctx.op + length;
79 memcpy(dctx.op, dctx.ip, length);
83 //TODO: dynamic offset size?
84 /* Encode the offset. */
85 offset = MEM_read32(dctx.ip);
86 dctx.ip += LDM_OFFSET_SIZE;
87 match = dctx.op - offset;
89 /* Get the match length. */
90 length = token & ML_MASK;
91 if (length == ML_MASK) {
98 length += LDM_MIN_MATCH_LENGTH;
101 cpy = dctx.op + length;
103 // TODO: this can be made more efficient.
104 while (match < cpy - offset && dctx.op < dctx.oend) {
105 *(dctx.op)++ = *match++;
108 return dctx.op - (BYTE *)dst;