FS#8961 - Anti-Aliased Fonts.
[kugel-rb/myfork.git] / apps / codecs / libwavpack / pack.c
blob9ccfa072610abd0235ef0072dd51c37ac7c0410e
1 ////////////////////////////////////////////////////////////////////////////
2 // **** WAVPACK **** //
3 // Hybrid Lossless Wavefile Compressor //
4 // Copyright (c) 1998 - 2005 Conifer Software. //
5 // All Rights Reserved. //
6 // Distributed under the BSD Software License (see license.txt) //
7 ////////////////////////////////////////////////////////////////////////////
9 // pack.c
11 // This module actually handles the compression of the audio data, except for
12 // the entropy coding which is handled by the words? modules. For efficiency,
13 // the conversion is isolated to tight loops that handle an entire buffer.
15 #include "wavpack.h"
17 #include <string.h>
19 // This flag provides faster encoding speed at the expense of more code. The
20 // improvement applies to 16-bit stereo lossless only.
22 //////////////////////////////// local tables ///////////////////////////////
24 // These two tables specify the characteristics of the decorrelation filters.
25 // Each term represents one layer of the sequential filter, where positive
26 // values indicate the relative sample involved from the same channel (1=prev),
27 // 17 & 18 are special functions using the previous 2 samples, and negative
28 // values indicate cross channel decorrelation (in stereo only).
30 static const signed char default_terms [] = { 18,18,2,3,-2,0 };
31 static const signed char high_terms [] = { 18,18,2,3,-2,18,2,4,7,5,3,6,0 };
32 static const signed char fast_terms [] = { 17,17,0 };
34 ///////////////////////////// executable code ////////////////////////////////
36 // This function initializes everything required to pack WavPack bitstreams
37 // and must be called BEFORE any other function in this module.
39 void pack_init (WavpackContext *wpc)
41 WavpackStream *wps = &wpc->stream;
42 uint32_t flags = wps->wphdr.flags;
43 struct decorr_pass *dpp;
44 const signed char *term_string;
45 int ti;
47 wps->sample_index = 0;
48 CLEAR (wps->decorr_passes);
50 if (wpc->config.flags & CONFIG_HIGH_FLAG)
51 term_string = high_terms;
52 else if (wpc->config.flags & CONFIG_FAST_FLAG)
53 term_string = fast_terms;
54 else
55 term_string = default_terms;
57 for (dpp = wps->decorr_passes, ti = 0; term_string [ti]; ti++)
58 if (term_string [ti] >= 0 || (flags & CROSS_DECORR)) {
59 dpp->term = term_string [ti];
60 dpp++->delta = 2;
62 else if (!(flags & MONO_FLAG)) {
63 dpp->term = -3;
64 dpp++->delta = 2;
67 wps->num_terms = dpp - wps->decorr_passes;
68 init_words (wps);
71 // Allocate room for and copy the decorrelation terms from the decorr_passes
72 // array into the specified metadata structure. Both the actual term id and
73 // the delta are packed into single characters.
75 static void write_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
77 int tcount = wps->num_terms;
78 struct decorr_pass *dpp;
79 char *byteptr;
81 byteptr = wpmd->data = wpmd->temp_data;
82 wpmd->id = ID_DECORR_TERMS;
84 for (dpp = wps->decorr_passes; tcount--; ++dpp)
85 *byteptr++ = ((dpp->term + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0);
87 wpmd->byte_length = byteptr - (char *) wpmd->data;
90 // Allocate room for and copy the decorrelation term weights from the
91 // decorr_passes array into the specified metadata structure. The weights
92 // range +/-1024, but are rounded and truncated to fit in signed chars for
93 // metadata storage. Weights are separate for the two channels
95 static void write_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
97 int tcount = wps->num_terms;
98 struct decorr_pass *dpp;
99 signed char *byteptr;
101 byteptr = wpmd->data = wpmd->temp_data;
102 wpmd->id = ID_DECORR_WEIGHTS;
104 for (dpp = wps->decorr_passes; tcount--; ++dpp) {
105 dpp->weight_A = restore_weight (*byteptr++ = store_weight (dpp->weight_A));
107 if (!(wps->wphdr.flags & MONO_FLAG))
108 dpp->weight_B = restore_weight (*byteptr++ = store_weight (dpp->weight_B));
111 wpmd->byte_length = byteptr - (signed char *) wpmd->data;
114 // Allocate room for and copy the decorrelation samples from the decorr_passes
115 // array into the specified metadata structure. The samples are signed 32-bit
116 // values, but are converted to signed log2 values for storage in metadata.
117 // Values are stored for both channels and are specified from the first term
118 // with unspecified samples set to zero. The number of samples stored varies
119 // with the actual term value, so those must obviously be specified before
120 // these in the metadata list. Any number of terms can have their samples
121 // specified from no terms to all the terms, however I have found that
122 // sending more than the first term's samples is a waste. The "wcount"
123 // variable can be set to the number of terms to have their samples stored.
125 static void write_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
127 int tcount = wps->num_terms, wcount = 1, temp;
128 struct decorr_pass *dpp;
129 uchar *byteptr;
131 byteptr = wpmd->data = wpmd->temp_data;
132 wpmd->id = ID_DECORR_SAMPLES;
134 for (dpp = wps->decorr_passes; tcount--; ++dpp)
135 if (wcount) {
136 if (dpp->term > MAX_TERM) {
137 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
138 *byteptr++ = temp;
139 *byteptr++ = temp >> 8;
140 dpp->samples_A [1] = exp2s (temp = log2s (dpp->samples_A [1]));
141 *byteptr++ = temp;
142 *byteptr++ = temp >> 8;
144 if (!(wps->wphdr.flags & MONO_FLAG)) {
145 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
146 *byteptr++ = temp;
147 *byteptr++ = temp >> 8;
148 dpp->samples_B [1] = exp2s (temp = log2s (dpp->samples_B [1]));
149 *byteptr++ = temp;
150 *byteptr++ = temp >> 8;
153 else if (dpp->term < 0) {
154 dpp->samples_A [0] = exp2s (temp = log2s (dpp->samples_A [0]));
155 *byteptr++ = temp;
156 *byteptr++ = temp >> 8;
157 dpp->samples_B [0] = exp2s (temp = log2s (dpp->samples_B [0]));
158 *byteptr++ = temp;
159 *byteptr++ = temp >> 8;
161 else {
162 int m = 0, cnt = dpp->term;
164 while (cnt--) {
165 dpp->samples_A [m] = exp2s (temp = log2s (dpp->samples_A [m]));
166 *byteptr++ = temp;
167 *byteptr++ = temp >> 8;
169 if (!(wps->wphdr.flags & MONO_FLAG)) {
170 dpp->samples_B [m] = exp2s (temp = log2s (dpp->samples_B [m]));
171 *byteptr++ = temp;
172 *byteptr++ = temp >> 8;
175 m++;
179 wcount--;
181 else {
182 CLEAR (dpp->samples_A);
183 CLEAR (dpp->samples_B);
186 wpmd->byte_length = byteptr - (uchar *) wpmd->data;
189 // Allocate room for and copy the configuration information into the specified
190 // metadata structure. Currently, we just store the upper 3 bytes of
191 // config.flags and only in the first block of audio data. Note that this is
192 // for informational purposes not required for playback or decoding (like
193 // whether high or fast mode was specified).
195 static void write_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
197 char *byteptr;
199 byteptr = wpmd->data = wpmd->temp_data;
200 wpmd->id = ID_CONFIG_BLOCK;
201 *byteptr++ = (char) (wpc->config.flags >> 8);
202 *byteptr++ = (char) (wpc->config.flags >> 16);
203 *byteptr++ = (char) (wpc->config.flags >> 24);
204 wpmd->byte_length = byteptr - (char *) wpmd->data;
207 // Pack an entire block of samples (either mono or stereo) into a completed
208 // WavPack block. It is assumed that there is sufficient space for the
209 // completed block at "wps->blockbuff" and that "wps->blockend" points to the
210 // end of the available space. A return value of FALSE indicates an error.
211 // Any unsent metadata is transmitted first, then required metadata for this
212 // block is sent, and finally the compressed integer data is sent. If a "wpx"
213 // stream is required for floating point data or large integer data, then this
214 // must be handled outside this function. To find out how much data was written
215 // the caller must look at the ckSize field of the written WavpackHeader, NOT
216 // the one in the WavpackStream.
218 int pack_start_block (WavpackContext *wpc)
220 WavpackStream *wps = &wpc->stream;
221 WavpackMetadata wpmd;
223 memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader));
225 ((WavpackHeader *) wps->blockbuff)->ckSize = sizeof (WavpackHeader) - 8;
226 ((WavpackHeader *) wps->blockbuff)->block_index = wps->sample_index;
227 ((WavpackHeader *) wps->blockbuff)->block_samples = 0;
228 ((WavpackHeader *) wps->blockbuff)->crc = 0xffffffff;
230 if (wpc->wrapper_bytes) {
231 wpmd.id = ID_RIFF_HEADER;
232 wpmd.byte_length = wpc->wrapper_bytes;
233 wpmd.data = wpc->wrapper_data;
234 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
235 free_metadata (&wpmd);
236 wpc->wrapper_data = NULL;
237 wpc->wrapper_bytes = 0;
240 write_decorr_terms (wps, &wpmd);
241 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
242 free_metadata (&wpmd);
244 write_decorr_weights (wps, &wpmd);
245 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
246 free_metadata (&wpmd);
248 write_decorr_samples (wps, &wpmd);
249 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
250 free_metadata (&wpmd);
252 write_entropy_vars (wps, &wpmd);
253 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
254 free_metadata (&wpmd);
256 if ((wps->wphdr.flags & INITIAL_BLOCK) && !wps->sample_index) {
257 write_config_info (wpc, &wpmd);
258 copy_metadata (&wpmd, wps->blockbuff, wps->blockend);
259 free_metadata (&wpmd);
262 bs_open_write (&wps->wvbits, wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12, wps->blockend);
264 return TRUE;
267 static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr, int m);
268 static void decorr_stereo_pass_18 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
269 static void decorr_stereo_pass_17 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
270 static void decorr_stereo_pass_m2 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr);
272 int pack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count)
274 WavpackStream *wps = &wpc->stream;
275 uint32_t flags = wps->wphdr.flags;
276 struct decorr_pass *dpp;
277 int32_t *bptr, *eptr;
278 int tcount, m;
279 uint32_t crc;
281 if (!sample_count)
282 return TRUE;
284 eptr = buffer + sample_count * ((flags & MONO_FLAG) ? 1 : 2);
285 m = ((WavpackHeader *) wps->blockbuff)->block_samples & (MAX_TERM - 1);
286 crc = ((WavpackHeader *) wps->blockbuff)->crc;
288 /////////////////////// handle lossless mono mode /////////////////////////
290 if (!(flags & HYBRID_FLAG) && (flags & MONO_FLAG))
291 for (bptr = buffer; bptr < eptr;) {
292 int32_t code;
294 crc = crc * 3 + (code = *bptr);
296 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) {
297 int32_t sam;
299 if (dpp->term > MAX_TERM) {
300 if (dpp->term & 1)
301 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
302 else
303 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
305 dpp->samples_A [1] = dpp->samples_A [0];
306 dpp->samples_A [0] = code;
308 else {
309 sam = dpp->samples_A [m];
310 dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = code;
313 code -= apply_weight_i (dpp->weight_A, sam);
314 update_weight (dpp->weight_A, 2, sam, code);
317 m = (m + 1) & (MAX_TERM - 1);
318 *bptr++ = code;
321 //////////////////// handle the lossless stereo mode //////////////////////
323 else if (!(flags & HYBRID_FLAG) && !(flags & MONO_FLAG)) {
324 if (flags & JOINT_STEREO)
325 for (bptr = buffer; bptr < eptr; bptr += 2) {
326 crc = crc * 9 + (bptr [0] * 3) + bptr [1];
327 bptr [1] += ((bptr [0] -= bptr [1]) >> 1);
329 else
330 for (bptr = buffer; bptr < eptr; bptr += 2)
331 crc = crc * 9 + (bptr [0] * 3) + bptr [1];
333 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) {
334 if (dpp->term == 17)
335 decorr_stereo_pass_17 (dpp, buffer, eptr);
336 else if (dpp->term == 18)
337 decorr_stereo_pass_18 (dpp, buffer, eptr);
338 else if (dpp->term >= 1 && dpp->term <= 7)
339 decorr_stereo_pass (dpp, buffer, eptr, m);
340 else if (dpp->term == -2)
341 decorr_stereo_pass_m2 (dpp, buffer, eptr);
345 send_words (buffer, sample_count, flags, &wps->w, &wps->wvbits);
346 ((WavpackHeader *) wps->blockbuff)->crc = crc;
347 ((WavpackHeader *) wps->blockbuff)->block_samples += sample_count;
348 wps->sample_index += sample_count;
350 return TRUE;
353 static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr, int m)
355 int k = (m + dpp->term) & (MAX_TERM - 1);
356 int32_t sam;
358 while (bptr < eptr) {
359 dpp->samples_A [k] = bptr [0];
360 bptr [0] -= apply_weight_i (dpp->weight_A, (sam = dpp->samples_A [m]));
361 update_weight (dpp->weight_A, 2, sam, bptr [0]);
362 bptr++;
363 dpp->samples_B [k] = bptr [0];
364 bptr [0] -= apply_weight_i (dpp->weight_B, (sam = dpp->samples_B [m]));
365 update_weight (dpp->weight_B, 2, sam, bptr [0]);
366 bptr++;
367 m = (m + 1) & (MAX_TERM - 1);
368 k = (k + 1) & (MAX_TERM - 1);
372 static void decorr_stereo_pass_18 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
374 int32_t sam;
376 while (bptr < eptr) {
377 sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1;
378 dpp->samples_A [1] = dpp->samples_A [0];
379 dpp->samples_A [0] = bptr [0];
380 bptr [0] -= apply_weight_i (dpp->weight_A, sam);
381 update_weight (dpp->weight_A, 2, sam, bptr [0]);
382 bptr++;
383 sam = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1;
384 dpp->samples_B [1] = dpp->samples_B [0];
385 dpp->samples_B [0] = bptr [0];
386 bptr [0] -= apply_weight_i (dpp->weight_B, sam);
387 update_weight (dpp->weight_B, 2, sam, bptr [0]);
388 bptr++;
392 static void decorr_stereo_pass_m2 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
394 int32_t sam_A, sam_B;
396 for (; bptr < eptr; bptr += 2) {
397 sam_A = bptr [1];
398 sam_B = dpp->samples_B [0];
399 dpp->samples_B [0] = bptr [0];
400 bptr [0] -= apply_weight_i (dpp->weight_A, sam_A);
401 update_weight_clip (dpp->weight_A, 2, sam_A, bptr [0]);
402 bptr [1] -= apply_weight_i (dpp->weight_B, sam_B);
403 update_weight_clip (dpp->weight_B, 2, sam_B, bptr [1]);
407 static void decorr_stereo_pass_17 (struct decorr_pass *dpp, int32_t *bptr, int32_t *eptr)
409 int32_t sam;
411 while (bptr < eptr) {
412 sam = 2 * dpp->samples_A [0] - dpp->samples_A [1];
413 dpp->samples_A [1] = dpp->samples_A [0];
414 dpp->samples_A [0] = bptr [0];
415 bptr [0] -= apply_weight_i (dpp->weight_A, sam);
416 update_weight (dpp->weight_A, 2, sam, bptr [0]);
417 bptr++;
418 sam = 2 * dpp->samples_B [0] - dpp->samples_B [1];
419 dpp->samples_B [1] = dpp->samples_B [0];
420 dpp->samples_B [0] = bptr [0];
421 bptr [0] -= apply_weight_i (dpp->weight_B, sam);
422 update_weight (dpp->weight_B, 2, sam, bptr [0]);
423 bptr++;
427 int pack_finish_block (WavpackContext *wpc)
429 WavpackStream *wps = &wpc->stream;
430 struct decorr_pass *dpp;
431 uint32_t data_count;
432 int tcount, m;
434 m = ((WavpackHeader *) wps->blockbuff)->block_samples & (MAX_TERM - 1);
436 if (m)
437 for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++)
438 if (dpp->term > 0 && dpp->term <= MAX_TERM) {
439 int32_t temp_A [MAX_TERM], temp_B [MAX_TERM];
440 int k;
442 memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A));
443 memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B));
445 for (k = 0; k < MAX_TERM; k++) {
446 dpp->samples_A [k] = temp_A [m];
447 dpp->samples_B [k] = temp_B [m];
448 m = (m + 1) & (MAX_TERM - 1);
452 flush_word (&wps->w, &wps->wvbits);
453 data_count = bs_close_write (&wps->wvbits);
455 if (data_count) {
456 if (data_count != (uint32_t) -1) {
457 uchar *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8;
459 *cptr++ = ID_WV_BITSTREAM | ID_LARGE;
460 *cptr++ = data_count >> 1;
461 *cptr++ = data_count >> 9;
462 *cptr++ = data_count >> 17;
463 ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4;
465 else
466 return FALSE;
469 return TRUE;