2010-01-31 7 views

ответ

4

Я думаю, что нашел решение.

Это очень грубый образец кода, но, похоже, он работает нормально.

Я предполагаю, что у меня есть функция do_mmap(), которая отображает весь файл как доступный только для чтения в память и возвращает отображаемый общий размер. Это, естественно, может быть адаптировано для использования read/fread/ReadFile или любого другого Файлового API.

extern size_t get_uncompressed_size(const char *filename) 
{ 
    lzma_stream_flags stream_flags; 
    int file_size; 

    const uint8_t *data = (uint8_t *) do_mmap(filename, &file_size); 

    // 12 is the size of the footer per the file-spec... 
    const uint8_t *footer_ptr = data + file_size - 12; 

    // Something is terribly wrong 
    if (footer_ptr < data) { 
    do_unmap((void *)data, file_size); 
    return -1; 
    } 

    // Decode the footer, so we have the backward_size pointing to the index 
    lzma_stream_footer_decode(&stream_flags, (const uint8_t *)footer_ptr); 
    // This is the index pointer, where the size is ultimately stored... 
    const uint8_t *index_ptr = footer_ptr - stream_flags.backward_size; 
    // Allocate an index 
    lzma_index *index = lzma_index_init(NULL); 
    uint64_t memlimit; 
    size_t in_pos = 0; 
    // decode the index we calculated 
    lzma_index_buffer_decode(&index, &memlimit, NULL, index_ptr, &in_pos, footer_ptr - index_ptr); 
    // Just make sure the whole index was decoded, otherwise, we might be 
    // dealing with something utterly corrupt 
    if (in_pos != stream_flags.backward_size) { 
    do_unmap((void *)data, file_size); 
    lzma_index_end(index, NULL); 
    return -1; 
    } 
    // Finally get the size 
    lzma_vli uSize = lzma_index_uncompressed_size(index); 
    lzma_index_end(index, NULL); 
    return (size_t) uSize; 
} 
+0

я хочу использовать LZMA2 родную библиотеки, чтобы написать компрессию Hadoop codec.If у вас есть какая-либо документация по API или вашим помощь в отношении сжатия/декомпрессии будет очень полезна. – samarth

+0

Два вопроса. (1) Вам нужно инициализировать 'memlimit' перед вызовом' lzma_index_buffer_decode', или в некоторых случаях он вернет 'LZMA_MEMLIMIT_ERROR'. (2) Вы не должны называть 'lzma_index_init'. Начальное значение 'index' игнорируется' lzma_index_buffer_decode'. – Patrick

0

Скачав источник из sourceforge и имел взгляд здесь, я цитировал это из основного файла заголовка LzmaLib.h

 
/* 
LzmaUncompress 
-------------- 
In: 
    dest  - output data 
    destLen - output data size 
    src  - input data 
    srcLen - input data size 
Out: 
    destLen - processed output size 
    srcLen - processed input size 
Returns: 
    SZ_OK    - OK 
    SZ_ERROR_DATA  - Data error 
    SZ_ERROR_MEM   - Memory allocation arror 
    SZ_ERROR_UNSUPPORTED - Unsupported properties 
    SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) 
*/ 

MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, 
    const unsigned char *props, size_t propsSize); 

Похоже, что destLen является размер данных, которые несжатый.

Надеюсь, это поможет, С уважением, Tom.

+1

Я думаю, что формат XZ файл не является прямым LZMA, а обертка для различных алгоритмов сжатия –