Closed nemequ closed 9 years ago
Test case (just change CODEC_TO_TEST
to MSCOMP_XPRESS
or MSCOMP_XPRESS_HUFF
and it will work as expected:
#include "mscomp.h"
#include <stdio.h>
#include <assert.h>
#include <assert.h>
#include <stdint.h>
#define CODEC_TO_TEST MSCOMP_LZNT1
#define LOREM_IPSUM (uint8_t*) \
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate " \
"lectus nisl, vitae ultricies justo dictum nec. Vestibulum ante ipsum " \
"primis in faucibus orci luctus et ultrices posuere cubilia Curae; " \
"Suspendisse suscipit quam a lectus adipiscing, sed tempor purus " \
"cursus. Vivamus id nulla eget elit eleifend molestie. Integer " \
"sollicitudin lorem enim, eu eleifend orci facilisis sed. Pellentesque " \
"sodales luctus enim vel viverra. Cras interdum vel nisl in " \
"facilisis. Curabitur sollicitudin tortor vel congue " \
"auctor. Suspendisse egestas orci vitae neque placerat blandit.\n" \
"\n" \
"Aenean sed nisl ultricies, vulputate lorem a, suscipit nulla. Donec " \
"egestas volutpat neque a eleifend. Nullam porta semper " \
"nunc. Pellentesque adipiscing molestie magna, quis pulvinar metus " \
"gravida sit amet. Vestibulum mollis et sapien eu posuere. Quisque " \
"tristique dignissim ante et aliquet. Phasellus vulputate condimentum " \
"nulla in vulputate.\n" \
"\n" \
"Nullam volutpat tellus at nisi auctor, vitae mattis nibh viverra. Nunc " \
"vitae lectus tristique, ultrices nibh quis, lobortis elit. Curabitur " \
"at vestibulum nisi, nec facilisis ante. Nulla pharetra blandit lacus, " \
"at sodales nulla placerat eget. Nulla congue varius tortor, sit amet " \
"tempor est mattis nec. Praesent vitae tristique ipsum, rhoncus " \
"tristique lorem. Sed et erat tristique ligula accumsan fringilla eu in " \
"urna. Donec dapibus hendrerit neque nec venenatis. In euismod sapien " \
"ipsum, auctor consectetur mi dapibus hendrerit.\n" \
"\n" \
"Phasellus sagittis rutrum velit, in sodales nibh imperdiet a. Integer " \
"vitae arcu blandit nibh laoreet scelerisque eu sit amet eros. Aenean " \
"odio felis, aliquam in eros at, ornare luctus magna. In semper " \
"tincidunt nunc, sollicitudin gravida nunc laoreet eu. Cras eu tempor " \
"sapien, ut dignissim elit. Proin eleifend arcu tempus, semper erat et, " \
"accumsan erat. Praesent vulputate diam mi, eget mollis leo " \
"pellentesque eget. Aliquam eu tortor posuere, posuere velit sed, " \
"suscipit eros. Nam eu leo vitae mauris condimentum lobortis non quis " \
"mauris. Nulla venenatis fringilla urna nec venenatis. Nam eget velit " \
"nulla. Proin ut malesuada felis. Suspendisse vitae nunc neque. Donec " \
"faucibus tempor lacinia. Vivamus ac vulputate sapien, eget lacinia " \
"nisl.\n" \
"\n" \
"Curabitur eu dolor molestie, ullamcorper lorem quis, egestas " \
"urna. Suspendisse in arcu sed justo blandit condimentum. Ut auctor, " \
"sem quis condimentum mattis, est purus pulvinar elit, quis viverra " \
"nibh metus ac diam. Etiam aliquet est eu dui fermentum consequat. Cras " \
"auctor diam eget bibendum sagittis. Aenean elementum purus sit amet " \
"sem euismod, non varius felis dictum. Aliquam tempus pharetra ante a " \
"sagittis. Curabitur ut urna felis. Etiam sed vulputate nisi. Praesent " \
"at libero eleifend, sagittis quam a, varius sapien."
#define LOREM_IPSUM_LENGTH ((size_t) 2725)
int main(int argc, char *argv[]) {
static uint8_t compressed[4096];
size_t compressed_length = sizeof (compressed);
static uint8_t decompressed[LOREM_IPSUM_LENGTH];
size_t decompressed_length = sizeof (decompressed);
MSCompStatus res = ms_compress (CODEC_TO_TEST, LOREM_IPSUM, LOREM_IPSUM_LENGTH, compressed, &compressed_length);
assert (res == MSCOMP_OK);
fprintf (stdout, "Compressed %p[%zu] to %p[%zu]\n", LOREM_IPSUM, LOREM_IPSUM_LENGTH, compressed, compressed_length);
res = ms_decompress (CODEC_TO_TEST, compressed, compressed_length, decompressed, &decompressed_length);
fprintf (stdout, "Decompressed %p[%zu] to %p[%zu]\n", compressed, compressed_length, decompressed, decompressed_length);
assert (decompressed_length == LOREM_IPSUM_LENGTH);
decompressed_length--;
res = ms_decompress (CODEC_TO_TEST, compressed, compressed_length, decompressed, &decompressed_length);
assert (res == MSCOMP_BUF_ERROR);
fprintf (stderr, "Victory!\n");
return 0;
}
This seems to be because LZNT1 does not have an optimized decompressor like Xpress and Xpress Huffman and is using the ALL_AT_ONCE_WRAPPER_DECOMPRESS. If you compile with MSCOMP_WITHOUT_OPT_DECOMPRESS all will behave by returning MSCOMP_DATA_ERROR. It looks as though my ALL_AT_ONCE_WRAPPER_DECOMPRESS needs to be improved...
So, the underlying issue is that *_inflate_end always returns MSCOMP_DATA_ERROR when the stream doesn't seem to be at the proper end (an "inconsistent state"). This reflects what inflateEnd in zlib returns (they return Z_STREAM_ERROR). I will have to think about how to change how this all operates so that when using the ALL_AT_ONCE_WRAPPER_DECOMPRESS you don't lose the MSCOMP_BUF_ERROR error messages.
Thanks.
When I decompress some data to a buffer which is 1 byte too small (using
ms_decompress(MSCOMP_LZNT1, …)
) I getMSCOMP_DATA_ERROR
(-3) instead ofMSCOMP_BUF_ERROR
(-5).xpress and xpress-huffman work as expected.