📄 ippcompress.c
字号:
if( ippStsNoErr != ( st = ippsDecodeHuffInitAlloc_8u( codeLenTable, &pMyHuffState ) ) ) {
fprintf(stderr, "Error <%d> while decoding Huffman (Init)\n", st);
return st;
}
/* decodes using Huffman */
if( ippStsNoErr != ( st = ippsDecodeHuff_8u( pSrc + tmpLen, (SrcLen - tmpLen), pDst, pDstLen, pMyHuffState ) ) ) {
fprintf(stderr, "Error <%d> while decoding HUFFMAN\n", st);
return st;
}
ippsHuffFree_8u( pMyHuffState );
return ippStsNoErr;
}
/*************************************************************************************************
* Function:
* IppStatus EncodeHuffman( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen )
*
* Function for relization of Huffman Encoding
* Gets the pSrc as a source vector of length SrcLen, does Huffman encoding and
* writes result to pDst ( and length of pDst in pDstLen )
*
* Main Parameters:
* pSrc - pointer to Source buffer,
* pDst - pointer to Destination buffer,
* SrcLen - Length of source buffer,
* pDstLen - Length of destination buffer
*
* Returns:
* ippStsNullPtrErr If One or several pointer(s) is NULL
* ippStsSizeErr Length of the source vector is less or equal zero
* ippStsNoErr No errors
*
************************************************************************************************/
IppStatus EncodeHuffman( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen) {
int freqHuffman[256]; /* here we will store the frequencies for source vector */
int codeLenTable[256]; /* this is for the huffman codelength table */
int dstBuffSize = *pDstLen;
int i, counter = 0; /* loop counter */
IppHuffState_8u * pMyHuffState;
IppStatus st; /* variable where data about result will be stored */
/* checks the pointer is not null */
if( NULL == pSrc || NULL == pDst )
return ippStsNullPtrErr;
/* calculates the code frequencies for input block
zero all the frequencies */
for( i=0; i <= 255; i++ )
freqHuffman[i] = 1;
/* init the table */
while( counter <= SrcLen ) {
freqHuffman[(pSrc[counter])] += 1;
counter += 1;
}
/* Init structure for huffman and automatically allocate memory for it */
if( ippStsNoErr != ( st = ippsEncodeHuffInitAlloc_8u( freqHuffman, &pMyHuffState ) ) ) {
fprintf( stderr, "Error while trying to init the frequency table for huffman. Exiting.\n" );
return st;
}
/* gets the table with huffman codes length */
if( ippStsNoErr != ( st = ippsHuffGetLenCodeTable_8u( codeLenTable, pMyHuffState ) ) ) {
fprintf( stderr, "Error while trying to get the code length 4 huffman. Exiting.\n" );
return st;
}
/* Packs the lengths of Huffman table */
if( ippStsNoErr != ( st = ippsHuffLenCodeTablePack_8u( codeLenTable, pDst, &dstBuffSize ) ) ) {
fprintf( stderr, "Error <%d> while trying to flush code lengths. Exiting.\n", st );
return st;
}
/* increments the value of bytes encoded */
*pDstLen = dstBuffSize;
/* Encodes using Huffman encoding */
if( ippStsNoErr != ( st = ippsEncodeHuff_8u( pSrc, SrcLen, pDst + (*pDstLen), &dstBuffSize, pMyHuffState ) ) ) {
fprintf( stderr, "Error <%d> while trying to encode huffman. Exiting.\n", st );
return st;
}
/* increment the value of bytes encoded */
*pDstLen += dstBuffSize;
/* do the final flush of huffman */
if( ippStsNoErr != ( st = ippsEncodeHuffFinal_8u( pDst + (*pDstLen), &dstBuffSize, pMyHuffState ) ) ) {
fprintf( stderr, "Error <%d> while trying to finalize ecoding huffman. Exiting.\n", st);
return st;
}
/* increment the value of bytes encoded */
*pDstLen += dstBuffSize;
ippsHuffFree_8u( pMyHuffState );
return ippStsNoErr; /* No Errors */
}
/*************************************************************************************************
* Function:
* IppStatus EncodeGIT( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen )
*
* Function for relization of General Interval Transform
* Gets the pSrc as a source vector of length SrcLen, does GIT and
* writes result to pDst ( and length of pDst in pDstLen )
*
* Main Parameters:
* pSrc - pointer to Source buffer,
* pDst - pointer to Destination buffer,
* SrcLen - Length of source buffer,
* pDstLen - Length of destination buffer
*
* Returns:
* ippStsNullPtrErr If One or several pointer(s) is NULL
* ippStsSizeErr Length of the source vector is less or equal zero
* ippStsNoErr No errors
*
************************************************************************************************/
IppStatus EncodeGIT( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen ) {
IppStatus st;
if( ippStsNoErr != ( st = ippsEncodeGIT_8u( pSrc, SrcLen, pDst, pDstLen, strategyHint, pGITState ) ) ) {
fprintf( stderr, "Error <%d> while trying GIT (main). Exiting.\n", st );
return st;
}
return ippStsNoErr;
}
/*************************************************************************************************
* Function:
* IppStatus DecodeGIT( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen )
*
* Function for relization of backward General Interval Transform
* Gets the pSrc as a source vector of length SrcLen, does GIT and
* writes result to pDst ( and length of pDst in pDstLen )
*
* Main Parameters:
* pSrc - pointer to Source buffer,
* pDst - pointer to Destination buffer,
* SrcLen - Length of source buffer,
* pDstLen - Length of destination buffer
*
* Returns:
* ippStsNullPtrErr If One or several pointer(s) is NULL
* ippStsSizeErr Length of the source vector is less or equal zero
* ippStsNoErr No errors
*
************************************************************************************************/
IppStatus DecodeGIT( Ipp8u * pSrc, int SrcLen, Ipp8u *pDst, int *pDstLen ) {
IppStatus st;
if( ippStsNoErr != ( st = ippsDecodeGIT_8u( pSrc, SrcLen, pDst, pDstLen, strategyHint, pGITState ) ) ) {
fprintf( stderr, "Error <%d> while trying decode GIT. Exiting.\n", st );
return st;
}
return ippStsNoErr;
}
int main(int argc, char **argv) {
/* variables */
int i = 0; /* loop counter */
int blocksize = 0;
int bwtsize = 0;
int dstLen = 0;
int bwtLen = 0;
int mtfLen = 0;
int rleLen = 0;
int hufLen = 0;
int gitLen = 0;
int bytesReaded = 0;
int bytesEncoded = 0;
int bytesWrited = 0;
int bytesDecoded = 0;
int caseofwork = 0;
int wayofwork = 0;
/* input and output files descriptors */
FILE * fi = NULL,
* fo = NULL,
* f_t = NULL; // temp
gzFile gzfile = NULL;
IppStatus st = ippStsNoErr;
Ipp8u * pSrc = NULL,
* pDst = NULL,
* srcBuff = NULL,
* dstBuff = NULL,
* pTmp = NULL;
Ipp8u * header = (Ipp8u *)ippMalloc( 4 );
if( argc < 3 ) { usage(argv[0]); exit(1); } /* error: no parameters - outputs usage string */
if( ippStaticInit() < 0 ) {
fprintf( stderr, "Can't init IPP libraries. Exiting.\n");
exit(-1);
}
blocksize = DEFAULTBLOCKSIZE;
strategyHint = ippGITLeftReorder;
/* assume, that command-line is the following:
ippcompress.exe {methodnumber} {e|d} sf {source_file_name} df {dest_file_name} b {blocksize} sh {strategy_hint}
*/
if( argv[1][0] == '-' )
wayofwork = (int)(argv[1][1] - 48 ); /* method number */
else
wayofwork = (int)(argv[1][0] - 48 ); /* method number */
if( wayofwork < 1 || wayofwork > 4 ) goto err;
if( argv[2][0] == '-' )
caseofwork = ( argv[2][1] );
else
caseofwork = ( argv[2][0] );
if( caseofwork != 'e' && caseofwork !='d' ) goto err;
if( NULL == ( fi = fopen( argv[4], "rb" ) ) ) {
fprintf( stderr, "Error while reading source file!\n" );
exit(1);
}
/* in case we using LZ77 we have to use another file-opening method when decompression case takes place */
if( wayofwork == 4 && caseofwork == 'd' ) {
if( NULL == ( gzfile = gzopen( argv[4], "rb" ) ) ) {
fprintf(stderr, "Error while reading source file file!\n");
exit(11);
}
}
/* check 4 presence of output file name */
if( NULL == ( fo = fopen( argv[6], "w+b" ) ) ) {
fprintf(stderr, "Error while writing destination file!\n");
exit(1);
}
if( wayofwork == 4 && caseofwork == 'e' ) {
if( NULL == ( gzfile = gzopen( argv[6], "wb1" ) ) ) {
fprintf(stderr, "Error while writing destination file!\n");
exit(1);
}
}
if( argv[7] != NULL ) {
if( caseofwork == 'e' && ( argv[7][0] == 'b' || ( argv[7][0] == '-' && argv[7][1] == 'b' ) ) ) {
/* in case, when user tries to set the block length (in Kbytes) */
if( ( argv[8][0] - 48 ) <= 9 && ( argv[8][0] - 48 ) >= 1 ) {
blocksize = BLOCKUNIT * (int)( argv[8][0] - 48 );
if( blocksize < 2 )
blocksize += 1;
} else {
fprintf( stderr, "Choice another block size ( from (1)00 till (9)00 kbytes)\n");
exit(121); /* Error code invalid blocksize */
}
if( argv[9] != NULL ) {
if( ( argv[9][0] == 's' && argv[9][1] == 'h' ) || ( argv[9][0] == '-' && argv[9][1] == 's' && argv[9][2] == 'h' ) ) {
switch ( argv[10][0] ) {
case 'n':
strategyHint = ippGITNoStrategy; break;
case 'r':
strategyHint = ippGITRightReorder; break;
case 'l':
strategyHint = ippGITLeftReorder; break;
case 'f':
strategyHint = ippGITFixedOrder; break;
}
}
}
}
else if( ( argv[7][0] == 's' && argv[7][1] == 'h' ) || ( argv[7][0] == '-' && argv[7][1] == 's' && argv[7][2] == 'h' ) ) {
switch ( argv[8][0] ) {
case 'n':
strategyHint = ippGITNoStrategy; break;
case 'r':
strategyHint = ippGITRightReorder; break;
case 'l':
strategyHint = ippGITLeftReorder; break;
case 'f':
strategyHint = ippGITFixedOrder; break;
}
}
}
if( caseofwork == 'e' && wayofwork == 4 )
blocksize = ZLIBBLOCKSIZE;
/* switch the case of work from the first argument in command line */
switch( caseofwork ) {
case 'e': /* encoding case */
/* allocate memort 4 the source buffer */
srcBuff = (Ipp8u *)ippMalloc( ( DEFAULTBLOCKSIZE << 1 ) * sizeof(Ipp8u) );
dstBuff = (Ipp8u *)ippMalloc( ( DEFAULTBLOCKSIZE << 1 ) * sizeof(Ipp8u) );
pSrc = srcBuff;
pDst = dstBuff;
/* does the method specific allocations .. */
switch( wayofwork ) {
case 1: /* bwt->mtf->rle->huffman */
/* allocation of additional buffer for BWT */
if( ippStsNoErr != ( st = ippsBWTFwdGetSize_8u( DEFAULTBLOCKSIZE, &bwtsize ) ) )
return st;
addBuff = (Ipp8u *)ippMalloc( bwtsize );
if( NULL == addBuff )
return ippStsNullPtrErr;
/* allocates the memory needed for MTF transformation structure */
if( ippStsNoErr != ( st = ippsMTFInitAlloc_8u( &pMyMTF ) ) )
return st;
while( ( bytesReaded = readBlockFromFile( fi, &srcBuff, blocksize ) ) > 0 ) {
bytesEncoded = DEFAULTBLOCKSIZE;
mtfLen = DEFAULTBLOCKSIZE;
rleLen = DEFAULTBLOCKSIZE;
hufLen = DEFAULTBLOCKSIZE;
if( ippStsNoErr != ( st = DoTheForwardBWT( srcBuff, bytesReaded, dstBuff, &bwtLen ) ) ) {
fprintf(stderr, "Error <%d> while trying forward BWT Transformation. Exiting.\n", st );
return st;
}
EXCHANGEBUFFERS( srcBuff, dstBuff );
if( ippStsNoErr != ( st = DoTheForwardMTF( srcBuff, bwtLen, dstBuff, &mtfLen ) ) ) {
fprintf(stderr, "Error <%d> while trying forward MTF Transformation. Exiting.\n", st );
return st;
}
EXCHANGEBUFFERS( srcBuff, dstBuff );
if( ippStsNoErr != ( st = EncodeRLE( srcBuff, mtfLen, dstBuff, &rleLen ) ) ) {
fprintf(stderr, "Error <%d> while trying to encode RLE. Exiting.\n", st );
return st;
}
EXCHANGEBUFFERS( srcBuff, dstBuff );
if( ippStsNoErr != ( st = EncodeHuffman( srcBuff, rleLen, dstBuff, &bytesEncoded ) ) ) {
fprintf(stderr, "Error <%d> while trying to encode Huffman. Exiting.\n", st );
return st;
}
/* converts the size of encoded block (int) to the 4 byte (Ipp8u) */
((int*)header)[0] = bytesEncoded;
/* writes the 4 bytes (block length) into output file */
bytesWrited = writeBlockToFile( fo, header, sizeof(int) );
/* writes the (block length) bytes into output file */
bytesWrited = writeBlockToFile( fo, dstBuff, bytesEncoded );
}
fclose(fi);
fclose(fo);
break;
case 2: /* bwt->git */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -