4949#define LAST_MATCH_OFFSET 12
5050#define LAST_LITERALS 5
5151
52+ #define MODESWITCH_PENALTY 1
53+
5254/** One match */
5355typedef struct _lz4ultra_match {
5456 unsigned int length ;
@@ -388,14 +390,14 @@ static void lz4ultra_find_all_matches(lsza_compressor *pCompressor, const int nS
388390}
389391
390392/**
391- * Get the number of extra bytes required to represent a literals length
393+ * Get the number of extra bits required to represent a literals length
392394 *
393395 * @param nLength literals length
394396 *
395- * @return number of extra bytes required
397+ * @return number of extra bits required
396398 */
397399static inline int lz4ultra_get_literals_varlen_size (const int nLength ) {
398- return ((nLength - LITERALS_RUN_LEN + 255 ) / 255 );
400+ return ((nLength - LITERALS_RUN_LEN + 255 ) / 255 ) << 3 ;
399401}
400402
401403/**
@@ -420,14 +422,14 @@ static inline int lz4ultra_write_literals_varlen(unsigned char *pOutData, int nO
420422}
421423
422424/**
423- * Get the number of extra bytes required to represent an encoded match length
425+ * Get the number of extra bits required to represent an encoded match length
424426 *
425427 * @param nLength encoded match length (actual match length - MIN_MATCH_SIZE)
426428 *
427- * @return number of extra bytes required
429+ * @return number of extra bits required
428430 */
429431static inline int lz4ultra_get_match_varlen_size (const int nLength ) {
430- return ((nLength - MATCH_RUN_LEN + 255 ) / 255 );
432+ return ((nLength - MATCH_RUN_LEN + 255 ) / 255 ) << 3 ;
431433}
432434
433435/**
@@ -463,19 +465,21 @@ static void lz4ultra_optimize_matches(lsza_compressor *pCompressor, const int nS
463465 int nLastLiteralsOffset ;
464466 int i ;
465467
466- cost [nEndOffset - 1 ] = 1 ;
468+ cost [nEndOffset - 1 ] = 8 ;
467469 nLastLiteralsOffset = nEndOffset ;
468470
469471 for (i = nEndOffset - 2 ; i != (nStartOffset - 1 ); i -- ) {
470472 int nBestCost , nBestMatchLen , nBestMatchOffset ;
471473
472474 int nLiteralsLen = nLastLiteralsOffset - i ;
473- nBestCost = 1 + cost [i + 1 ];
475+ nBestCost = 8 + cost [i + 1 ];
474476 if (nLiteralsLen >= LITERALS_RUN_LEN && ((nLiteralsLen - LITERALS_RUN_LEN ) % 255 ) == 0 ) {
475477 /* Add to the cost of encoding literals as their number crosses a variable length encoding boundary.
476478 * The cost automatically accumulates down the chain. */
477- nBestCost ++ ;
479+ nBestCost += 8 ;
478480 }
481+ if (pCompressor -> match [(i + 1 ) << MATCHES_PER_OFFSET_SHIFT ].length >= MIN_MATCH_SIZE )
482+ nBestCost += MODESWITCH_PENALTY ;
479483 nBestMatchLen = 0 ;
480484 nBestMatchOffset = 0 ;
481485
@@ -490,8 +494,10 @@ static void lz4ultra_optimize_matches(lsza_compressor *pCompressor, const int nS
490494 if ((i + nMatchLen ) > (nEndOffset - LAST_LITERALS ))
491495 nMatchLen = nEndOffset - LAST_LITERALS - i ;
492496
493- nCurCost = 1 + 2 + lz4ultra_get_match_varlen_size (nMatchLen - MIN_MATCH_SIZE );
497+ nCurCost = 8 + 16 + lz4ultra_get_match_varlen_size (nMatchLen - MIN_MATCH_SIZE );
494498 nCurCost += cost [i + nMatchLen ];
499+ if (pCompressor -> match [(i + nMatchLen ) << MATCHES_PER_OFFSET_SHIFT ].length >= MIN_MATCH_SIZE )
500+ nCurCost += MODESWITCH_PENALTY ;
495501
496502 if (nBestCost >= nCurCost ) {
497503 nBestCost = nCurCost ;
@@ -513,8 +519,10 @@ static void lz4ultra_optimize_matches(lsza_compressor *pCompressor, const int nS
513519 for (k = MIN_MATCH_SIZE ; k < nMatchRunLen ; k ++ ) {
514520 int nCurCost ;
515521
516- nCurCost = 1 + 2 /* no extra match len bytes */ ;
522+ nCurCost = 8 + 16 /* no extra match len bytes */ ;
517523 nCurCost += cost [i + k ];
524+ if (pCompressor -> match [(i + k ) << MATCHES_PER_OFFSET_SHIFT ].length >= MIN_MATCH_SIZE )
525+ nCurCost += MODESWITCH_PENALTY ;
518526
519527 if (nBestCost >= nCurCost ) {
520528 nBestCost = nCurCost ;
@@ -526,8 +534,10 @@ static void lz4ultra_optimize_matches(lsza_compressor *pCompressor, const int nS
526534 for (; k <= nMatchLen ; k ++ ) {
527535 int nCurCost ;
528536
529- nCurCost = 1 + 2 + lz4ultra_get_match_varlen_size (k - MIN_MATCH_SIZE );
537+ nCurCost = 8 + 16 + lz4ultra_get_match_varlen_size (k - MIN_MATCH_SIZE );
530538 nCurCost += cost [i + k ];
539+ if (pCompressor -> match [(i + k ) << MATCHES_PER_OFFSET_SHIFT ].length >= MIN_MATCH_SIZE )
540+ nCurCost += MODESWITCH_PENALTY ;
531541
532542 if (nBestCost >= nCurCost ) {
533543 nBestCost = nCurCost ;
@@ -569,10 +579,10 @@ static void lz4ultra_optimize_command_count(lsza_compressor *pCompressor, const
569579 if (nMatchLen <= 19 && (i + nMatchLen ) < nEndOffset ) {
570580 int nMatchOffset = pMatch -> offset ;
571581 int nEncodedMatchLen = nMatchLen - MIN_MATCH_SIZE ;
572- int nCommandSize = 1 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + 2 /* match offset */ + lz4ultra_get_match_varlen_size (nEncodedMatchLen );
582+ int nCommandSize = 8 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + 16 /* match offset */ + lz4ultra_get_match_varlen_size (nEncodedMatchLen );
573583
574584 if (pCompressor -> match [(i + nMatchLen ) << MATCHES_PER_OFFSET_SHIFT ].length >= MIN_MATCH_SIZE ) {
575- if (nCommandSize >= (nMatchLen + lz4ultra_get_literals_varlen_size (nNumLiterals + nMatchLen ))) {
585+ if (nCommandSize >= (( nMatchLen << 3 ) + lz4ultra_get_literals_varlen_size (nNumLiterals + nMatchLen ))) {
576586 /* This command is a match; the next command is also a match. The next command currently has no literals; replacing this command by literals will
577587 * make the next command eat the cost of encoding the current number of literals, + nMatchLen extra literals. The size of the current match command is
578588 * at least as much as the number of literal bytes + the extra cost of encoding them in the next match command, so we can safely replace the current
@@ -589,7 +599,7 @@ static void lz4ultra_optimize_command_count(lsza_compressor *pCompressor, const
589599 nNextNumLiterals ++ ;
590600 } while (nCurIndex < nEndOffset && pCompressor -> match [nCurIndex << MATCHES_PER_OFFSET_SHIFT ].length < MIN_MATCH_SIZE );
591601
592- if (nCommandSize >= (nMatchLen + lz4ultra_get_literals_varlen_size (nNumLiterals + nNextNumLiterals + nMatchLen ) - lz4ultra_get_literals_varlen_size (nNextNumLiterals ))) {
602+ if (nCommandSize >= (( nMatchLen << 3 ) + lz4ultra_get_literals_varlen_size (nNumLiterals + nNextNumLiterals + nMatchLen ) - lz4ultra_get_literals_varlen_size (nNextNumLiterals ))) {
593603 /* This command is a match, and is followed by literals, and then another match or the end of the input data. If encoding this match as literals doesn't take
594604 * more room than the match, and doesn't grow the next match command's literals encoding, go ahead and remove the command. */
595605 nReduce = 1 ;
@@ -655,9 +665,9 @@ static int lz4ultra_write_block(lsza_compressor *pCompressor, const unsigned cha
655665 int nEncodedMatchLen = nMatchLen - MIN_MATCH_SIZE ;
656666 int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN ) ? LITERALS_RUN_LEN : nNumLiterals ;
657667 int nTokenMatchLen = (nEncodedMatchLen >= MATCH_RUN_LEN ) ? MATCH_RUN_LEN : nEncodedMatchLen ;
658- int nCommandSize = 1 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + nNumLiterals + 2 /* match offset */ + lz4ultra_get_match_varlen_size (nEncodedMatchLen );
668+ int nCommandSize = 8 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + ( nNumLiterals << 3 ) + 16 /* match offset */ + lz4ultra_get_match_varlen_size (nEncodedMatchLen );
659669
660- if ((nOutOffset + nCommandSize ) > nMaxOutDataSize )
670+ if ((nOutOffset + ( nCommandSize >> 3 ) ) > nMaxOutDataSize )
661671 return -1 ;
662672 if (nMatchOffset < MIN_OFFSET || nMatchOffset > MAX_OFFSET )
663673 return -1 ;
@@ -688,9 +698,9 @@ static int lz4ultra_write_block(lsza_compressor *pCompressor, const unsigned cha
688698
689699 {
690700 int nTokenLiteralsLen = (nNumLiterals >= LITERALS_RUN_LEN ) ? LITERALS_RUN_LEN : nNumLiterals ;
691- int nCommandSize = 1 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + nNumLiterals ;
701+ int nCommandSize = 8 /* token */ + lz4ultra_get_literals_varlen_size (nNumLiterals ) + ( nNumLiterals << 3 ) ;
692702
693- if ((nOutOffset + nCommandSize ) > nMaxOutDataSize )
703+ if ((nOutOffset + ( nCommandSize >> 3 ) ) > nMaxOutDataSize )
694704 return -1 ;
695705
696706 pOutData [nOutOffset ++ ] = (nTokenLiteralsLen << 4 );
0 commit comments