/*******************************************************************************
* Copyright 2017-2018 Intel Corporation.
*
* This software and the related documents are Intel copyrighted materials, and
* your use of them is governed by the express license under which they were
* provided to you (License). Unless the License provides otherwise, you may not
* use, modify, copy, publish, distribute, disclose or transmit this software or
* the related documents without Intel's prior written permission.
*
* This software and the related documents are provided as is, with no express
* or implied warranties, other than those that are expressly stated in the
* License.
*******************************************************************************/
/*
The example below shows how to use the functions:
ippsEncodeLZ4HashTableGetSize_8u
ippsEncodeLZ4HashTableInit_8u
ippsEncodeLZ4Dict_8u
ippsDecodeLZ4_8u
*/
#include <stdio.h>
#include <string.h>
#include <ipp.h>
/* Next two defines are created to simplify code reading and understanding */
#define EXIT_MAIN exitLine: /* Label for Exit */
#define check_sts(st) if((st) != ippStsNoErr) goto exitLine; /* Go to Exit if Intel(R) Integrated Primitives (Intel(R) IPP) function returned status different from ippStsNoErr */
#define TEST_SIZE (1024 * 4)
#define CHUNK_SIZE (512)
#define RATIO (TEST_SIZE / CHUNK_SIZE)
static int Verify(const Ipp8u* comprBuf, int comprLen, Ipp8u* decomprBuf,
int maxDecomprLen, const Ipp8u* srcBuf, int srcLen);
int main(void)
{
Ipp8u *srcBuf = NULL, *comprBuf = NULL, *decomprBuf = NULL, *hashTable = NULL;
Ipp8u *comprPtr, *dict;
IppStatus st = ippStsNoErr;
int hashSize = 0,
maxChunkCompr = CHUNK_SIZE + CHUNK_SIZE / 255 + 16,
comprLen = (maxChunkCompr) * RATIO, /* Extra bytes for uncompressible
data */
decomprLen = TEST_SIZE + 33;
int destLen;
int i;
srcBuf = ippsMalloc_8u(TEST_SIZE);
decomprBuf = ippsMalloc_8u(decomprLen); /* Spare bytes for "wild" (non-safe)
decompression */
comprBuf = ippsMalloc_8u(comprLen);
/* Initialize source buffer */
check_sts( st = ippsVectorJaehne_8u(srcBuf, TEST_SIZE, IPP_MAX_8U) )
for(i = 0; i < TEST_SIZE; i++)
srcBuf[i] >>= 6; /* Decrease source data entropy */
/* Allocate and initialize hash table */
check_sts( st = ippsEncodeLZ4HashTableGetSize_8u(&hashSize) )
hashTable = ippsMalloc_8u(hashSize);
check_sts( st = ippsEncodeLZ4HashTableInit_8u(hashTable, TEST_SIZE) )
/* Compress source data using chunks without dictionary*/
comprPtr = comprBuf;
for(i = 0; i < RATIO; i++)
{
destLen = maxChunkCompr;
check_sts( st = ippsEncodeLZ4_8u(srcBuf + CHUNK_SIZE * i, CHUNK_SIZE,
comprPtr + 2, &destLen, hashTable) )
*comprPtr++ = destLen & 0xFF;
*comprPtr++ = (destLen >> 8) & 0xFF;
comprPtr += destLen;
}
/* Print compression result */
comprLen = (int)(comprPtr - comprBuf);
printf("Compression w/o dictionary: %d bytes compressed into %d bytes.", TEST_SIZE,
comprLen);
if(!Verify(comprBuf, comprLen, decomprBuf, decomprLen, srcBuf, TEST_SIZE))
{
printf("Verification failed!\n");
st = ippStsErr;
goto exitLine;
}
else
printf("Verified.\n");
/* Compress source data with dictionary*/
comprPtr = comprBuf;
dict = srcBuf;
for(i = 0; i < RATIO; i++)
{
int srcIdx, dictLen;
destLen = maxChunkCompr;
srcIdx = CHUNK_SIZE * i;
dictLen = CHUNK_SIZE * i; /* All previous chunks as dictionary */
check_sts( st = ippsEncodeLZ4Dict_8u(srcBuf + CHUNK_SIZE * i, srcIdx, CHUNK_SIZE,
comprPtr + 2, &destLen, hashTable, dict,
dictLen) )
*comprPtr++ = destLen & 0xFF;
*comprPtr++ = (destLen >> 8) & 0xFF;
comprPtr += destLen;
}
/* Print compression result */
comprLen = (int)(comprPtr - comprBuf);
printf("Compression with dictionary: %d bytes compressed into %d bytes.", TEST_SIZE,
comprLen);
if(!Verify(comprBuf, comprLen, decomprBuf, decomprLen, srcBuf, TEST_SIZE))
{
printf("Verification failed!\n");
st = ippStsErr;
goto exitLine;
}
else
printf("Verified.\n");
EXIT_MAIN
if(st != ippStsNoErr)
printf("Function status: %s\n", ippGetStatusString(st));
ippsFree(srcBuf);
ippsFree(comprBuf);
ippsFree(decomprBuf);
ippsFree(hashTable);
return (int)st;
}
static int Verify(const Ipp8u* comprBuf, int comprLen, Ipp8u* decomprBuf,
int maxDecomprLen, const Ipp8u* srcBuf, int srcLen)
{
const Ipp8u* locPtr = comprBuf;
Ipp8u* decomprPtr = decomprBuf;
IppStatus st;
int decomprLen = 0;
while((int)(locPtr - comprBuf) < comprLen)
{
int nextInLen;
int nextOutLen;
nextInLen = (*locPtr++);
nextInLen += (*locPtr++) << 8;
nextOutLen = maxDecomprLen - decomprLen;
st = ippsDecodeLZ4_8u(locPtr, nextInLen, decomprPtr, &nextOutLen);
if(st != ippStsNoErr) return 0;
locPtr += nextInLen;
decomprLen += nextOutLen;
decomprPtr += nextOutLen;
}
if(decomprLen != srcLen || memcmp(decomprBuf, srcBuf, srcLen) != 0)
return 0;
return 1;
}