int lzma_init(gzFile infile, struct LZMAFile **lzmaFile) { LZMAFile *inBuffer; g_totalRead = 0; *lzmaFile = inBuffer = (LZMAFile *)malloc(sizeof(struct LZMAFile)); if (inBuffer == NULL) return -1; memset(inBuffer, 0, sizeof(LZMAFile)); inBuffer->File = infile; inBuffer->InCallback.Read = LzmaReadCompressed; inBuffer->waitEOS = 1; /* Read LZMA properties for compressed stream */ if (!MyReadFileAndCheck(infile, inBuffer->properties, LZMA_PROPERTIES_SIZE)) return -1; /* Read uncompressed size */ { int i; for (i = 0; i < 8; i++) { unsigned char b; if (!MyReadFileAndCheck(infile, &b, 1)) return -1; if (b != 0xFF) inBuffer->waitEOS = 0; if (i < 4) inBuffer->outSize += (UInt32)(b) << (i * 8); else inBuffer->outSizeHigh += (UInt32)(b) << ((i - 4) * 8); } } /* Decode LZMA properties and allocate memory */ if (LzmaDecodeProperties(&(inBuffer->state.Properties), inBuffer->properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) { PrintMessage("Incorrect stream properties"); return -1; } inBuffer->state.Probs = (CProb *)malloc(LzmaGetNumProbs(&(inBuffer->state.Properties)) * sizeof(CProb)); if (inBuffer->state.Probs == NULL) return -1; inBuffer->state.Dictionary = (unsigned char *)malloc(inBuffer->state.Properties.DictionarySize); if (inBuffer->state.Dictionary == NULL) return -1; LzmaDecoderInit(&(inBuffer->state)); return 0; }
static int Decode(FILE *inFile, FILE *outFile, char *rs) { UInt64 unpackSize; int thereIsSize; /* = 1, if there is uncompressed size in headers */ int i; int res = 0; CLzmaDec state; /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ unsigned char header[LZMA_PROPS_SIZE + 8]; /* Read and parse header */ if (!MyReadFileAndCheck(inFile, header, sizeof(header))) return PrintError(rs, kCantReadMessage); unpackSize = 0; thereIsSize = 0; for (i = 0; i < 8; i++) { unsigned char b = header[LZMA_PROPS_SIZE + i]; if (b != 0xFF) thereIsSize = 1; unpackSize += (UInt64)b << (i * 8); } LzmaDec_Construct(&state); res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); if (res != SZ_OK) return res; { Byte inBuf[IN_BUF_SIZE]; Byte outBuf[OUT_BUF_SIZE]; size_t inPos = 0, inSize = 0, outPos = 0; LzmaDec_Init(&state); for (;;) { if (inPos == inSize) { inSize = MyReadFile(inFile, inBuf, IN_BUF_SIZE); inPos = 0; } { SizeT inProcessed = inSize - inPos; SizeT outProcessed = OUT_BUF_SIZE - outPos; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; ELzmaStatus status; if (thereIsSize && outProcessed > unpackSize) { outProcessed = (SizeT)unpackSize; finishMode = LZMA_FINISH_END; } res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed, inBuf + inPos, &inProcessed, finishMode, &status); inPos += (UInt32)inProcessed; outPos += outProcessed; unpackSize -= outProcessed; if (outFile != 0) MyWriteFile(outFile, outBuf, outPos); outPos = 0; if (res != SZ_OK || thereIsSize && unpackSize == 0) break; if (inProcessed == 0 && outProcessed == 0) { if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) res = SZ_ERROR_DATA; break; } } } } LzmaDec_Free(&state, &g_Alloc); return res; }