11 static inline uint64_t get_64(const void *p
)
13 const unsigned char *data
= (const unsigned char *)p
;
14 return (L data
[0]) | (L data
[1] << 8) | (L data
[2] << 16) |
15 (L data
[3] << 24) | (L data
[4] << 32) | (L data
[5] << 40) |
16 (L data
[6] << 48) | (L data
[7] << 56);
19 static void put_64(void *p
, uint64_t value
)
21 unsigned char *data
= (unsigned char *)p
;
22 data
[0] = value
& 0xff;
23 data
[1] = (value
>> 8) & 0xff;
24 data
[2] = (value
>> 16) & 0xff;
25 data
[3] = (value
>> 24) & 0xff;
26 data
[4] = (value
>> 32) & 0xff;
27 data
[5] = (value
>> 40) & 0xff;
28 data
[6] = (value
>> 48) & 0xff;
29 data
[7] = (value
>> 56) & 0xff;
32 /* Memory Allocation API */
34 static void *SzAlloc(unused
void *u
, size_t size
)
39 static void SzFree(unused
void *u
, void *address
)
44 static struct ISzAlloc LZMAalloc
= { SzAlloc
, SzFree
};
54 static struct vector_t instream
, outstream
;
56 static SRes
Read(unused
void *u
, void *buf
, size_t *size
)
58 if ((instream
.size
- instream
.pos
) < *size
)
59 *size
= instream
.size
- instream
.pos
;
60 memcpy(buf
, instream
.p
+ instream
.pos
, *size
);
61 instream
.pos
+= *size
;
65 static size_t Write(unused
void *u
, const void *buf
, size_t size
)
67 if(outstream
.size
- outstream
.pos
< size
)
68 size
= outstream
.size
- outstream
.pos
;
69 memcpy(outstream
.p
+ outstream
.pos
, buf
, size
);
70 outstream
.pos
+= size
;
74 static struct ISeqInStream is
= { Read
};
75 static struct ISeqOutStream os
= { Write
};
78 * Compress a buffer with lzma
79 * Don't copy the result back if it is too large.
80 * @param in a pointer to the buffer
81 * @param in_len the length in bytes
82 * @param out a pointer to a buffer of at least size in_len
83 * @param out_len a pointer to the compressed length of in
86 int do_lzma_compress(char *in
, int in_len
, char *out
, int *out_len
)
89 ERROR("LZMA: Input length is zero.\n");
93 struct CLzmaEncProps props
;
94 LzmaEncProps_Init(&props
);
95 props
.dictSize
= in_len
;
96 props
.pb
= 0; /* PosStateBits, default: 2, range: 0..4 */
97 props
.lp
= 0; /* LiteralPosStateBits, default: 0, range: 0..4 */
98 props
.lc
= 1; /* LiteralContextBits, default: 3, range: 0..8 */
99 props
.fb
= 273; /* NumFastBytes */
100 props
.mc
= 0; /* MatchFinderCycles, default: 0 */
101 props
.algo
= 1; /* AlgorithmNo, apparently, 0 and 1 are valid values. 0 = fast mode */
102 props
.numThreads
= 1;
104 switch (props
.algo
) {
105 case 0: // quick: HC4
113 props
.numHashBytes
= 4;
117 CLzmaEncHandle p
= LzmaEnc_Create(&LZMAalloc
);
119 int res
= LzmaEnc_SetProps(p
, &props
);
121 ERROR("LZMA: LzmaEnc_SetProps failed.\n");
125 unsigned char propsEncoded
[LZMA_PROPS_SIZE
+ 8];
126 size_t propsSize
= sizeof propsEncoded
;
127 res
= LzmaEnc_WriteProperties(p
, propsEncoded
, &propsSize
);
129 ERROR("LZMA: LzmaEnc_WriteProperties failed.\n");
135 instream
.size
= in_len
;
139 outstream
.size
= in_len
;
141 put_64(propsEncoded
+ LZMA_PROPS_SIZE
, in_len
);
142 Write(&os
, propsEncoded
, LZMA_PROPS_SIZE
+8);
144 res
= LzmaEnc_Encode(p
, &os
, &is
, 0, &LZMAalloc
, &LZMAalloc
);
145 LzmaEnc_Destroy(p
, &LZMAalloc
, &LZMAalloc
);
147 ERROR("LZMA: LzmaEnc_Encode failed %d.\n", res
);
151 *out_len
= outstream
.pos
;
155 int do_lzma_uncompress(char *dst
, int dst_len
, char *src
, int src_len
,
158 if (src_len
<= LZMA_PROPS_SIZE
+ 8) {
159 ERROR("LZMA: Input length is too small.\n");
163 uint64_t out_sizemax
= get_64(&src
[LZMA_PROPS_SIZE
]);
165 if (out_sizemax
> (size_t) dst_len
) {
166 ERROR("Not copying %d bytes to %d-byte buffer!\n",
167 (unsigned int)out_sizemax
, dst_len
);
171 enum ELzmaStatus status
;
173 size_t destlen
= out_sizemax
;
174 size_t srclen
= src_len
- (LZMA_PROPS_SIZE
+ 8);
176 int res
= LzmaDecode((uint8_t *) dst
, &destlen
,
177 (uint8_t *) &src
[LZMA_PROPS_SIZE
+ 8], &srclen
,
178 (uint8_t *) &src
[0], LZMA_PROPS_SIZE
,
184 ERROR("Error while decompressing.\n");
188 if (actual_size
!= NULL
)
189 *actual_size
= destlen
;