mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
Add in sigbits decoding functions
This commit is contained in:
parent
53f90321e5
commit
9d32782984
@ -313,12 +313,12 @@ test_sigbits_encoding()
|
||||
01100000 `
|
||||
*/
|
||||
bytes = "abc";
|
||||
common8 = pc_sigbits_8(bytes, strlen(bytes), &count);
|
||||
common8 = pc_sigbits_count_8(bytes, strlen(bytes), &count);
|
||||
CU_ASSERT_EQUAL(count, 6);
|
||||
CU_ASSERT_EQUAL(common8, '`');
|
||||
|
||||
bytes = "abcdef";
|
||||
common8 = pc_sigbits_8(bytes, strlen(bytes), &count);
|
||||
common8 = pc_sigbits_count_8(bytes, strlen(bytes), &count);
|
||||
CU_ASSERT_EQUAL(count, 5);
|
||||
CU_ASSERT_EQUAL(common8, '`');
|
||||
|
||||
@ -329,14 +329,8 @@ test_sigbits_encoding()
|
||||
0110000000000000 24576
|
||||
*/
|
||||
bytes = "aabbcc";
|
||||
common16 = pc_sigbits_16(bytes, strlen(bytes)/2, &count);
|
||||
count = pc_sigbits_count(bytes, PC_UINT16, strlen(bytes)/2);
|
||||
CU_ASSERT_EQUAL(count, 6);
|
||||
CU_ASSERT_EQUAL(common16, 24576);
|
||||
|
||||
// bytes = "aaaabaaacaaadaaaeaaafaaa";
|
||||
// common32 = pc_sigbits_32(bytes, strlen(bytes)/4, &count);
|
||||
// CU_ASSERT_EQUAL(count, 29);
|
||||
// CU_ASSERT_EQUAL(common32, 1633771872);
|
||||
|
||||
/*
|
||||
"abca" encoded:
|
||||
@ -351,6 +345,7 @@ test_sigbits_encoding()
|
||||
CU_ASSERT_EQUAL(ebytes[3], 109); /* packed byte */
|
||||
CU_ASSERT_EQUAL(ebytes[4], 110); /* packed byte */
|
||||
CU_ASSERT_EQUAL(ebytes[5], 111); /* packed byte */
|
||||
pcfree(ebytes);
|
||||
|
||||
/*
|
||||
"abca" encoded:
|
||||
@ -364,6 +359,16 @@ test_sigbits_encoding()
|
||||
CU_ASSERT_EQUAL(ebytes[2], 41); /* packed byte */
|
||||
CU_ASSERT_EQUAL(ebytes[3], 194); /* packed byte */
|
||||
|
||||
bytes = pc_bytes_sigbits_decode(ebytes, PC_INT8, strlen(bytes));
|
||||
CU_ASSERT_EQUAL(bytes[0], 'a');
|
||||
CU_ASSERT_EQUAL(bytes[1], 'b');
|
||||
CU_ASSERT_EQUAL(bytes[2], 'c');
|
||||
CU_ASSERT_EQUAL(bytes[3], 'd');
|
||||
CU_ASSERT_EQUAL(bytes[4], 'a');
|
||||
CU_ASSERT_EQUAL(bytes[5], 'b');
|
||||
pcfree(bytes);
|
||||
pcfree(ebytes);
|
||||
|
||||
/*
|
||||
0110000101100001 24929
|
||||
0110000101100010 24930
|
||||
@ -382,16 +387,28 @@ test_sigbits_encoding()
|
||||
bytes16[4] = 24933;
|
||||
bytes16[5] = 24934;
|
||||
|
||||
uint32_t commonbits;
|
||||
common16 = pc_sigbits_16((uint8_t*)bytes16, 6, &commonbits);
|
||||
common16 = pc_sigbits_count_16((uint8_t*)bytes16, 6, &count);
|
||||
CU_ASSERT_EQUAL(common16, 24928);
|
||||
CU_ASSERT_EQUAL(commonbits, 13);
|
||||
CU_ASSERT_EQUAL(count, 13);
|
||||
ebytes = pc_bytes_sigbits_encode((uint8_t*)bytes16, PC_INT16, 6, &ebytes_size);
|
||||
pcfree(bytes16);
|
||||
ebytes16 = (uint16_t*)ebytes;
|
||||
// printf("commonbits %d\n", commonbits);
|
||||
CU_ASSERT_EQUAL(ebytes16[0], 3); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes16[1], 24928); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes16[2], 10699); /* packed uint16 one */
|
||||
|
||||
/* uint8_t* pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems) */
|
||||
bytes = pc_bytes_sigbits_decode(ebytes, PC_INT16, 6);
|
||||
bytes16 = (uint16_t*)bytes;
|
||||
CU_ASSERT_EQUAL(bytes16[0], 24929);
|
||||
CU_ASSERT_EQUAL(bytes16[1], 24930);
|
||||
CU_ASSERT_EQUAL(bytes16[2], 24931);
|
||||
CU_ASSERT_EQUAL(bytes16[3], 24932);
|
||||
CU_ASSERT_EQUAL(bytes16[4], 24933);
|
||||
CU_ASSERT_EQUAL(bytes16[5], 24934);
|
||||
pcfree(ebytes);
|
||||
pcfree(bytes);
|
||||
}
|
||||
|
||||
/* REGISTER ***********************************************************/
|
||||
|
||||
@ -96,11 +96,14 @@ uint8_t* pc_bytes_run_length_decode(const uint8_t *bytes_rle, size_t bytes_rle_s
|
||||
/** How many bits are shared by all elements of this array? */
|
||||
uint32_t pc_signbits_count(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems);
|
||||
|
||||
uint8_t pc_sigbits_8 (const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint16_t pc_sigbits_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint32_t pc_sigbits_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint64_t pc_sigbits_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint8_t pc_sigbits_count_8 (const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint16_t pc_sigbits_count_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint32_t pc_sigbits_count_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
uint64_t pc_sigbits_count_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits);
|
||||
|
||||
uint8_t* pc_bytes_sigbits_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems, size_t *bytes_sigbits_size);
|
||||
|
||||
uint8_t* pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems);
|
||||
|
||||
|
||||
#endif /* _PC_API_INTERNAL_H */
|
||||
@ -152,15 +152,8 @@ pc_bytes_run_length_decode(const uint8_t *bytes_rle, size_t bytes_rle_size, uint
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t
|
||||
pc_sigbits_8(const uint8_t *bytes, uint32_t nelems, uint32_t *nsigbits)
|
||||
pc_sigbits_count_8(const uint8_t *bytes, uint32_t nelems, uint32_t *nsigbits)
|
||||
{
|
||||
static uint8_t nbits = 8;
|
||||
uint8_t elem_and = bytes[0];
|
||||
@ -186,7 +179,7 @@ pc_sigbits_8(const uint8_t *bytes, uint32_t nelems, uint32_t *nsigbits)
|
||||
}
|
||||
|
||||
uint16_t
|
||||
pc_sigbits_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
pc_sigbits_count_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
{
|
||||
static int nbits = 16;
|
||||
uint16_t *bytes = (uint16_t*)bytes8;
|
||||
@ -213,7 +206,7 @@ pc_sigbits_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pc_sigbits_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
pc_sigbits_count_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
{
|
||||
static int nbits = 32;
|
||||
uint32_t *bytes = (uint32_t*)bytes8;
|
||||
@ -240,7 +233,7 @@ pc_sigbits_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
}
|
||||
|
||||
uint64_t
|
||||
pc_sigbits_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
pc_sigbits_count_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
{
|
||||
static int nbits = 64;
|
||||
uint64_t *bytes = (uint64_t*)bytes8;
|
||||
@ -266,85 +259,38 @@ pc_sigbits_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits)
|
||||
return elem_and;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* How many bits are shared by all elements of this array?
|
||||
*/
|
||||
uint32_t
|
||||
pc_sigbits_count(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems)
|
||||
{
|
||||
int i, j, start, end, incr;
|
||||
const uint8_t *bytes_ptr;
|
||||
uint8_t bytes_and[8];
|
||||
uint8_t bytes_or[8];
|
||||
uint8_t bytes_sig[8];
|
||||
size_t size = INTERPRETATION_SIZES[interpretation];
|
||||
uint32_t count = 0;
|
||||
|
||||
memset(bytes_sig, 0, 8);
|
||||
memset(bytes_and, 0, 8);
|
||||
memset(bytes_or, 0, 8);
|
||||
memcpy(bytes_and, bytes, size);
|
||||
memcpy(bytes_or, bytes, size);
|
||||
|
||||
/* Figure out the global "and" and "or" of all the values */
|
||||
for ( i = 1; i < nelems; i++ )
|
||||
{
|
||||
bytes_ptr = bytes + i*size;
|
||||
for ( j = 0; j < size; j++ )
|
||||
{
|
||||
bytes_and[j] &= bytes_ptr[j];
|
||||
bytes_or[j] |= bytes_ptr[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* Count down the bytes for little-endian, up for big */
|
||||
if ( machine_endian() == PC_NDR )
|
||||
{
|
||||
start = size-1;
|
||||
end = -1;
|
||||
incr = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = 0;
|
||||
end = size;
|
||||
incr = 1;
|
||||
}
|
||||
|
||||
for ( i = start; i != end; i += incr )
|
||||
{
|
||||
/* If bytes are the same, all 8 bits are shared! */
|
||||
if ( bytes_and[i] == bytes_or[i] )
|
||||
{
|
||||
count += 8;
|
||||
bytes_sig[i] = bytes_and[i];
|
||||
}
|
||||
/* If bytes are different, find if they share any top bits */
|
||||
else
|
||||
{
|
||||
int commonbits = 8;
|
||||
uint8_t b_and = bytes_and[i];
|
||||
uint8_t b_or = bytes_or[i];
|
||||
|
||||
/* Slide off bottom bits until the values match */
|
||||
while ( b_and != b_or )
|
||||
{
|
||||
b_and >>= 1;
|
||||
b_or >>= 1;
|
||||
commonbits -= 1;
|
||||
}
|
||||
count += commonbits;
|
||||
|
||||
/* Save the common bits to the significant bit value */
|
||||
b_and <<= 8 - commonbits;
|
||||
bytes_sig[i] = b_and;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
size_t size = INTERPRETATION_SIZES[interpretation];
|
||||
uint32_t nbits = -1;
|
||||
switch ( size )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint8_t commonvalue = pc_sigbits_count_8(bytes, nelems, &nbits);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
uint16_t commonvalue = pc_sigbits_count_16(bytes, nelems, &nbits);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
uint16_t commonvalue = pc_sigbits_count_32(bytes, nelems, &nbits);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("Uh oh");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return nbits;
|
||||
}
|
||||
|
||||
|
||||
@ -375,9 +321,9 @@ pc_bytes_sigbits_encode_8(const uint8_t *bytes, uint32_t nelems, uint8_t commonv
|
||||
int bit = bitwidth;
|
||||
|
||||
/* Number of unique bits goes up front */
|
||||
*byte_ptr++ = nbits;
|
||||
*byte_ptr = nbits; byte_ptr++;
|
||||
/* The common value we'll add the unique values to */
|
||||
*byte_ptr++ = commonvalue;
|
||||
*byte_ptr = commonvalue; byte_ptr++;
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
@ -451,9 +397,9 @@ pc_bytes_sigbits_encode_16(const uint8_t *bytes8, uint32_t nelems, uint16_t comm
|
||||
int bit = bitwidth;
|
||||
|
||||
/* Number of unique bits goes up front */
|
||||
*byte_ptr++ = nbits;
|
||||
*byte_ptr = nbits; byte_ptr++;
|
||||
/* The common value we'll add the unique values to */
|
||||
*byte_ptr++ = commonvalue;
|
||||
*byte_ptr = commonvalue; byte_ptr++;
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
@ -527,9 +473,9 @@ pc_bytes_sigbits_encode_32(const uint8_t *bytes8, uint32_t nelems, uint32_t comm
|
||||
int bit = bitwidth;
|
||||
|
||||
/* Number of unique bits goes up front */
|
||||
*byte_ptr++ = nbits;
|
||||
*byte_ptr = nbits; byte_ptr++;
|
||||
/* The common value we'll add the unique values to */
|
||||
*byte_ptr++ = commonvalue;
|
||||
*byte_ptr = commonvalue; byte_ptr++;
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
@ -591,17 +537,17 @@ pc_bytes_sigbits_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint8_t commonvalue = pc_sigbits_8(bytes, nelems, &nbits);
|
||||
uint8_t commonvalue = pc_sigbits_count_8(bytes, nelems, &nbits);
|
||||
return pc_bytes_sigbits_encode_8(bytes, nelems, commonvalue, nbits, ebytes_size);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
uint16_t commonvalue = pc_sigbits_16(bytes, nelems, &nbits);
|
||||
uint16_t commonvalue = pc_sigbits_count_16(bytes, nelems, &nbits);
|
||||
return pc_bytes_sigbits_encode_16(bytes, nelems, commonvalue, nbits, ebytes_size);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
uint16_t commonvalue = pc_sigbits_32(bytes, nelems, &nbits);
|
||||
uint16_t commonvalue = pc_sigbits_count_32(bytes, nelems, &nbits);
|
||||
return pc_bytes_sigbits_encode_32(bytes, nelems, commonvalue, nbits, ebytes_size);
|
||||
}
|
||||
default:
|
||||
@ -614,7 +560,190 @@ pc_bytes_sigbits_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
static uint8_t *
|
||||
pc_bytes_sigbits_decode_8(const uint8_t *bytes, uint32_t nelems)
|
||||
{
|
||||
}
|
||||
int i;
|
||||
const uint8_t *bytes_ptr = bytes;
|
||||
uint8_t nbits;
|
||||
uint8_t commonvalue;
|
||||
uint8_t mask;
|
||||
int bit = 8;
|
||||
uint8_t *outbytes = pcalloc(sizeof(uint8_t) * nelems);
|
||||
uint8_t *obytes = (uint8_t*)outbytes;
|
||||
|
||||
/* How many unique bits? */
|
||||
nbits = *bytes_ptr; bytes_ptr++;
|
||||
/* What is the shared bit value? */
|
||||
commonvalue = *bytes_ptr; bytes_ptr++;
|
||||
/* Mask for just the unique parts */
|
||||
mask = (0xFF >> (bit-nbits));
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
int shift = bit - nbits;
|
||||
uint8_t val = *bytes_ptr;
|
||||
/* The unique part is all in this word */
|
||||
if ( shift >= 0 )
|
||||
{
|
||||
/* Push unique part to bottom of word */
|
||||
val >>= shift;
|
||||
/* Mask out any excess */
|
||||
val &= mask;
|
||||
/* Add in the common part */
|
||||
val |= commonvalue;
|
||||
/* Save */
|
||||
obytes[i] = val;
|
||||
/* Move read head */
|
||||
bit -= nbits;
|
||||
}
|
||||
/* The unique part is split over this word and the next */
|
||||
else
|
||||
{
|
||||
int s = abs(shift);
|
||||
val <<= s;
|
||||
val &= mask;
|
||||
val |= commonvalue;
|
||||
obytes[i] = val;
|
||||
bytes_ptr++;
|
||||
bit = 8;
|
||||
val = *bytes_ptr;
|
||||
shift = bit - s;
|
||||
val >>= shift;
|
||||
val &= mask;
|
||||
obytes[i] |= val;
|
||||
bit -= s;
|
||||
}
|
||||
}
|
||||
return outbytes;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
pc_bytes_sigbits_decode_16(const uint8_t *bytes, uint32_t nelems)
|
||||
{
|
||||
int i;
|
||||
const uint16_t *bytes_ptr = (const uint16_t *)bytes;
|
||||
uint16_t nbits;
|
||||
uint16_t commonvalue;
|
||||
uint16_t mask;
|
||||
int bit = 16;
|
||||
uint8_t *outbytes = pcalloc(sizeof(uint16_t) * nelems);
|
||||
uint16_t *obytes = (uint16_t*)outbytes;
|
||||
|
||||
/* How many unique bits? */
|
||||
nbits = *bytes_ptr; bytes_ptr++;
|
||||
/* What is the shared bit value? */
|
||||
commonvalue = *bytes_ptr; bytes_ptr++;
|
||||
/* Calculate mask */
|
||||
mask = (0xFFFF >> (bit-nbits));
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
int shift = bit - nbits;
|
||||
uint16_t val = *bytes_ptr;
|
||||
if ( shift >= 0 )
|
||||
{
|
||||
val >>= shift;
|
||||
val &= mask;
|
||||
val |= commonvalue;
|
||||
obytes[i] = val;
|
||||
bit -= nbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = abs(shift);
|
||||
val <<= s;
|
||||
val &= mask;
|
||||
val |= commonvalue;
|
||||
obytes[i] = val;
|
||||
bytes_ptr++;
|
||||
bit = 16;
|
||||
val = *bytes_ptr;
|
||||
shift = bit - s;
|
||||
val >>= shift;
|
||||
val &= mask;
|
||||
obytes[i] |= val;
|
||||
bit -= s;
|
||||
}
|
||||
}
|
||||
return outbytes;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
pc_bytes_sigbits_decode_32(const uint8_t *bytes, uint32_t nelems)
|
||||
{
|
||||
int i;
|
||||
const uint32_t *bytes_ptr = (const uint32_t *)bytes;
|
||||
uint32_t nbits;
|
||||
uint32_t commonvalue;
|
||||
uint32_t mask;
|
||||
int bit = 32;
|
||||
uint8_t *outbytes = pcalloc(sizeof(uint32_t) * nelems);
|
||||
uint32_t *obytes = (uint32_t*)outbytes;
|
||||
|
||||
/* How many unique bits? */
|
||||
nbits = *bytes_ptr; bytes_ptr++;
|
||||
/* What is the shared bit value? */
|
||||
commonvalue = *bytes_ptr; bytes_ptr++;
|
||||
/* Calculate mask */
|
||||
mask = (0xFFFFFFFF >> (bit-nbits));
|
||||
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
int shift = bit - nbits;
|
||||
uint32_t val = *bytes_ptr;
|
||||
if ( shift >= 0 )
|
||||
{
|
||||
val >>= shift;
|
||||
val &= mask;
|
||||
val |= commonvalue;
|
||||
obytes[i] = val;
|
||||
bit -= nbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = abs(shift);
|
||||
val <<= s;
|
||||
val &= mask;
|
||||
val |= commonvalue;
|
||||
obytes[i] = val;
|
||||
bytes_ptr++;
|
||||
bit = 32;
|
||||
val = *bytes_ptr;
|
||||
shift = bit - s;
|
||||
val >>= shift;
|
||||
val &= mask;
|
||||
bit -= s;
|
||||
obytes[i] |= val;
|
||||
}
|
||||
}
|
||||
return outbytes;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems)
|
||||
{
|
||||
size_t size = INTERPRETATION_SIZES[interpretation];
|
||||
switch ( size )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return pc_bytes_sigbits_decode_8(bytes, nelems);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return pc_bytes_sigbits_decode_16(bytes, nelems);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
return pc_bytes_sigbits_decode_32(bytes, nelems);
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("Uh oh");
|
||||
}
|
||||
}
|
||||
pcerror("Uh Oh");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user