/*
// Copyright 2017 2018 Intel Corporation All Rights Reserved.
//
// The source code, information and material ("Material") contained herein is
// owned by Intel Corporation or its suppliers or licensors, and title
// to such Material remains with Intel Corporation or its suppliers or
// licensors. The Material contains proprietary information of Intel
// or its suppliers and licensors. The Material is protected by worldwide
// copyright laws and treaty provisions. No part of the Material may be used,
// copied, reproduced, modified, published, uploaded, posted, transmitted,
// distributed or disclosed in any way without Intel's prior express written
// permission. No license under any patent, copyright or other intellectual
// property rights in the Material is granted to or conferred upon you,
// either expressly, by implication, inducement, estoppel or otherwise.
// Any license under such intellectual property rights must be express and
// approved by Intel in writing.
//
// Unless otherwise agreed by Intel in writing,
// you may not remove or alter this notice or any other notice embedded in
// Materials by Intel or Intel's suppliers or licensors in any way.
*/
/*
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;
}