Ken
Ken

Reputation: 31161

Programmatically LZMA decompressing a static LZMA-compressed file

I'm LZMA-decompressing a resource file which I earlier compressed using lzma e <infile> <outfile> -lc0 -lp2 from the terminal and imported to my project. However when applied to this file LzmaDec_DecodeToBuf returns 1 in the first iteration, i.e. LZMA data error. (Also by which time inLen is always 5, outLen is 0.)

Why is that?

My code reads:

SRes static decompress(FILE *inFile, FILE *outFile)
{
  // Position the inFile pointer at the start.
  fseek(inFile, 0, SEEK_SET);

  // Read in LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header.
  char unsigned header[LZMA_PROPS_SIZE+8];
  fgets(header, sizeof(header), inFile);
  CLzmaDec state;
  LzmaDec_Construct(&state);
  SRes res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &SzAllocForLzma);

  if (res != SZ_OK) {
    // Free all allocated structures.
    LzmaDec_Free(&state, &SzAllocForLzma);
    return res;
  }

  char unsigned inBuf[IN_BUF_SIZE];
  char unsigned outBuf[OUT_BUF_SIZE];
  LzmaDec_Init(&state);

  ELzmaStatus status;
  long unsigned outLen = sizeof(outBuf);
  long unsigned inLen = sizeof(inBuf);
  long unsigned inPos = ftell(inFile);

  while (fgets(inBuf, sizeof(inBuf), inFile) != NULL) {
    inLen = MIN(sizeof(inBuf), MAX(ftell(inFile)-inPos, 0));
    outLen = sizeof(outBuf);

    SRes res = LzmaDec_DecodeToBuf(&state,
                                   outBuf,
                                   &outLen,
                                   inBuf,
                                   &inLen,
                                   LZMA_FINISH_ANY,
                                   &status);
// continues...

Upvotes: 0

Views: 1239

Answers (2)

Nathan
Nathan

Reputation: 1157

This is a rather old post to be replying to, however I ran into this same problem.

The issue is that the header is NOT supposed to be a part of the data you are decompressing. The solution is to start at sizeof(header) instead of 0, when reading the data, and don't forget to also adjust it's total length by sizeof(header) as well.

Upvotes: 1

ianc
ianc

Reputation: 1

Are you sure the input is not a 7zArchive? That would need calls to SzArEx_Open and SzArEx_Extract.

Upvotes: 0

Related Questions