1920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell/************************************** 2920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell * Compiler Options 3920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell **************************************/ 4920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#ifdef _MSC_VER /* Visual Studio */ 5920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell# define _CRT_SECURE_NO_WARNINGS // for MSVC 6920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell# define snprintf sprintf_s 7920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#endif 8920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#ifdef __GNUC__ 9920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell# pragma GCC diagnostic ignored "-Wmissing-braces" /* GCC bug 53119 : doesn't accept { 0 } as initializer (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119) */ 10920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#endif 11920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 12920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 13920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell/************************************** 14920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell * Includes 15920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell **************************************/ 16920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#include <stdio.h> 17920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#include <stdint.h> 18920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#include <stdlib.h> 19920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#include <string.h> 20920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell#include "lz4.h" 21920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 22920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 23920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell/* Returns non-zero on failure. */ 24920bf21714f99cc20d3b8bcc28060136a390354aNick Terrellint test_compress(const char *input, int inSize, char *output, int outSize) 25920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell{ 26920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell LZ4_stream_t lz4Stream_body = { 0 }; 27920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell LZ4_stream_t* lz4Stream = &lz4Stream_body; 28920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 29920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int inOffset = 0; 30920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int outOffset = 0; 31920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 32920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if (inSize & 3) return -1; 33920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 34920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell while (inOffset < inSize) { 35920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell const int length = inSize >> 2; 36920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if (inSize > 1024) return -2; 37920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if (outSize - (outOffset + 8) < LZ4_compressBound(length)) return -3; 38920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell { 393580d9698098e8ad2ef757d1c3673aceca38c576Yann Collet const int outBytes = LZ4_compress_fast_continue( 403580d9698098e8ad2ef757d1c3673aceca38c576Yann Collet lz4Stream, input + inOffset, output + outOffset + 8, length, outSize-outOffset, 1); 41920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if(outBytes <= 0) return -4; 42920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memcpy(output + outOffset, &length, 4); /* input length */ 43920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memcpy(output + outOffset + 4, &outBytes, 4); /* output length */ 44920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell inOffset += length; 45920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell outOffset += outBytes + 8; 46920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 47920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 48920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if (outOffset + 8 > outSize) return -5; 49920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memset(output + outOffset, 0, 4); 50920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memset(output + outOffset + 4, 0, 4); 51920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell return 0; 52920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell} 53920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 54920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell/* Returns non-zero on failure. Not a safe function. */ 55920bf21714f99cc20d3b8bcc28060136a390354aNick Terrellint test_decompress(const char *uncompressed, const char *compressed) 56920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell{ 57920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char outBufferA[1024]; 58920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char spacing; /* So prefixEnd != dest */ 59920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char outBufferB[1024]; 60920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char *output = outBufferA; 61920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char *lastOutput = outBufferB; 62920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell LZ4_streamDecode_t lz4StreamDecode_body = { 0 }; 63920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body; 64920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int offset = 0; 65920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int unOffset = 0; 66920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int lastBytes = 0; 67920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 68920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell (void)spacing; 69920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 70920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell for(;;) { 71920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int32_t bytes; 72920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int32_t unBytes; 73920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell /* Read uncompressed size and compressed size */ 74920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memcpy(&unBytes, compressed + offset, 4); 75920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell memcpy(&bytes, compressed + offset + 4, 4); 76920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell offset += 8; 77920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell /* Check if we reached end of stream or error */ 78920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if(bytes == 0 && unBytes == 0) return 0; 79920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if(bytes <= 0 || unBytes <= 0 || unBytes > 1024) return 1; 80920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 81920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell /* Put the last output in the dictionary */ 82920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell LZ4_setStreamDecode(lz4StreamDecode, lastOutput, lastBytes); 83920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell /* Decompress */ 84920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell bytes = LZ4_decompress_fast_continue( 85920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell lz4StreamDecode, compressed + offset, output, unBytes); 86920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if(bytes <= 0) return 2; 87920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell /* Check result */ 883f6f57768752a5687c2715ad4a7cd4ebfa502bc2Yann Collet { int const r = memcmp(uncompressed + unOffset, output, unBytes); 89920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if (r) return 3; 90920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 913f6f57768752a5687c2715ad4a7cd4ebfa502bc2Yann Collet { char* const tmp = output; output = lastOutput; lastOutput = tmp; } 92920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell offset += bytes; 93920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell unOffset += unBytes; 94920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell lastBytes = unBytes; 95920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 96920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell} 97920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 98920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 99920bf21714f99cc20d3b8bcc28060136a390354aNick Terrellint main(int argc, char **argv) 100920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell{ 101920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char input[] = 102920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 103920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 104920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 105920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 106920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 107920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 108920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 109920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 110920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 111920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 112920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 113920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 114920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 115920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 116920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello!" 117920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell "Hello Hello Hello Hello Hello Hello Hello Hello"; 118920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell char output[LZ4_COMPRESSBOUND(4096)]; 119920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell int r; 120920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 121920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell (void)argc; 122920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell (void)argv; 123920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell 124920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if ((r = test_compress(input, sizeof(input), output, sizeof(output)))) { 125920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell return r; 126920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 127920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell if ((r = test_decompress(input, output))) { 128920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell return r; 129920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell } 130920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell return 0; 131920bf21714f99cc20d3b8bcc28060136a390354aNick Terrell} 132