12 static int convert_options(int sz_opts)
18 memset(co, 0, sizeof(int) * NOPTS);
19 co[SZ_MSB_OPTION_MASK] = AEC_DATA_MSB;
20 co[SZ_NN_OPTION_MASK] = AEC_DATA_PREPROCESS;
22 for (i = 1; i < NOPTS; i <<= 1)
29 static int bits_to_bytes(int bit_length)
33 else if (bit_length > 8)
39 static void interleave_buffer(void *dest, const void *src,
40 size_t n, int wordsize)
43 const unsigned char *src8;
46 src8 = (unsigned char *)src;
47 dest8 = (unsigned char *)dest;
49 for (i = 0; i < n / wordsize; i++)
50 for (j = 0; j < wordsize; j++)
51 dest8[j * (n / wordsize) + i] = src8[i * wordsize + j];
54 static void deinterleave_buffer(void *dest, const void *src,
55 size_t n, int wordsize)
58 const unsigned char *src8;
61 src8 = (unsigned char *)src;
62 dest8 = (unsigned char *)dest;
64 for (i = 0; i < n / wordsize; i++)
65 for (j = 0; j < wordsize; j++)
66 dest8[i * wordsize + j] = src8[j * (n / wordsize) + i];
69 static void add_padding(void *dest, const void *src, size_t total,
70 size_t line_size, size_t padding_size,
71 int pixel_size, int pp)
75 const char zero_pixel[] = {0, 0, 0, 0};
79 for (i = 0; i < total; i += line_size) {
80 memcpy((char *)dest + j, (char *)src + i, line_size);
83 pixel = (char *)src + i + line_size - pixel_size;
84 for (k = 0; k < padding_size; k += pixel_size)
85 memcpy((char *)dest + j + k, pixel, pixel_size);
90 static void remove_padding(void *buf, size_t total,
91 size_t line_size, size_t padding_size,
95 size_t padded_line_size = line_size + padding_size;
98 for (j = padded_line_size; j < total; j += padded_line_size) {
99 memmove((char *)buf + i, (char *)buf + j, line_size);
104 int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
105 const void *source, size_t sourceLen,
108 struct aec_stream strm;
119 strm.block_size = param->pixels_per_block;
120 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
121 / param->pixels_per_block;
122 strm.flags = convert_options(param->options_mask);
123 strm.avail_out = *destLen;
124 strm.next_out = dest;
128 interleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
129 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
131 strm.bits_per_sample = 8;
132 buf = malloc(sourceLen);
134 status = SZ_MEM_ERROR;
137 interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
139 strm.bits_per_sample = param->bits_per_pixel;
140 buf = (void *)source;
143 pixel_size = bits_to_bytes(strm.bits_per_sample);
146 scanlines = sourceLen / param->pixels_per_scanline;
147 padbuf_size = strm.rsi * strm.block_size * pixel_size * scanlines;
148 padbuf = malloc(padbuf_size);
149 if (padbuf == NULL) {
150 status = SZ_MEM_ERROR;
155 (strm.rsi * strm.block_size - param->pixels_per_scanline)
158 add_padding(padbuf, buf, sourceLen,
159 param->pixels_per_scanline * pixel_size,
160 padding_size, pixel_size,
161 strm.flags & AEC_DATA_PREPROCESS);
162 strm.next_in = padbuf;
163 strm.avail_in = padbuf_size;
166 strm.avail_in = sourceLen;
169 status = aec_buffer_encode(&strm);
170 *destLen = strm.total_out;
173 if (pad_scanline && padbuf)
175 if (interleave && buf)
180 int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
181 const void *source, size_t sourceLen,
184 struct aec_stream strm;
189 size_t buf_size, total_out;
195 strm.block_size = param->pixels_per_block;
196 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
197 / param->pixels_per_block;
198 strm.flags = convert_options(param->options_mask);
199 strm.avail_in = sourceLen;
200 strm.next_in = source;
203 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
204 deinterleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
205 extra_buffer = pad_scanline || deinterleave;
208 strm.bits_per_sample = 8;
210 strm.bits_per_sample = param->bits_per_pixel;
212 pixel_size = bits_to_bytes(strm.bits_per_sample);
216 scanlines = (*destLen / pixel_size + param->pixels_per_scanline - 1)
217 / param->pixels_per_scanline;
218 buf_size = strm.rsi * strm.block_size * pixel_size * scanlines;
222 buf = malloc(buf_size);
224 status = SZ_MEM_ERROR;
228 strm.avail_out = buf_size;
230 strm.next_out = dest;
231 strm.avail_out = *destLen;
234 status = aec_buffer_decode(&strm);
235 if (status != AEC_OK)
240 (strm.rsi * strm.block_size - param->pixels_per_scanline)
242 remove_padding(buf, strm.total_out,
243 param->pixels_per_scanline * pixel_size,
244 padding_size, pixel_size);
245 total_out = scanlines * param->pixels_per_scanline * pixel_size;
247 total_out = strm.total_out;
250 if (total_out < *destLen)
251 *destLen = total_out;
254 deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
255 else if (pad_scanline)
256 memcpy(dest, buf, *destLen);
259 if (extra_buffer && buf)
265 int SZ_encoder_enabled(void)