Skip to content
Merged
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 85 additions & 68 deletions src/H5Zscaleoffset.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,22 @@ static herr_t H5Z__scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enu
static herr_t H5Z__scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type,
unsigned filavail, const unsigned cd_values[],
uint32_t minbits, unsigned long long minval, double D_val);
static void H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len);
static void H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
unsigned begin_i, const unsigned char *buffer, size_t *j,
unsigned *buf_len, parms_atomic p, unsigned dtype_len);
static void H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill);
static herr_t H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k,
unsigned begin_i, const unsigned char *buffer,
size_t buf_size, size_t *j, unsigned *bits_to_fill,
parms_atomic p, unsigned dtype_len);
static void H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
unsigned begin_i, unsigned char *buffer, size_t *j,
unsigned *buf_len, parms_atomic p, unsigned dtype_len);
unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len);
static void H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
unsigned char *buffer, size_t *j, unsigned *buf_len,
parms_atomic p);
unsigned char *buffer, size_t buf_size, size_t *j,
unsigned *bits_to_fill, parms_atomic p);
static void H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset,
unsigned char *buffer, size_t *j, unsigned *buf_len,
unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
parms_atomic p);
static void H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
parms_atomic p);
size_t buf_size, parms_atomic p);
static void H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer,
size_t buffer_size, parms_atomic p);

Expand Down Expand Up @@ -1262,8 +1263,10 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
}

/* decompress the buffer if minbits not equal to zero */
if (minbits != 0)
H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset, p);
if (minbits != 0) {
H5Z__scaleoffset_decompress(outbuf, d_nelmts, (unsigned char *)(*buf) + buf_offset,
*buf_size - buf_offset, p);
}
else {
/* fill value is not defined and all data elements have the same value */
for (i = 0; i < size_out; i++)
Expand Down Expand Up @@ -1604,50 +1607,61 @@ H5Z__scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scale
}

static void
H5Z__scaleoffset_next_byte(size_t *j, unsigned *buf_len)
H5Z__scaleoffset_next_byte(size_t *j, unsigned *bits_to_fill)
{
++(*j);
*buf_len = 8 * sizeof(unsigned char);
*bits_to_fill = 8 * sizeof(unsigned char);
}

static void
static herr_t
H5Z__scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, unsigned k, unsigned begin_i,
const unsigned char *buffer, size_t *j, unsigned *buf_len,
parms_atomic p, unsigned dtype_len)
const unsigned char *buffer, size_t buf_size, size_t *j,
unsigned *bits_to_fill, parms_atomic p, unsigned dtype_len)
{
unsigned dat_len; /* dat_len is the number of bits to be copied in each data byte */
unsigned char val; /* value to be copied in each data byte */
unsigned bits_to_copy; /* bits_to_copy is the number of bits to be copied in each data byte */
unsigned char val; /* value to be copied in each data byte */
herr_t ret_value = SUCCEED; /* Return value */

FUNC_ENTER_PACKAGE

if (*j >= buf_size)
HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");

/* initialize value and bits of unsigned char to be copied */
val = buffer[*j];
if (k == begin_i)
dat_len = 8 - (dtype_len - p.minbits) % 8;
bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
else
dat_len = 8;
bits_to_copy = 8;

if (*buf_len > dat_len) {
data[data_offset + k] =
(unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & (unsigned)(~((unsigned)~0 << dat_len)));
*buf_len -= dat_len;
if (*bits_to_fill > bits_to_copy) {
data[data_offset + k] = (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
(unsigned)(~((unsigned)~0 << bits_to_copy)));
*bits_to_fill -= bits_to_copy;
} /* end if */
else {
data[data_offset + k] =
(unsigned char)((val & ~((unsigned)(~0) << *buf_len)) << (dat_len - *buf_len));
dat_len -= *buf_len;
H5Z__scaleoffset_next_byte(j, buf_len);
if (dat_len == 0)
return;
(unsigned char)((val & ~((unsigned)(~0) << *bits_to_fill)) << (bits_to_copy - *bits_to_fill));
bits_to_copy -= *bits_to_fill;
H5Z__scaleoffset_next_byte(j, bits_to_fill);
if (bits_to_copy == 0)
goto done;
else if (*j >= buf_size)
HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, 0, "Buffer too short");

val = buffer[*j];
data[data_offset + k] |=
(unsigned char)((unsigned)(val >> (*buf_len - dat_len)) & ~((unsigned)(~0) << dat_len));
*buf_len -= dat_len;
data[data_offset + k] |= (unsigned char)((unsigned)(val >> (*bits_to_fill - bits_to_copy)) &
~((unsigned)(~0) << bits_to_copy));
*bits_to_fill -= bits_to_copy;
} /* end else */

done:
FUNC_LEAVE_NOAPI(ret_value)
}

static void
H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
size_t *j, unsigned *buf_len, parms_atomic p)
size_t buf_size, size_t *j, unsigned *bits_to_fill, parms_atomic p)
{
/* begin_i: the index of byte having first significant bit */
unsigned begin_i;
Expand All @@ -1662,76 +1676,79 @@ H5Z__scaleoffset_decompress_one_atomic(unsigned char *data, size_t data_offset,
begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;

for (k = (int)begin_i; k >= 0; k--)
H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
p, dtype_len);
H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, buf_size, j,
bits_to_fill, p, dtype_len);
}
else { /* big endian */
assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);

begin_i = (dtype_len - p.minbits) / 8;

for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len,
p, dtype_len);
H5Z__scaleoffset_decompress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, buf_size, j,
bits_to_fill, p, dtype_len);
}
}

static void
H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, parms_atomic p)
H5Z__scaleoffset_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, size_t buf_size,
parms_atomic p)
{
/* i: index of data, j: index of buffer,
buf_len: number of bits to be filled in current byte */
bits_to_fill: number of bits to be filled in current byte */
size_t i, j;
unsigned buf_len;
unsigned bits_to_fill;

/* must initialize to zeros */
for (i = 0; i < d_nelmts * (size_t)p.size; i++)
data[i] = 0;

/* initialization before the loop */
j = 0;
buf_len = sizeof(unsigned char) * 8;
j = 0;
bits_to_fill = sizeof(unsigned char) * 8;

/* decompress */
for (i = 0; i < d_nelmts; i++)
H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
H5Z__scaleoffset_decompress_one_atomic(data, i * p.size, buffer, buf_size, &j, &bits_to_fill, p);
}

static void
H5Z__scaleoffset_compress_one_byte(const unsigned char *data, size_t data_offset, unsigned k,
unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *buf_len,
unsigned begin_i, unsigned char *buffer, size_t *j, unsigned *bits_to_fill,
parms_atomic p, unsigned dtype_len)
{
unsigned dat_len; /* dat_len is the number of bits to be copied in each data byte */
unsigned char val; /* value to be copied in each data byte */
unsigned bits_to_copy; /* bits_to_copy is the number of bits to be copied in each data byte */
unsigned char val; /* value to be copied in each data byte */

/* initialize value and bits of unsigned char to be copied */
val = data[data_offset + k];
if (k == begin_i)
dat_len = 8 - (dtype_len - p.minbits) % 8;
bits_to_copy = 8 - (dtype_len - p.minbits) % 8;
else
dat_len = 8;
bits_to_copy = 8;

if (*buf_len > dat_len) {
buffer[*j] |= (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
*buf_len -= dat_len;
if (*bits_to_fill > bits_to_copy) {
buffer[*j] |=
(unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
*bits_to_fill -= bits_to_copy;
}
else {
buffer[*j] |=
(unsigned char)((unsigned)(val >> (dat_len - *buf_len)) & ~((unsigned)(~0) << *buf_len));
dat_len -= *buf_len;
H5Z__scaleoffset_next_byte(j, buf_len);
if (dat_len == 0)
buffer[*j] |= (unsigned char)((unsigned)(val >> (bits_to_copy - *bits_to_fill)) &
~((unsigned)(~0) << *bits_to_fill));
bits_to_copy -= *bits_to_fill;
H5Z__scaleoffset_next_byte(j, bits_to_fill);
if (bits_to_copy == 0)
return;

buffer[*j] = (unsigned char)((val & ~((unsigned)(~0) << dat_len)) << (*buf_len - dat_len));
*buf_len -= dat_len;
buffer[*j] =
(unsigned char)((val & ~((unsigned)(~0) << bits_to_copy)) << (*bits_to_fill - bits_to_copy));
*bits_to_fill -= bits_to_copy;
} /* end else */
}

static void
H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer,
size_t *j, unsigned *buf_len, parms_atomic p)
size_t *j, unsigned *bits_to_fill, parms_atomic p)
{
/* begin_i: the index of byte having first significant bit */
unsigned begin_i;
Expand All @@ -1746,16 +1763,16 @@ H5Z__scaleoffset_compress_one_atomic(unsigned char *data, size_t data_offset, un
begin_i = p.size - 1 - (dtype_len - p.minbits) / 8;

for (k = (int)begin_i; k >= 0; k--)
H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
dtype_len);
H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
bits_to_fill, p, dtype_len);
}
else { /* big endian */
assert(p.mem_order == H5Z_SCALEOFFSET_ORDER_BE);
begin_i = (dtype_len - p.minbits) / 8;

for (k = (int)begin_i; k <= (int)(p.size - 1); k++)
H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j, buf_len, p,
dtype_len);
H5Z__scaleoffset_compress_one_byte(data, data_offset, (unsigned)k, begin_i, buffer, j,
bits_to_fill, p, dtype_len);
}
}

Expand All @@ -1764,19 +1781,19 @@ H5Z__scaleoffset_compress(unsigned char *data, unsigned d_nelmts, unsigned char
parms_atomic p)
{
/* i: index of data, j: index of buffer,
buf_len: number of bits to be filled in current byte */
bits_to_fill: number of bits to be filled in current byte */
size_t i, j;
unsigned buf_len;
unsigned bits_to_fill;

/* must initialize buffer to be zeros */
for (j = 0; j < buffer_size; j++)
buffer[j] = 0;

/* initialization before the loop */
j = 0;
buf_len = sizeof(unsigned char) * 8;
j = 0;
bits_to_fill = sizeof(unsigned char) * 8;

/* compress */
for (i = 0; i < d_nelmts; i++)
H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &buf_len, p);
H5Z__scaleoffset_compress_one_atomic(data, i * p.size, buffer, &j, &bits_to_fill, p);
}
Loading