11 #define MIN(a, b) (((a) < (b))? (a): (b))
13 static int convert_options(int sz_opts)
19 memset(co, 0, sizeof(int) * NOPTS);
20 co[SZ_MSB_OPTION_MASK] = AEC_DATA_MSB;
21 co[SZ_NN_OPTION_MASK] = AEC_DATA_PREPROCESS;
23 for (i = 1; i < NOPTS; i <<= 1)
30 static int bits_to_bytes(int bit_length)
34 else if (bit_length > 8)
40 static void interleave_buffer(void *dest, const void *src,
41 size_t n, int wordsize)
45 const unsigned char *src8;
48 src8 = (unsigned char *)src;
49 dest8 = (unsigned char *)dest;
51 for (i = 0; i < n / wordsize; i++)
52 for (j = 0; j < wordsize; j++)
53 dest8[j * (n / wordsize) + i] = src8[i * wordsize + j];
56 static void deinterleave_buffer(void *dest, const void *src,
57 size_t n, int wordsize)
61 const unsigned char *src8;
64 src8 = (unsigned char *)src;
65 dest8 = (unsigned char *)dest;
67 for (i = 0; i < n / wordsize; i++)
68 for (j = 0; j < wordsize; j++)
69 dest8[i * wordsize + j] = src8[j * (n / wordsize) + i];
72 static void add_padding(void *dest, const void *src, size_t total,
73 size_t line_size, size_t padding_size,
74 int pixel_size, int pp)
76 size_t i, j, k, ls, ps;
78 const char zero_pixel[] = {0, 0, 0, 0};
84 ls = MIN(total - i, line_size);
85 memcpy((char *)dest + j, (char *)src + i, ls);
89 pixel = (char *)src + i - pixel_size;
90 ps = line_size + padding_size - ls;
91 for (k = 0; k < ps; k += pixel_size)
92 memcpy((char *)dest + j + k, pixel, pixel_size);
97 static void remove_padding(void *buf, size_t total,
98 size_t line_size, size_t padding_size,
102 size_t padded_line_size = line_size + padding_size;
105 for (j = padded_line_size; j < total; j += padded_line_size) {
106 memmove((char *)buf + i, (char *)buf + j, line_size);
111 int SZ_BufftoBuffCompress(void *dest, size_t *destLen,
112 const void *source, size_t sourceLen,
115 struct aec_stream strm;
127 strm.block_size = param->pixels_per_block;
128 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
129 / param->pixels_per_block;
130 strm.flags = convert_options(param->options_mask);
131 strm.avail_out = *destLen;
132 strm.next_out = dest;
136 interleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
137 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
139 strm.bits_per_sample = 8;
140 buf = malloc(sourceLen);
142 status = SZ_MEM_ERROR;
145 interleave_buffer(buf, source, sourceLen, param->bits_per_pixel / 8);
147 strm.bits_per_sample = param->bits_per_pixel;
148 buf = (void *)source;
151 pixel_size = bits_to_bytes(strm.bits_per_sample);
154 scanlines = (sourceLen + param->pixels_per_scanline - 1)
155 / param->pixels_per_scanline;
156 padbuf_size = strm.rsi * strm.block_size * pixel_size * scanlines;
157 padbuf = malloc(padbuf_size);
158 if (padbuf == NULL) {
159 status = SZ_MEM_ERROR;
164 (strm.rsi * strm.block_size - param->pixels_per_scanline)
167 add_padding(padbuf, buf, sourceLen,
168 param->pixels_per_scanline * pixel_size,
169 padding_size, pixel_size,
170 strm.flags & AEC_DATA_PREPROCESS);
171 strm.next_in = padbuf;
172 strm.avail_in = padbuf_size;
175 strm.avail_in = sourceLen;
178 aec_status = aec_buffer_encode(&strm);
179 if (aec_status == AEC_STREAM_ERROR)
180 status = SZ_OUTBUFF_FULL;
183 *destLen = strm.total_out;
186 if (pad_scanline && padbuf)
188 if (interleave && buf)
193 int SZ_BufftoBuffDecompress(void *dest, size_t *destLen,
194 const void *source, size_t sourceLen,
197 struct aec_stream strm;
202 size_t buf_size, total_out;
208 strm.block_size = param->pixels_per_block;
209 strm.rsi = (param->pixels_per_scanline + param->pixels_per_block - 1)
210 / param->pixels_per_block;
211 strm.flags = convert_options(param->options_mask);
212 strm.avail_in = sourceLen;
213 strm.next_in = source;
216 pad_scanline = param->pixels_per_scanline % param->pixels_per_block;
217 deinterleave = param->bits_per_pixel == 32 || param->bits_per_pixel == 64;
218 extra_buffer = pad_scanline || deinterleave;
221 strm.bits_per_sample = 8;
223 strm.bits_per_sample = param->bits_per_pixel;
225 pixel_size = bits_to_bytes(strm.bits_per_sample);
229 scanlines = (*destLen / pixel_size + param->pixels_per_scanline - 1)
230 / param->pixels_per_scanline;
231 buf_size = strm.rsi * strm.block_size * pixel_size * scanlines;
235 buf = malloc(buf_size);
237 status = SZ_MEM_ERROR;
241 strm.avail_out = buf_size;
243 strm.next_out = dest;
244 strm.avail_out = *destLen;
247 status = aec_buffer_decode(&strm);
248 if (status != AEC_OK)
253 (strm.rsi * strm.block_size - param->pixels_per_scanline)
255 remove_padding(buf, strm.total_out,
256 param->pixels_per_scanline * pixel_size,
257 padding_size, pixel_size);
258 total_out = scanlines * param->pixels_per_scanline * pixel_size;
260 total_out = strm.total_out;
263 if (total_out < *destLen)
264 *destLen = total_out;
267 deinterleave_buffer(dest, buf, *destLen, param->bits_per_pixel / 8);
268 else if (pad_scanline)
269 memcpy(dest, buf, *destLen);
272 if (extra_buffer && buf)
278 int SZ_encoder_enabled(void)