8 static int convert_options(int sz_opts)
14 memset(co, 0, sizeof(int) * NOPTS);
15 co[SZ_MSB_OPTION_MASK] = AEC_DATA_MSB;
16 co[SZ_NN_OPTION_MASK] = AEC_DATA_PREPROCESS;
18 for (i = 1; i < NOPTS; i <<= 1)
25 static int bits_to_bytes(int bit_length)
29 else if (bit_length > 8)
35 static void interleave_buffer(void *dest, const void *src,
36 size_t n, int wordsize)
39 const unsigned char *src8;
42 src8 = (unsigned char *)src;
43 dest8 = (unsigned char *)dest;
45 for (i = 0; i < n / wordsize; i++)
46 for (j = 0; j < wordsize; j++)
47 dest8[j * (n / wordsize) + i] = src8[i * wordsize + j];
50 static void deinterleave_buffer(void *dest, const void *src,
51 size_t n, int wordsize)
54 const unsigned char *src8;
57 src8 = (unsigned char *)src;
58 dest8 = (unsigned char *)dest;
60 for (i = 0; i < n / wordsize; i++)
61 for (j = 0; j < wordsize; j++)
62 dest8[i * wordsize + j] = src8[j * (n / wordsize) + i];
65 static size_t add_padding(void *dest, const void *src, size_t total,
66 size_t line_size, size_t padding_size,
67 int pixel_size, int pp)
71 const char zero_pixel[] = {0, 0, 0, 0, 0, 0, 0, 0};
72 size_t padded_line_size = line_size + padding_size;
76 for (i = 0; i < total; i += line_size) {
77 if (i + line_size > total) {
78 line_size = total - i;
79 padding_size = padded_line_size - line_size;
81 memcpy((char *)dest + j, (char *)src + i, line_size);
84 pixel = (char *)src + i + line_size - pixel_size;
85 for (k = 0; k < padding_size; k += pixel_size)
86 memcpy((char *)dest + j + k, pixel, pixel_size);
92 static size_t remove_padding(void *buf, size_t total,
93 size_t line_size, size_t padding_size,
97 size_t padded_line_size = line_size + padding_size;
100 for (j = padded_line_size; j < total; j += padded_line_size) {
101 memmove((char *)buf + i, (char *)buf + j, line_size);
107 int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
108 const void *source, size_t sourceLen,
111 struct aec_stream strm;
116 size_t padded_length;
123 strm.block_size = param->pixels_per_block;
124 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
125 / param->pixels_per_block;
126 strm.flags = convert_options(param->options_mask);
127 strm.avail_out = *destLen;
128 strm.next_out = dest;
130 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
131 interleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
134 strm.bits_per_sample = 8;
135 buf = malloc(sourceLen);
138 interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
140 strm.bits_per_sample = param->bits_per_pixel;
141 buf = (void *)source;
144 pixel_size = bits_to_bytes(strm.bits_per_sample);
147 scanlines = (sourceLen / pixel_size + param->pixels_per_scanline - 1)
148 / param->pixels_per_scanline;
149 buf_size = strm.rsi * param->pixels_per_block * pixel_size * scanlines;
151 padbuf = malloc(buf_size);
156 param->pixels_per_block -
157 (param->pixels_per_scanline % param->pixels_per_block)
160 padded_length = add_padding(padbuf, buf, sourceLen,
161 param->pixels_per_scanline * pixel_size,
162 padding_size, pixel_size,
163 strm.flags & AEC_DATA_PREPROCESS);
165 strm.next_in = padbuf;
166 strm.avail_in = padded_length;
169 strm.avail_in = sourceLen;
172 status = aec_buffer_encode(&strm);
173 *destLen = strm.total_out;
175 if (pad_scanline && padbuf)
177 if (interleave && buf)
183 int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
184 const void *source, size_t sourceLen,
187 struct aec_stream strm;
192 size_t buf_size, total_out;
198 strm.block_size = param->pixels_per_block;
199 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
200 / param->pixels_per_block;
201 strm.flags = convert_options(param->options_mask);
202 strm.avail_in = sourceLen;
203 strm.next_in = source;
205 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
206 deinterleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
207 extra_buffer = pad_scanline || deinterleave;
210 strm.bits_per_sample = 8;
212 strm.bits_per_sample = param->bits_per_pixel;
214 pixel_size = bits_to_bytes(strm.bits_per_sample);
218 scanlines = (*destLen / pixel_size + param->pixels_per_scanline - 1)
219 / param->pixels_per_scanline;
220 buf_size = strm.rsi * param->pixels_per_block
221 * pixel_size * scanlines;
225 buf = malloc(buf_size);
229 strm.avail_out = buf_size;
231 strm.next_out = dest;
232 strm.avail_out = *destLen;
235 status = aec_buffer_decode(&strm);
236 if (status != AEC_OK)
241 param->pixels_per_block -
242 (param->pixels_per_scanline % param->pixels_per_block)
244 total_out = remove_padding(buf, strm.total_out,
245 param->pixels_per_scanline * pixel_size,
246 padding_size, pixel_size);
248 total_out = strm.total_out;
251 if (total_out < *destLen)
252 *destLen = total_out;
255 deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
256 else if (pad_scanline)
257 memcpy(dest, buf, *destLen);
259 if (extra_buffer && buf)
265 int SZ_encoder_enabled(void)