2016-11-22 10 views
8

Я пытаюсь использовать LzmaLibLzmaCompress() и LzmaDecompress() с буферами, приспосабливая приведенные примеры here.LzmaLib: сжатие/распаковка буфера в C

Я тестирую буфер размером ~ 3 МБ, и функция сжатия работает нормально (производит сжатый буфер ~ 1,2 МБ), но когда я пытаюсь распаковать, он просто извлекает ~ 300 байт и возвращает SZ_ERROR_DATA.

Несколько извлеченных байтов являются правильными, но я не знаю, почему он останавливается там.

Мой код:

#include <stdio.h> 
#include <stdlib.h> 

#include "LzmaLib.h" 

void compress(
    unsigned char **outBuf, size_t *dstLen, 
    unsigned char *inBuf, size_t srcLen) 
{ 
    unsigned propsSize = LZMA_PROPS_SIZE; 
    *dstLen = srcLen + srcLen/3 + 128; 

    *outBuf = (unsigned char*)malloc(propsSize + *dstLen); 

    int res = LzmaCompress(
     (unsigned char*)(*outBuf + LZMA_PROPS_SIZE), dstLen, 
     inBuf, srcLen, 
     *outBuf, &propsSize, 
     -1, 0, -1, -1, -1, -1, -1); 

    assert(res == SZ_OK); 

    *dstLen = *dstLen + LZMA_PROPS_SIZE; 
} 

void uncompress(
    unsigned char **outBuf, size_t *dstLen, 
    unsigned char *inBuf, size_t srcLen 
) { 
    *dstLen = 5000000; 
    *outBuf = (unsigned char*)malloc(*dstLen); 

    srcLen = srcLen - LZMA_PROPS_SIZE; 
    int res = LzmaUncompress(
     *outBuf, dstLen, 
     (unsigned char*)(inBuf + LZMA_PROPS_SIZE), &srcLen, 
     inBuf, LZMA_PROPS_SIZE); 

    assert(res == SZ_OK); 
} 

void do_compress() { 
    FILE* file = fopen("Module.dll", "r"); 
    size_t size, decSize; 
    unsigned char *data, *dec = NULL; 

    fseek(file, 0L, SEEK_END); 
    size = ftell(file); 
    fseek(file, 0L, SEEK_SET); 

    data = (unsigned char*)malloc(size); 
    fread(data, 1, size, file); 
    fclose(file); 

    compress((unsigned char**)&dec, &decSize, data, size); 

    file = fopen("Module.lzma", "w"); 
    fwrite(dec, 1, decSize, file); 
    fclose(file); 
} 

void do_uncompress() { 
    FILE* file = fopen("Module.lzma", "r"); 
    size_t size, decSize; 
    unsigned char *data, *dec = NULL; 

    fseek(file, 0L, SEEK_END); 
    size = ftell(file); 
    fseek(file, 0L, SEEK_SET); 

    data = (unsigned char*)malloc(size); 
    fread(data, 1, size, file); 
    fclose(file); 

    uncompress((unsigned char**)&dec, &decSize, data, size); 

    file = fopen("Module_DEC.dll", "w"); 
    fwrite(dec, 1, decSize, file); 
    fclose(file); 
} 

int main() 
{ 
    do_compress(); 
    do_uncompress(); 

    return 0; 
} 

Если этот код не лучший способ сжатия буферов с LzmaLib, я рад принять предложения.

+0

прохожу 'dstLen' и проблема сохраняется. Только несколько байтов распаковываются, и возвращается ошибка 1 ('SZ_ERROR_DATA'). – karliwson

ответ

8

Бьюсь об заклад, проблема скрывается в том, как вы читаете/пишете свои файлы. Вам нужно открыть их в двоичном режиме, чтобы предотвратить любые замены во время операций чтения/записи.

Изменение всех экземпляров:

  • fopen(xxx, "r") ->fopen(xxx, "rb")
  • fopen(xxx, "w") ->fopen(xxx, "wb")
+0

Человек, я не могу сказать слова, о которых я сейчас думаю. Это была точная проблема. Большое спасибо. – karliwson

+0

Маленькие ошибки труднее всего найти :) – Codeguard

0

Я не проверял это специально для LzmaCompress, но большинство других компрессионных библиотек, таких как дескриптор libz, которые функционируют аналогично стандартным функциям чтения/записи или fread/fwrite, то есть позволяют постоянно вызывать функции для сжатия большего количества и больше данных в одном потоке. Поэтому в какой-то момент вам придется сказать: «Я закончил, пожалуйста, промойте все, что не написано до сих пор». Возможно, вы забыли эту часть. Если нет, то Minimal, Complete, and Verifiable example будет классно.

+0

Я понимаю, но 'LzmaCompress()' и 'LzmaDecompress()' являются вспомогательными функциями, которые сжимают/декомпилируют полный блок данных одним вызовом. – karliwson

+0

, тогда часть о MCVE остается. –

0

Когда вы сжимаете, вы передаете количество сжатых выходных байтов вызывающему. Но ваш буфер содержит LZMA_PROPS_SIZE дополнительных байтов. Итак, при написании файла lzma вы фактически забудете последние LZMA_PROPS_SIZE байт, а при последующем прочтении они отсутствуют.

+0

Это правда. Я добавил 'LZMA_PROPS_SIZE' размер результата, но проблема все еще сохраняется. – karliwson

 Смежные вопросы

  • Нет связанных вопросов^_^