Simon-Okp
Simon-Okp

Reputation: 697

lzma compress/Uncompress from memory c++

I have a code working, but i'm not entirely satisfied of the result, so I figured I could ask some questions here.

Here are my two functions :

void compress(string nameSrc, string nameDst){

    ifstream input;
    input.open(nameSrc,fstream::in | fstream::binary);

    size_t propsSize = LZMA_PROPS_SIZE;
    size_t srcLen = getLength(input);
    size_t dstLen = srcLen; //??? no idea how to know to right value here

    unsigned char* src = new unsigned char[srcLen];
    unsigned char* dst = new unsigned char[dstLen + propsSize];

    input.read((char*)src, srcLen);

    int res = LzmaCompress(
        &dst[LZMA_PROPS_SIZE], &dstLen,
        src, srcLen,
        dst, &propsSize,
        -1, 0, -1, -1, -1, -1, -1);

    delete [] src;
    input.close();

    ofstream output(nameDst, ios::binary);
    output.write((char*)dst, dstLen + propsSize);

    delete [] dst;


}

and :

void unCompress(string nameSrc, string nameDst){

    ifstream input;
    input.open(nameSrc,fstream::in | fstream::binary);

    size_t srcLen = getLength(input);
    size_t dstLen = srcLen*5; //??? no idea how to know to right value here

    unsigned char* src = new unsigned char[srcLen];
    unsigned char* dst = new unsigned char[dstLen];

    input.read((char*)src,srcLen);

    int res = LzmaUncompress(dst,&dstLen,&src[LZMA_PROPS_SIZE],&srcLen, src, LZMA_PROPS_SIZE);

    delete [] src;
    input.close();

    ofstream output(nameDst, ios::binary);
    output.write((char*)dst, dstLen);

    delete [] dst;
}

  1. In both function, how am I supposed to know what value to put into dstLen ? I don't want to allocate a lot of memory for nothing.
  2. Is it bad that I have to cast to char* ? Do I really have to use unsigned char ?
  3. I tried changing the last argument of LzmaCompress (numThreads), it didn't improve the performance, not even slightly. Is there something else to do ?
  4. if you have any tips, feel free to tell me.

Thanks.

Upvotes: 1

Views: 5046

Answers (2)

janbar
janbar

Reputation: 13

I think you can save the length of the source file to the compressed file. You can read the length of the source file through the compressed file when decompressing.

Of course, you can use this for compression,That's the result of my multiple searches

dstLen = LZMA_PROPS_SIZE + srcLen + srcLen/3 + 128

Upvotes: 0

widmore
widmore

Reputation: 11

Use following function to get destination size:

INT32
EFIAPI
LzmaGetInfo(
CONST VOID  *Source,
UINT32      SourceSize,
UINT32      *DestinationSize
)
{
    UInt64  DecodedSize;

    ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize;

    DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source);

    *DestinationSize = (UINT32)DecodedSize;
    return ERR_SUCCESS;
}

Upvotes: 1

Related Questions