Commit 2a2e588b authored by Mathis Rosenhauer's avatar Mathis Rosenhauer Committed by Thomas Jahns

Addition and removal of padding in SZ compatibility

parent 0c6860cf
...@@ -23,6 +23,16 @@ static int convert_options(int sz_opts) ...@@ -23,6 +23,16 @@ static int convert_options(int sz_opts)
return 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, static void interleave_buffer(void *dest, const void *src,
size_t n, int wordsize) size_t n, int wordsize)
{ {
...@@ -53,43 +63,126 @@ static void deinterleave_buffer(void *dest, const void *src, ...@@ -53,43 +63,126 @@ static void deinterleave_buffer(void *dest, const void *src,
dest8[i * wordsize + j] = src8[j * (n / wordsize) + i]; 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, int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
const void *source, size_t sourceLen, const void *source, size_t sourceLen,
SZ_com_t *param) SZ_com_t *param)
{ {
int status;
struct aec_stream strm; struct aec_stream strm;
int status;
void *padbuf;
void *buf; 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); buf = malloc(sourceLen);
if (buf == NULL) if (buf == NULL)
return SZ_MEM_ERROR; return SZ_MEM_ERROR;
interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8); interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
strm.bit_per_sample = 8;
strm.next_in = buf;
} else { } else {
strm.next_in = source;
strm.bit_per_sample = param->bits_per_pixel; strm.bit_per_sample = param->bits_per_pixel;
buf = (void *)source;
} }
strm.avail_in = sourceLen; pixel_size = bits_to_bytes(strm.bit_per_sample);
strm.block_size = param->pixels_per_block;
strm.rsi = param->pixels_per_scanline / param->pixels_per_block; if (pad_scanline) {
strm.flags = convert_options(param->options_mask); scanlines = (sourceLen / pixel_size + param->pixels_per_scanline - 1)
strm.avail_out = *destLen; / param->pixels_per_scanline;
strm.next_out = dest; 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); status = aec_buffer_encode(&strm);
if (status != AEC_OK) if (status != AEC_OK)
return status; 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); free(buf);
}
*destLen = strm.total_out;
return SZ_OK; return SZ_OK;
} }
...@@ -97,39 +190,80 @@ int SZ_BufftoBuffDecompress(void *dest, size_t *destLen, ...@@ -97,39 +190,80 @@ int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
const void *source, size_t sourceLen, const void *source, size_t sourceLen,
SZ_com_t *param) SZ_com_t *param)
{ {
int status;
struct aec_stream strm; struct aec_stream strm;
int status;
void *buf; 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) { strm.block_size = param->pixels_per_block;
buf = malloc(*destLen); strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
if (buf == NULL) / param->pixels_per_block;
return SZ_MEM_ERROR; 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; 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.next_out = buf;
strm.avail_out = buf_size;
} else { } else {
strm.next_out = dest; 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); status = aec_buffer_decode(&strm);
if (status != AEC_OK) if (status != AEC_OK)
return status; 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); deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
else if (pad_scanline)
memcpy(dest, buf, *destLen);
if (extra_buffer)
free(buf); free(buf);
}
return SZ_OK; return SZ_OK;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment