Skip to content
Snippets Groups Projects
Commit 2a2e588b authored by Mathis Rosenhauer's avatar Mathis Rosenhauer Committed by Thomas Jahns
Browse files

Addition and removal of padding in SZ compatibility

parent 0c6860cf
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,16 @@ static int convert_options(int sz_opts)
return opts;
}
static int bits_to_bytes(int bit_length)
{
if (bit_length > 16)
return 4;
else if (bit_length > 8)
return 2;
else
return 1;
}
static void interleave_buffer(void *dest, const void *src,
size_t n, int wordsize)
{
......@@ -53,43 +63,126 @@ static void deinterleave_buffer(void *dest, const void *src,
dest8[i * wordsize + j] = src8[j * (n / wordsize) + i];
}
static size_t add_padding(void *dest, const void *src, size_t total,
size_t line_size, size_t padding_size,
int pixel_size, int pp)
{
size_t i, j, k;
const char *pixel;
const char zero_pixel[] = {0, 0, 0, 0, 0, 0, 0, 0};
for (i = 0, j = 0;
i < total;
i += pixel_size, j += pixel_size) {
if (i > 0 && (i % line_size) == 0) {
if (pp)
pixel = (char *)src + i - 1;
else
pixel = zero_pixel;
for (k = 0; k < padding_size; k += pixel_size)
memcpy((char *)dest + j + k, pixel, pixel_size);
j += padding_size;
}
memcpy((char *)dest + j, (char *)src + i, pixel_size);
}
return j;
}
static size_t remove_padding(void *buf, size_t total,
size_t line_size, size_t padding_size,
int pixel_size)
{
size_t i, j;
for (i = 0, j = padding_size;
i < total;
i += pixel_size, j += pixel_size) {
if (i % (line_size + padding_size) == 0)
j -= padding_size;
memcpy((char *)buf + j, (char *)buf + i, pixel_size);
}
if ((i % (line_size + padding_size)) == 0)
j -= padding_size;
return j;
}
int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
const void *source, size_t sourceLen,
SZ_com_t *param)
{
int status;
struct aec_stream strm;
int status;
void *padbuf;
void *buf;
size_t padding_size;
size_t padded_length;
size_t scanlines;
size_t buf_size;
int pixel_size;
int pad_scanline;
int interleave;
strm.block_size = param->pixels_per_block;
strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
/ param->pixels_per_block;
strm.flags = convert_options(param->options_mask);
strm.avail_out = *destLen;
strm.next_out = dest;
if (param->bits_per_pixel == 32 || param->bits_per_pixel == 64) {
pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
interleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
if (interleave) {
strm.bit_per_sample = 8;
buf = malloc(sourceLen);
if (buf == NULL)
return SZ_MEM_ERROR;
interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
strm.bit_per_sample = 8;
strm.next_in = buf;
} else {
strm.next_in = source;
strm.bit_per_sample = param->bits_per_pixel;
buf = (void *)source;
}
strm.avail_in = sourceLen;
strm.block_size = param->pixels_per_block;
strm.rsi = param->pixels_per_scanline / param->pixels_per_block;
strm.flags = convert_options(param->options_mask);
strm.avail_out = *destLen;
strm.next_out = dest;
pixel_size = bits_to_bytes(strm.bit_per_sample);
if (pad_scanline) {
scanlines = (sourceLen / pixel_size + param->pixels_per_scanline - 1)
/ param->pixels_per_scanline;
buf_size = strm.rsi * param->pixels_per_block * pixel_size * scanlines;
padbuf = malloc(buf_size);
if (padbuf == NULL)
return SZ_MEM_ERROR;
padding_size = (
param->pixels_per_block -
(param->pixels_per_scanline % param->pixels_per_block)
) * pixel_size;
padded_length = add_padding(padbuf, buf, sourceLen,
param->pixels_per_scanline * pixel_size,
padding_size, pixel_size,
strm.flags & AEC_DATA_PREPROCESS);
strm.next_in = padbuf;
strm.avail_in = padded_length;
} else {
strm.next_in = buf;
strm.avail_in = sourceLen;
}
status = aec_buffer_encode(&strm);
if (status != AEC_OK)
return status;
if (param->bits_per_pixel == 32 || param->bits_per_pixel == 64) {
*destLen = strm.total_out;
if (pad_scanline)
free(padbuf);
if (interleave)
free(buf);
}
*destLen = strm.total_out;
return SZ_OK;
}
......@@ -97,39 +190,80 @@ int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
const void *source, size_t sourceLen,
SZ_com_t *param)
{
int status;
struct aec_stream strm;
int status;
void *buf;
size_t padding_size;
size_t scanlines;
size_t buf_size, total_out;
int pixel_size;
int pad_scanline;
int deinterleave;
int extra_buffer;
if (param->bits_per_pixel == 32 || param->bits_per_pixel == 64) {
buf = malloc(*destLen);
if (buf == NULL)
return SZ_MEM_ERROR;
strm.block_size = param->pixels_per_block;
strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
/ param->pixels_per_block;
strm.flags = convert_options(param->options_mask);
strm.avail_in = sourceLen;
strm.next_in = source;
pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
deinterleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
extra_buffer = pad_scanline || deinterleave;
if (deinterleave)
strm.bit_per_sample = 8;
else
strm.bit_per_sample = param->bits_per_pixel;
pixel_size = bits_to_bytes(strm.bit_per_sample);
if (extra_buffer) {
if (pad_scanline) {
scanlines = (*destLen / pixel_size + param->pixels_per_scanline - 1)
/ param->pixels_per_scanline;
buf_size = strm.rsi * param->pixels_per_block
* pixel_size * scanlines;
} else {
buf_size = *destLen;
}
buf = malloc(buf_size);
if (buf == NULL)
return SZ_MEM_ERROR;
strm.next_out = buf;
strm.avail_out = buf_size;
} else {
strm.next_out = dest;
strm.bit_per_sample = param->bits_per_pixel;
strm.avail_out = *destLen;
}
strm.block_size = param->pixels_per_block;
strm.rsi = param->pixels_per_scanline / param->pixels_per_block;
strm.flags = convert_options(param->options_mask);
strm.avail_in = sourceLen;
strm.avail_out = *destLen;
strm.next_in = source;
status = aec_buffer_decode(&strm);
if (status != AEC_OK)
return status;
*destLen = strm.total_out;
if (pad_scanline) {
padding_size = (
param->pixels_per_block -
(param->pixels_per_scanline % param->pixels_per_block)
) * pixel_size;
total_out = remove_padding(buf, strm.total_out,
param->pixels_per_scanline * pixel_size,
padding_size, pixel_size);
} else {
total_out = strm.total_out;
}
if (total_out < *destLen)
*destLen = total_out;
if (param->bits_per_pixel == 32 || param->bits_per_pixel == 64) {
if (deinterleave)
deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
else if (pad_scanline)
memcpy(dest, buf, *destLen);
if (extra_buffer)
free(buf);
}
return SZ_OK;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment