/*******************************************************************************
* 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
     ippsEncodeLZ4Safe_8u
*/

#include <stdio.h>
#include <string.h>

#include <ippdc.h>
#include <ipps.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)
#define COMPR_LEN (TEST_SIZE / 20)

int main(void)
{
    Ipp8u       *srcBuf = NULL, *comprBuf = NULL, *hashTable = NULL;
    IppStatus   st = ippStsNoErr;
    int         i, hashSize, remBytes, srcLen, dstLen;

    srcBuf      = ippsMalloc_8u(TEST_SIZE);
    comprBuf    = ippsMalloc_8u(COMPR_LEN);
    /* 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 */
    /* Init and allocate hash table */
    check_sts(  st = ippsEncodeLZ4HashTableGetSize_8u(&hashSize)    )
    hashTable   = ippsMalloc_8u(hashSize);
    check_sts(  st = ippsEncodeLZ4HashTableInit_8u(hashTable, TEST_SIZE)    )
    /* Compress source data */
    remBytes = TEST_SIZE;
    while(remBytes > 0)
    {
        srcLen = remBytes;
        dstLen = COMPR_LEN;
        /* Compressing into knowingly small buffer */
        st = ippsEncodeLZ4Safe_8u((const Ipp8u*)srcBuf + TEST_SIZE - remBytes, &srcLen,
                                  comprBuf, &dstLen, hashTable);
        if(st == ippStsDstSizeLessExpected)
        {
            /* Print compression result */
            printf("Compression: %d bytes compressed into %d bytes\n", srcLen, dstLen);
        }
        else if(st < ippStsNoErr)
        {
            printf("Error in compression function\n");
            break;
        }
        remBytes -= srcLen;
    }
EXIT_MAIN
    ippsFree(srcBuf);
    ippsFree(comprBuf);
    ippsFree(hashTable);
    return (int)st;
}