10 static int convert_options(int sz_opts)
16 memset(co, 0, sizeof(int) * NOPTS);
17 co[SZ_MSB_OPTION_MASK] = AEC_DATA_MSB;
18 co[SZ_NN_OPTION_MASK] = AEC_DATA_PREPROCESS;
20 for (i = 1; i < NOPTS; i <<= 1)
27 static int bits_to_bytes(int bit_length)
31 else if (bit_length > 8)
37 static void interleave_buffer(void *dest, const void *src,
38 size_t n, int wordsize)
41 const unsigned char *src8;
44 src8 = (unsigned char *)src;
45 dest8 = (unsigned char *)dest;
47 for (i = 0; i < n / wordsize; i++)
48 for (j = 0; j < wordsize; j++)
49 dest8[j * (n / wordsize) + i] = src8[i * wordsize + j];
52 static void deinterleave_buffer(void *dest, const void *src,
53 size_t n, int wordsize)
56 const unsigned char *src8;
59 src8 = (unsigned char *)src;
60 dest8 = (unsigned char *)dest;
62 for (i = 0; i < n / wordsize; i++)
63 for (j = 0; j < wordsize; j++)
64 dest8[i * wordsize + j] = src8[j * (n / wordsize) + i];
67 static size_t add_padding(void *dest, const void *src, size_t total,
68 size_t line_size, size_t padding_size,
69 int pixel_size, int pp)
73 const char zero_pixel[] = {0, 0, 0, 0, 0, 0, 0, 0};
77 i += pixel_size, j += pixel_size) {
78 if (i > 0 && (i % line_size) == 0) {
80 pixel = (char *)src + i - 1;
83 for (k = 0; k < padding_size; k += pixel_size)
84 memcpy((char *)dest + j + k, pixel, pixel_size);
87 memcpy((char *)dest + j, (char *)src + i, pixel_size);
92 static size_t remove_padding(void *buf, size_t total,
93 size_t line_size, size_t padding_size,
98 for (i = 0, j = padding_size;
100 i += pixel_size, j += pixel_size) {
101 if (i % (line_size + padding_size) == 0)
103 memcpy((char *)buf + j, (char *)buf + i, pixel_size);
105 if (i % (line_size + padding_size) == 0)
110 int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
111 const void *source, size_t sourceLen,
114 struct aec_stream strm;
119 size_t padded_length;
126 strm.block_size = param->pixels_per_block;
127 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
128 / param->pixels_per_block;
129 strm.flags = convert_options(param->options_mask);
130 strm.avail_out = *destLen;
131 strm.next_out = dest;
133 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
134 interleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
137 strm.bits_per_sample = 8;
138 buf = malloc(sourceLen);
141 interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
143 strm.bits_per_sample = param->bits_per_pixel;
144 buf = (void *)source;
147 pixel_size = bits_to_bytes(strm.bits_per_sample);
150 scanlines = (sourceLen / pixel_size + param->pixels_per_scanline - 1)
151 / param->pixels_per_scanline;
152 buf_size = strm.rsi * param->pixels_per_block * pixel_size * scanlines;
154 padbuf = malloc(buf_size);
159 param->pixels_per_block -
160 (param->pixels_per_scanline % param->pixels_per_block)
163 padded_length = add_padding(padbuf, buf, sourceLen,
164 param->pixels_per_scanline * pixel_size,
165 padding_size, pixel_size,
166 strm.flags & AEC_DATA_PREPROCESS);
168 strm.next_in = padbuf;
169 strm.avail_in = padded_length;
172 strm.avail_in = sourceLen;
175 status = aec_buffer_encode(&strm);
176 if (status != AEC_OK)
179 *destLen = strm.total_out;
181 if (pad_scanline && padbuf)
184 if (interleave && buf)
190 int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
191 const void *source, size_t sourceLen,
194 struct aec_stream strm;
199 size_t buf_size, total_out;
205 strm.block_size = param->pixels_per_block;
206 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
207 / param->pixels_per_block;
208 strm.flags = convert_options(param->options_mask);
209 strm.avail_in = sourceLen;
210 strm.next_in = source;
212 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
213 deinterleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
214 extra_buffer = pad_scanline || deinterleave;
217 strm.bits_per_sample = 8;
219 strm.bits_per_sample = param->bits_per_pixel;
221 pixel_size = bits_to_bytes(strm.bits_per_sample);
225 scanlines = (*destLen / pixel_size + param->pixels_per_scanline - 1)
226 / param->pixels_per_scanline;
227 buf_size = strm.rsi * param->pixels_per_block
228 * pixel_size * scanlines;
232 buf = malloc(buf_size);
236 strm.avail_out = buf_size;
238 strm.next_out = dest;
239 strm.avail_out = *destLen;
242 status = aec_buffer_decode(&strm);
243 if (status != AEC_OK)
248 param->pixels_per_block -
249 (param->pixels_per_scanline % param->pixels_per_block)
251 total_out = remove_padding(buf, strm.total_out,
252 param->pixels_per_scanline * pixel_size,
253 padding_size, pixel_size);
255 total_out = strm.total_out;
258 if (total_out < *destLen)
259 *destLen = total_out;
262 deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
263 else if (pad_scanline)
264 memcpy(dest, buf, *destLen);
266 if (extra_buffer && buf)
272 int SZ_encoder_enabled(void)