Skip to content

Commit 8bc13ba

Browse files
author
lsleonard
committed
fix bugs in td5 and td5d
1 parent d3c79cf commit 8bc13ba

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

td512.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
values of 16 to use 7-bit mode, use 6% as minimum compression for
3939
compression modes used prior to 7-bit mode.
4040
*/
41+
// Notes for version 1.1.3:
42+
/*
43+
1. Fixed bugs in td5 and td5d functions.
44+
2. Recognize random data starting at 16 input values.
45+
*/
4146

4247
#ifndef td512_h
4348
#define td512_h

td64.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ int32_t td5(const unsigned char *inVals, unsigned char *outVals, const uint32_t
8080
// inVals input data
8181
// outVals compressed data
8282
// nValues number of values to compress
83-
// returns number of bits compressed, 0 if not compressible, or -1 if error
83+
// returns number of bits compressed, 0 if not compressible, or negative value if error
8484
{
85+
outVals[0] = 1; // default uncompressed reason is general failure
8586
switch (nValues)
8687
{
8788
case 1:
@@ -221,7 +222,7 @@ int32_t td5(const unsigned char *inVals, unsigned char *outVals, const uint32_t
221222
const int32_t ival2=(unsigned char)inVals[1];
222223
const int32_t ival3=(unsigned char)inVals[2];
223224
const int32_t ival4=(unsigned char)inVals[3];
224-
if (ival1 == ival2 == ival3 == ival4)
225+
if (ival1 == ival2 && ival1 == ival3 && ival1 == ival4)
225226
{
226227
if (nValues == 4)
227228
{
@@ -230,7 +231,7 @@ int32_t td5(const unsigned char *inVals, unsigned char *outVals, const uint32_t
230231
outVals[1] = (unsigned char)ival1 >> 6;
231232
return 10;
232233
}
233-
else if ((nValues == 5) && (ival1 == inVals[4]))
234+
else if (ival1 == inVals[4])
234235
{
235236
// all 5 values equal
236237
outVals[0] = (unsigned char)(ival1 << 2) | 1;
@@ -266,7 +267,7 @@ int32_t td5(const unsigned char *inVals, unsigned char *outVals, const uint32_t
266267
int32_t otherVal=-1;
267268
if (ival2 != ival1)
268269
{
269-
otherVal=ival2;
270+
otherVal = ival2;
270271
outBits |= 2;
271272
}
272273
if (ival3 != ival1)
@@ -336,9 +337,9 @@ int32_t td5d(const unsigned char *inVals, unsigned char *outVals, const uint32_t
336337
if ((firstByte & 3) == 1)
337338
{
338339
// process single unique
339-
uint32_t unique = (firstByte >> 2) | (inVals[1] >> 6);
340+
uint32_t unique = (firstByte >> 2) | (inVals[1] << 6);
340341
memset(outVals, (unsigned char)unique, nOriginalValues);
341-
*bytesProcessed = (firstByte & 2) ? 1 : 2;
342+
*bytesProcessed = 2;
342343
return (int)nOriginalValues;
343344
}
344345
uint32_t val1;
@@ -410,7 +411,7 @@ int32_t td5d(const unsigned char *inVals, unsigned char *outVals, const uint32_t
410411
outVals[1] = (unsigned char)textChars[(firstByte>>6) | ((secondByte<<2) & 0xf)];
411412
outVals[2] = (unsigned char)textChars[(secondByte>>2) & 0xf];
412413
outVals[3] = (unsigned char)textChars[(secondByte>>6) | ((inVals[2]<<2) & 0xf)];
413-
return 3;
414+
return 4;
414415
}
415416
const int32_t thirdByte = (unsigned char)inVals[2];
416417
val1 = (unsigned char)(firstByte >> 4) | (unsigned char)(secondByte << 4);
@@ -435,7 +436,7 @@ int32_t td5d(const unsigned char *inVals, unsigned char *outVals, const uint32_t
435436
if (thirdByte & 0x4)
436437
{
437438
// fifth byte is text char
438-
outVals[4] = (unsigned char)(thirdByte >> 3) & 0xf;
439+
outVals[4] = (unsigned char)textChars[(thirdByte >> 3) & 0xf];
439440
}
440441
else
441442
{
@@ -867,7 +868,7 @@ int32_t td64(unsigned char *inVals, unsigned char *outVals, const uint32_t nValu
867868
uint32_t nUniqueVals=0; // count of unique vals encountered
868869
unsigned char val256[256]={0}; // init characters found to 0
869870
const uint32_t uniqueLimit=uniqueLimits25[nValues]; // if exceeded, return uncompressible by fixed bit coding
870-
const uint32_t nValsInitLoop=(nValues*5/16)+1;
871+
const uint32_t nValsInitLoop=nValues<24 ? nValues/2+1 : (nValues*5/16)+1; // 1-23 use 1/2 nValues, 24+ use 1/3 nValues
871872
// save uniques for use after check for text mode
872873
unsigned char saveUniques[MAX_TD64_BYTES];
873874
uint32_t textModeCalled=0; // need to restore uniques for some modes after text mode called
@@ -891,9 +892,9 @@ int32_t td64(unsigned char *inVals, unsigned char *outVals, const uint32_t nValu
891892
highBitCheck |= inVal; // keep watch on high bit of unique values
892893
}
893894
}
894-
if (nUniqueVals > uniqueLimit+1)
895+
if (nUniqueVals > uniqueLimit+1 && nValues >= MIN_VALUES_RECOGNIZE_RANDOM_DATA)
895896
{
896-
// supported unique values exceeded
897+
// supported unique values exceeded--skip this for < 16 values
897898
if ((highBitCheck & 0x80) == 0 && nValues >= MIN_VALUES_7_BIT_MODE)
898899
{
899900
// attempt to compress based on high bit clear across all values
@@ -972,7 +973,7 @@ int32_t td64(unsigned char *inVals, unsigned char *outVals, const uint32_t nValu
972973
if (textModeCalled)
973974
memcpy(outVals+1, saveUniques, textModeCalled); // restore uniques to outVals starting in second byte
974975
// max bits set to 12% if high bit clear and enough input values, else 6%
975-
uint32_t maxBits = ((highBitCheck & 0x80) == 0 && nValues >= MIN_VALUE_7_BIT_MODE_6_PERCENT) ? nValues*7 : nValues*7+nValues/2 ;
976+
uint32_t maxBits = ((highBitCheck & 0x80) == 0 && nValues >= MIN_VALUE_7_BIT_MODE_12_PERCENT) ? nValues*7 : nValues*7+nValues/2 ;
976977
if ((retBits=encodeStringMode(inVals, outVals, nValues, nUniqueVals, uniqueOccurrence, maxBits)))
977978
return retBits;
978979
}

td64.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939
values of 16 to use 7-bit mode, use 6% as minimum compression for
4040
compression modes used prior to 7-bit mode.
4141
*/
42-
42+
// Notes for version 1.1.3:
43+
/*
44+
1. Fixed bugs in td5 and td5d functions.
45+
2. Recognize random data starting at 16 input values.
46+
*/
4347
#ifndef td64_h
4448
#define td64_h
4549

@@ -55,7 +59,8 @@
5559
#define MAX_STRING_MODE_UNIQUES 32 // max uniques supported by string mode
5660
#define MIN_VALUES_STRING_MODE 32 // min values to use string mode
5761
#define MIN_VALUES_7_BIT_MODE 16
58-
#define MIN_VALUE_7_BIT_MODE_6_PERCENT 24 // min value where 7-bit mode gets 6% compression
62+
#define MIN_VALUE_7_BIT_MODE_12_PERCENT 24 // min value where 7-bit mode expected to approach 12%, otherwise 6%
63+
#define MIN_VALUES_RECOGNIZE_RANDOM_DATA 16 // skip check for random data below this number of values
5964

6065
int32_t td5(const unsigned char *inVals, unsigned char *outVals, const uint32_t nValues);
6166
int32_t td5d(const unsigned char *inVals, unsigned char *outVals, const uint32_t nOriginalValues, uint32_t *bytesProcessed);

0 commit comments

Comments
 (0)