@@ -583,18 +583,6 @@ int32_t td5d(const unsigned char *inVals, unsigned char *outVals, const uint32_t
583583 }
584584} // end td5d
585585
586- static inline void esmOutputBits (unsigned char * outVals , const uint32_t nBits , const uint32_t bitVal , uint32_t * nextOutIx , uint32_t * nextOutBit )
587- {
588- // output 1 to 8 bits
589- outVals [* nextOutIx ] |= (unsigned char )(bitVal << * nextOutBit );
590- * nextOutBit += nBits ;
591- if (* nextOutBit >= 8 )
592- {
593- * nextOutBit -= 8 ;
594- outVals [++ (* nextOutIx )] = (unsigned char )bitVal >> (nBits - * nextOutBit );
595- }
596- } // end esmOutputBits
597-
598586static uint32_t textNBitsTable [MAX_PREDEFINED_FREQUENCY_CHAR_COUNT ]= {
599587 3 , 3 , 4 , 4 ,
600588 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
@@ -704,6 +692,7 @@ int32_t encodeAdaptiveTextMode(const unsigned char *inVals, unsigned char *outVa
704692 uint32_t inVal ;
705693 uint32_t nextOutIx = 1 ;
706694 uint32_t nextOutBit = 0 ;
695+ uint64_t outBits = 0 ; // store 64 bits before writing
707696 uint32_t eVal ;
708697 const uint32_t * textEncodingArray = extendedTextEncoding ;
709698 const uint32_t output7or8 = highBitclear ? 7 : 8 ;
@@ -714,22 +703,21 @@ int32_t encodeAdaptiveTextMode(const unsigned char *inVals, unsigned char *outVa
714703 setAdaptiveChars (val256 , outVals , nValues , & textEncodingArray );
715704 if (highBitclear )
716705 outVals [0 ] |= 128 ; // set high bit of info byte to indicate 7-bit values
717- outVals [1 ] = 0 ; // init first value used by esmOutputBits
718706 while (pInVal < pLastInValPlusOne )
719707 {
720708 eVal = textEncodingArray [(inVal = (unsigned char )* (pInVal ++ ))];
721709 if (eVal < MAX_PREDEFINED_FREQUENCY_CHAR_COUNT )
722710 {
723711 // encode predefined chars and adaptive chars
724- esmOutputBits (outVals , textNBitsTable [eVal ], textBitValTable [eVal ], & nextOutIx , & nextOutBit );
712+ thisOutIx2 (outVals , textNBitsTable [eVal ], textBitValTable [eVal ], & nextOutIx , & nextOutBit , & outBits );
725713 }
726714 else
727715 {
728716 // output char not predefined or adaptive
729717 if (nextOutIx > maxBytes )
730718 return 0 ; // requested compression not met
731- esmOutputBits (outVals , 3 , 0x5 , & nextOutIx , & nextOutBit );
732- esmOutputBits (outVals , output7or8 , inVal , & nextOutIx , & nextOutBit ); // output 7 bits if high bit clear, else 8
719+ thisOutIx2 (outVals , 3 , 0x5 , & nextOutIx , & nextOutBit , & outBits );
720+ thisOutIx2 (outVals , output7or8 , inVal , & nextOutIx , & nextOutBit , & outBits ); // output 7 bits if high bit clear, else 8
733721#ifdef TD64_TEST_MODE
734722 if (textEncodingArray == extendedTextEncoding )
735723 g_td64Text8bitCount ++ ;
@@ -738,7 +726,8 @@ int32_t encodeAdaptiveTextMode(const unsigned char *inVals, unsigned char *outVa
738726#endif
739727 }
740728 }
741- return nextOutIx * 8 + nextOutBit ;
729+ esmOutputRemainder (outVals , & nextOutIx , & nextOutBit , & outBits );
730+ return nextOutIx * 8 ;
742731} // end encodeAdaptiveTextMode
743732
744733int32_t encodeSingleValueMode (const unsigned char * inVals , unsigned char * outVals , const uint32_t nValues , int32_t singleValue , const uint32_t compressNSV )
@@ -940,6 +929,7 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
940929 //uint32_t nextOutIx=nUniquesIn + 1; // start of encoding past uniques written from outer loop;
941930 uint32_t nextOutIx ; // round for now
942931 uint32_t nextOutBit = 1 ; // first bit indicates 1 or 2 uniques in first two input values
932+ uint64_t outBits ; // store 64 bits before writing
943933 const uint32_t maxBytes = maxBits /8 ; // compare against bytes out during loop
944934
945935 if (nUniquesIn > 32 || nUniquesIn < MIN_STRING_MODE_UNIQUES )
@@ -956,7 +946,6 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
956946 nextOutIx = nUniquesIn + 1 ;
957947 outVals [0 ] = 1 | (unsigned char )((nUniquesIn - 17 )<<4 ); // indicate string mode in first 3 bits, 0 for uniques uncompressed, then number uniques - 17 (excess 16 as always 17+ values) in next 4 bits
958948 }
959- outVals [nextOutIx ] = 0 ; // init for esmOutputBits
960949 // output two initial values
961950 // first unique assumed
962951 const unsigned char inVal0 = inVals [0 ];
@@ -965,15 +954,15 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
965954 // first two values are the same
966955 nUniques = 1 ;
967956 // output 1 to indicate first unique value repeated
968- outVals [ nextOutIx ] = 1 ; // 1=repeat for second value
957+ outBits = 1 ; // 1=repeat for second value
969958 twoValsPos [inVal0 ] = 1 ;
970959 }
971960 else
972961 {
973962 // second val is a new unique
974963 nUniques = 2 ;
975964 // set up position of 2nd unique
976- outVals [ nextOutIx ] = 0 ; // 0=uniques in first two values
965+ outBits = 0 ; // 0=uniques in first two values
977966 twoValsPos [inVal0 ] = 1 ;
978967 twoValsPos [inVals [1 ]] = 2 ;
979968 }
@@ -991,10 +980,11 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
991980 {
992981 // first occurrence of this unique
993982 // output a 0 to indicate new unique
994- if (++ nextOutBit == 8 )
983+ if (++ nextOutBit == 64 )
995984 {
996- // update out index and next out bit
997- outVals [++ nextOutIx ] = 0 ;
985+ // output outBits and init for next output
986+ esmOutputOutBits (outVals , & nextOutIx , & outBits );
987+ outBits = 0 ;
998988 nextOutBit = 0 ;
999989 }
1000990 twoValsPos [inVal ] = inPos ;
@@ -1008,7 +998,7 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
1008998 {
1009999 // pos of unique plus one and next input value match
10101000 // output repeated value: 01 plus unique
1011- esmOutputBits (outVals , 2 + encodingBits [nUniques - 1 ], 1 |(uoInVal <<2 ), & nextOutIx , & nextOutBit );
1001+ thisOutIx2 (outVals , 2 + encodingBits [nUniques - 1 ], 1 |(uoInVal <<2 ), & nextOutIx , & nextOutBit , & outBits );
10121002 continue ;
10131003 }
10141004 // look for continuation of matching characters
@@ -1025,22 +1015,21 @@ int32_t encodeStringMode(const unsigned char *inVals, unsigned char *outVals, co
10251015 tvPos ++ ;
10261016 }
10271017 // output 11 plus 3 more bits for string length 2 to 9
1028- esmOutputBits (outVals , 5 , 3 | ((strCount - 2 )<<2 ), & nextOutIx , & nextOutBit );
1018+ thisOutIx2 (outVals , 5 , 3 | ((strCount - 2 )<<2 ), & nextOutIx , & nextOutBit , & outBits );
10291019 // output the unique that started this string, which gives its position
1030- esmOutputBits (outVals , encodingBits [nUniques - 1 ], uoInVal , & nextOutIx , & nextOutBit );
1020+ thisOutIx2 (outVals , encodingBits [nUniques - 1 ], uoInVal , & nextOutIx , & nextOutBit , & outBits );
10311021 inPos += strCount - 1 ;
10321022 nextInVal = inVals [inPos ]; // new next val after string
10331023 }
10341024 else
10351025 {
10361026 // this pair doesn't match the one for first occurrence of this unique
10371027 // repeated value: 01
1038- esmOutputBits (outVals , 2 + encodingBits [nUniques - 1 ], 1 |(uoInVal <<2 ), & nextOutIx , & nextOutBit );
1028+ thisOutIx2 (outVals , 2 + encodingBits [nUniques - 1 ], 1 |(uoInVal <<2 ), & nextOutIx , & nextOutBit , & outBits );
10391029 }
10401030 }
1031+ esmOutputRemainder (outVals , & nextOutIx , & nextOutBit , & outBits );
10411032 // output final bits
1042- if (nextOutBit > 0 )
1043- nextOutIx ++ ; // index past final bits
10441033 if (inPos < nValues )
10451034 {
10461035 outVals [nextOutIx ++ ] = inVals [lastPos ]; // output last input byte
@@ -1524,19 +1513,19 @@ int32_t decodeAdaptiveTextMode(const unsigned char *inVals, unsigned char *outVa
15241513 {
15251514 // peak at the next 7 bits to decide what to do
15261515 dtbmPeekBits (7 , bitPos , & theBits , & dtbmThisInVal );
1527- if ((theBits & 7 ) == 5 )
1516+ if ((theBits & 7 ) != 5 )
1517+ {
1518+ // output the corresponding text char and skip corresponding number of bits
1519+ outVals [nextOutVal ++ ] = (unsigned char )pTextChars [textDecodePos [theBits ]];
1520+ dtbmSkipBits (inVals , textDecodeBits [theBits ], & thisInValIx , & bitPos , & dtbmThisInVal );
1521+ }
1522+ else
15281523 {
15291524 // skip three bits, get 7 or 8 more bits and output original value
15301525 dtbmSkipBits (inVals , 3 , & thisInValIx , & bitPos , & dtbmThisInVal );
15311526 dtbmGetBits (inVals , input7or8 , & thisInValIx , & bitPos , & theBits , & dtbmThisInVal );
15321527 outVals [nextOutVal ++ ] = (unsigned char )theBits ;
15331528 }
1534- else
1535- {
1536- // output the corresponding text char and skip corresponding number of bits
1537- outVals [nextOutVal ++ ] = (unsigned char )pTextChars [textDecodePos [theBits ]];
1538- dtbmSkipBits (inVals , textDecodeBits [theBits ], & thisInValIx , & bitPos , & dtbmThisInVal );
1539- }
15401529 }
15411530 // Process the last three values: requires at least 2 bytes (3*3) and up to 4 bytes (3*7)
15421531 uint32_t lastBits = dtbmThisInVal >>bitPos ; // next value already read
0 commit comments