1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 // To do
23
24 // Sound error handling (when sound too short)
25 // rle b4 huffing
26 // adpcm encoding of sound
27
28 #if 0
29 #include "qdata.h"
30 #include "flex.h"
31 #include "fc.h"
32 #include "adpcm.h"
33
34 #define MIN_REPT 15
35 #define MAX_REPT 0
36 #define HUF_TOKENS (256 + MAX_REPT)
37
38 #define BLOCKSIZE 8
39
40 #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
41 #define SQRT2 1.414213562
42
43 typedef struct hnode_s
44 {
45 int count;
46 qboolean used;
47 int children[2];
48 } hnode_t;
49
50 typedef struct
51 {
52 int rate;
53 int width;
54 int channels;
55 int loopstart;
56 int samples;
57 int dataofs; // chunk starts this many bytes from file start
58 } wavinfo_t;
59
60 // These weren`t picked out my ass....
61 // They were defined at http://www.rahul.net/jfm/dct.html
62 // However, I think he plucked them out of his ass.....
63
64 float Quantise[BLOCKSIZE * BLOCKSIZE];
65
66 float LUT_Quantise[BLOCKSIZE * BLOCKSIZE] =
67 {
68 16.0F/16.0F, 11.0F/16.0F, 10.0F/16.0F, 16.0F/16.0F, 24.0F/16.0F, 40.0F/16.0F, 51.0F/16.0F, 61.0F/16.0F,
69 12.0F/16.0F, 13.0F/16.0F, 14.0F/16.0F, 19.0F/16.0F, 26.0F/16.0F, 58.0F/16.0F, 60.0F/16.0F, 55.0F/16.0F,
70 14.0F/16.0F, 13.0F/16.0F, 16.0F/16.0F, 24.0F/16.0F, 40.0F/16.0F, 57.0F/16.0F, 69.0F/16.0F, 56.0F/16.0F,
71 14.0F/16.0F, 17.0F/16.0F, 22.0F/16.0F, 29.0F/16.0F, 51.0F/16.0F, 87.0F/16.0F, 80.0F/16.0F, 62.0F/16.0F,
72 18.0F/16.0F, 22.0F/16.0F, 37.0F/16.0F, 56.0F/16.0F, 68.0F/16.0F,109.0F/16.0F,103.0F/16.0F, 77.0F/16.0F,
73 24.0F/16.0F, 35.0F/16.0F, 55.0F/16.0F, 64.0F/16.0F, 81.0F/16.0F,104.0F/16.0F,113.0F/16.0F, 92.0F/16.0F,
74 49.0F/16.0F, 64.0F/16.0F, 78.0F/16.0F, 87.0F/16.0F,103.0F/16.0F,121.0F/16.0F,120.0F/16.0F,101.0F/16.0F,
75 72.0F/16.0F, 92.0F/16.0F, 95.0F/16.0F, 98.0F/16.0F,112.0F/16.0F,100.0F/16.0F,103.0F/16.0F, 99.0F/16.0F
76 };
77
78 int LUT_ZZ[BLOCKSIZE * BLOCKSIZE] =
79 {
80 0,
81 1, 8,
82 16, 9, 2,
83 3, 10, 17, 24,
84 32, 25, 18, 11, 4,
85 5, 12, 19, 26, 33, 40,
86 48, 41, 34, 27, 20, 13, 6,
87 7, 14, 21, 28, 35, 42, 49, 56,
88 57, 50, 43, 36, 29, 22, 15,
89 23, 30, 37, 44, 51, 58,
90 59, 52, 45, 38, 31,
91 39, 46, 53, 60,
92 61, 54, 47,
93 55, 62,
94 63
95 };
96
97 char base[32];
98
99 byte *soundtrack;
100
101 byte scaled[256][HUF_TOKENS];
102 unsigned int charbits1[256][HUF_TOKENS];
103 int charbitscount1[256][HUF_TOKENS];
104 hnode_t hnodes1[256][HUF_TOKENS * 2];
105 int numhnodes1[256];
106 int order0counts[256];
107 int numhnodes;
108 hnode_t hnodes[512];
109 unsigned charbits[256];
110 int charbitscount[256];
111
112 CineHead_t cinehead;
113
114 byte *data_p;
115 byte *iff_end;
116 byte *last_chunk;
117 byte *iff_data;
118 int iff_chunk_len;
119
120 float dctbase[BLOCKSIZE][BLOCKSIZE];
121 float red[BLOCKSIZE * BLOCKSIZE];
122 float green[BLOCKSIZE * BLOCKSIZE];
123 float blue[BLOCKSIZE * BLOCKSIZE];
124 float temp[BLOCKSIZE * BLOCKSIZE];
125
126 wavinfo_t wavinfo;
127 adpcm_t adpcm;
128
129 /*
130 ===============================================================================
131
132 WAV loading
133
134 ===============================================================================
135 */
136
137 /* Intel ADPCM step variation table */
138 static int indexTable[16] =
139 {
140 -1, -1, -1, -1, 2, 4, 6, 8,
141 -1, -1, -1, -1, 2, 4, 6, 8,
142 };
143
144 static int stepsizeTable[89] =
145 {
146 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
147 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
148 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
149 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
150 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
151 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
152 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
153 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
154 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
155 };
156
157 #if 0
158 static void adpcm_decoder(char *indata, short *outdata, int len, adpcm_state_t *state)
159 {
160 signed char *inp; /* Input buffer pointer */
161 short *outp; /* output buffer pointer */
162 int sign; /* Current adpcm sign bit */
163 int delta; /* Current adpcm output value */
164 int step; /* Stepsize */
165 int valpred; /* Predicted value */
166 int vpdiff; /* Current change to valpred */
167 int index; /* Current step change index */
168 int inputbuffer; /* place to keep next 4-bit value */
169 int bufferstep; /* toggle between inputbuffer/input */
170
171 outp = outdata;
172 inp = (signed char *)indata;
173
174 valpred = state->valprev;
175 index = state->index;
176 step = stepsizeTable[index];
177
178 bufferstep = 0;
179
180 for(; len > 0; len--)
181 {
182 /* Step 1 - get the delta value */
183 if (bufferstep)
184 delta = inputbuffer & 0xf;
185 else
186 {
187 inputbuffer = *inp++;
188 delta = (inputbuffer >> 4) & 0xf;
189 }
190 bufferstep = !bufferstep;
191
192 /* Step 2 - Find new index value (for later) */
193 index += indexTable[delta];
194 if(index < 0)
195 index = 0;
196 if(index > 88)
197 index = 88;
198
199 /* Step 3 - Separate sign and magnitude */
200 sign = delta & 8;
201 delta = delta & 7;
202
203 /* Step 4 - Compute difference and new predicted value */
204 /*
205 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
206 ** in adpcm_coder.
207 */
208 vpdiff = step >> 3;
209 if(delta & 4)
210 vpdiff += step;
211 if(delta & 2)
212 vpdiff += step>>1;
213 if(delta & 1)
214 vpdiff += step>>2;
215
216 if (sign)
217 valpred -= vpdiff;
218 else
219 valpred += vpdiff;
220
221 /* Step 5 - clamp output value */
222 if (valpred > 32767)
223 valpred = 32767;
224 else if (valpred < -32768)
225 valpred = -32768;
226
227 /* Step 6 - Update step value */
228 step = stepsizeTable[index];
229
230 /* Step 7 - Output value */
231 *outp++ = valpred;
232 }
233
234 state->valprev = valpred;
235 state->index = index;
236 }
237 #endif
238
239 void adpcm_coder(short *inp, adpcm_t *adpcm)
240 {
241 int val; /* Current input sample value */
242 int sign; /* Current adpcm sign bit */
243 int delta; /* Current adpcm output value */
244 int diff; /* Difference between val and valprev */
245 int step; /* Stepsize */
246 int valpred; /* Predicted output value */
247 int vpdiff; /* Current change to valpred */
248 int index; /* Current step change index */
249 int outputbuffer; /* place to keep previous 4-bit value */
250 int bufferstep; /* toggle between outputbuffer/output */
251 adpcm_state_t *state;
252 char *outp;
253 int len;
254
255 state = &adpcm->state;
256 len = state->count;
257 outp = adpcm->adpcm;
258
259 valpred = state->in_valprev;
260 index = state->in_index;
261 step = stepsizeTable[index];
262
263 bufferstep = 1;
264 while(len--)
265 {
266 val = *inp++;
267
268 /* Step 1 - compute difference with previous value */
269 diff = val - valpred;
270 sign = (diff < 0) ? 8 : 0;
271 if (sign)
272 diff = -diff;
273
274 /* Step 2 - Divide and clamp */
275 /* Note:
276 ** This code *approximately* computes:
277 ** delta = diff*4/step;
278 ** vpdiff = (delta+0.5)*step/4;
279 ** but in shift step bits are dropped. The net result of this is
280 ** that even if you have fast mul/div hardware you cannot put it to
281 ** good use since the fixup would be too expensive.
282 */
283 delta = 0;
284 vpdiff = (step >> 3);
285
286 if (diff >= step)
287 {
288 delta = 4;
289 diff -= step;
290 vpdiff += step;
291 }
292 step >>= 1;
293 if (diff >= step)
294 {
295 delta |= 2;
296 diff -= step;
297 vpdiff += step;
298 }
299 step >>= 1;
300 if (diff >= step)
301 {
302 delta |= 1;
303 vpdiff += step;
304 }
305
306 /* Step 3 - Update previous value */
307 if (sign)
308 valpred -= vpdiff;
309 else
310 valpred += vpdiff;
311
312 /* Step 4 - Clamp previous value to 16 bits */
313 if (valpred > 32767)
314 valpred = 32767;
315 else if (valpred < -32768)
316 valpred = -32768;
317
318 /* Step 5 - Assemble value, update index and step values */
319 delta |= sign;
320
321 index += indexTable[delta];
322 if (index < 0)
323 index = 0;
324 if (index > 88)
325 index = 88;
326 step = stepsizeTable[index];
327
328 /* Step 6 - Output value */
329 if (bufferstep)
330 outputbuffer = (delta << 4) & 0xf0;
331 else
332 *outp++ = (delta & 0x0f) | outputbuffer;
333
334 bufferstep = !bufferstep;
335 }
336
337 /* Output last step, if needed */
338 if(!bufferstep)
339 *outp++ = outputbuffer;
340
341 state->out_valprev = valpred;
342 state->out_index = index;
343 }
344
345 void FindNextChunk(char *name)
346 {
347 while(1)
348 {
349 data_p = last_chunk;
350
351 if(data_p >= iff_end)
352 { // didn't find the chunk
353 data_p = NULL;
354 return;
355 }
356
357 data_p += 4;
358 iff_chunk_len = *(long *)data_p;
359 data_p += 4;
360 if(iff_chunk_len < 0)
361 {
362 data_p = NULL;
363 return;
364 }
365
366 data_p -= 8;
367 last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);
368 if (!strncmp(data_p, name, 4))
369 return;
370 }
371 }
372
373 void FindChunk(char *name)
374 {
375 last_chunk = iff_data;
376 FindNextChunk (name);
377 }
378
379 void DumpChunks(void)
380 {
381 char str[5];
382
383 str[4] = 0;
384 data_p = iff_data;
385 do
386 {
387 memcpy (str, data_p, 4);
388 data_p += 4;
389 iff_chunk_len = *(long *)data_p;
390 data_p += 4;
391 printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
392 data_p += (iff_chunk_len + 1) & ~1;
393 }
394 while(data_p < iff_end);
395 }
396
397 /*
398 ============
399 GetWavinfo
400 ============
401 */
402 wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
403 {
404 wavinfo_t info;
405 int i;
406 int format;
407 int samples;
408
409 memset(&info, 0, sizeof(info));
410
411 if (!wav)
412 return(info);
413
414 iff_data = wav;
415 iff_end = wav + wavlength;
416
417 // find "RIFF" chunk
418 FindChunk("RIFF");
419 if (!(data_p && !strncmp(data_p + 8, "WAVE", 4)))
420 {
421 printf("Missing RIFF/WAVE chunks\n");
422 return(info);
423 }
424
425 // get "fmt " chunk
426 iff_data = data_p + 12;
427
428 FindChunk("fmt ");
429 if(!data_p)
430 {
431 printf("Missing fmt chunk\n");
432 return(info);
433 }
434 data_p += 8;
435 format = *(short *)data_p;
436 data_p += 2;
437 if (format != 1)
438 {
439 printf("Microsoft PCM format only\n");
440 return(info);
441 }
442
443 info.channels = *(short *)data_p;
444 data_p += 2;
445 info.rate = *(long *)data_p;
446 data_p += 4;
447 data_p += 6;
448 info.width = *(short *)data_p / 8;
449 data_p += 2;
450
451 // get cue chunk
452 FindChunk("cue ");
453 if(data_p)
454 {
455 data_p += 32;
456 info.loopstart = *(long *)data_p;
457 data_p += 4;
458
459 // if the next chunk is a LIST chunk, look for a cue length marker
460 FindNextChunk ("LIST");
461 if(data_p)
462 {
463 // this is not a proper parse, but it works with cooledit...
464 if (!strncmp (data_p + 28, "mark", 4))
465 {
466 data_p += 24;
467 i = *(long *)data_p; // samples in loop
468 data_p += 4;
469 info.samples = info.loopstart + i;
470 }
471 }
472 }
473 else
474 info.loopstart = -1;
475
476 // find data chunk
477 FindChunk("data");
478 if (!data_p)
479 {
480 printf("Missing data chunk\n");
481 return(info);
482 }
483
484 data_p += 4;
485 samples = *(long *)data_p;
486 data_p += 4;
487
488 if (info.samples)
489 {
490 if(samples < info.samples)
491 Error ("Sound %s has a bad loop length", name);
492 }
493 else
494 info.samples = samples;
495
496 info.dataofs = data_p - wav;
497 return(info);
498 }
499
500 // ==============
501 // LoadSoundtrack
502 // ==============
503
504 void LoadSoundtrack()
505 {
506 char name[1024];
507 FILE *f;
508 int len;
509
510 soundtrack = NULL;
511 sprintf (name, "%svideo/%s/%s.wav", gamedir, base, base);
512 printf ("\nLoading sound : %s\n", name);
513 f = fopen (name, "rb");
514 if (!f)
515 {
516 printf ("\nNo soundtrack for %s\n", base);
517 return;
518 }
519 len = Q_filelength(f);
520 soundtrack = SafeMalloc(len, "LoadSoundtrack");
521 fread(soundtrack, 1, len, f);
522 fclose(f);
523
524 wavinfo = GetWavinfo(name, soundtrack, len);
525 adpcm.state.out_valprev = 0;
526 adpcm.state.out_index = 0;
527 }
528
529 // ==================
530 // WriteSound
531 // ==================
532
533 int WriteSound(FILE *output, int frame, int numframes)
534 {
535 int start, end;
536 int count;
537 int empty = 0;
538 int width;
539 char *work;
540
541 width = wavinfo.width * wavinfo.channels;
542 start = ((frame * wavinfo.rate / 14) + 31) & 0xffffffe0; // start sample
543 end = (((frame + numframes) * wavinfo.rate / 14) + 31) & 0xffffffe0; // end sample
544 count = end - start;
545
546 work = soundtrack + wavinfo.dataofs + (start * width);
547 adpcm.state.count = count * wavinfo.channels; // Number of samples
548 adpcm.state.in_valprev = adpcm.state.out_valprev;
549 adpcm.state.in_index = adpcm.state.out_index;
550 adpcm_coder((short *)work, &adpcm);
551 WriteHeader(output, FC_SOUND_22KMADPCM, FC_ADPCM_VERSION, (adpcm.state.count / 2) + sizeof(adpcm_state_t), (char *)&adpcm);
552 return(count / 2);
553 }
554 // ==============================
555 // Basic run length encoder
556 // ==============================
557
558 char *RLEZZ(char *in, char *out)
559 {
560 int srun;
561 char count;
562 int idx = 0;
563
564 while(idx < 64)
565 {
566 srun = idx; // Start of run
567
568 while(idx < 63)
569 {
570 if(in[LUT_ZZ[idx]] != in[LUT_ZZ[idx + 1]])
571 break;
572 idx++;
573 }
574 count = (char)(idx - srun); // count of repeated bytes
575
576 if(!count)
577 {
578 while(idx < 63)
579 {
580 if(in[LUT_ZZ[idx]] == in[LUT_ZZ[idx + 1]])
581 break;
582 idx++;
583 }
584 if(idx == 63)
585 idx++;
586
587 count = (char)(idx - srun); // count of unique bytes
588 *out++ = count;
589 while(count--)
590 *out++ = in[LUT_ZZ[srun++]];
591 }
592 else
593 {
594 *out++ = -(count + 1);
595 *out++ = in[LUT_ZZ[idx]];
596 idx++;
597 }
598 }
599 return(out);
600 }
601
602 // ==============================
603 // Discrete Cosine Transformation
604 // ==============================
605
606 void init_base(float quant)
607 {
608 int y, x;
609
610 for(y = 0; y < BLOCKSIZE; y++)
611 for(x = 0; x < BLOCKSIZE; x++)
612 {
613 if(y == 0)
614 dctbase[y][x] = 1;
615 else
616 dctbase[y][x] = SQRT2 * cos(((x * 2 + 1) * y * M_PI) / (BLOCKSIZE * 2));
617 }
618
619 for(y = 0; y < BLOCKSIZE * BLOCKSIZE; y++)
620 Quantise[y] = LUT_Quantise[y] / quant;
621 }
622
623 void SplitComponents(byte *src, int width, int height)
624 {
625 int i, j;
626 float *tr = red;
627 float *tg = green;
628 float *tb = blue;
629
630 for(i = 0; i < BLOCKSIZE; i++, src += (width - BLOCKSIZE) * 4)
631 for(j = 0; j < BLOCKSIZE; j++)
632 {
633 *tr++ = ((float)*src++) - 128.0F;
634 *tg++ = ((float)*src++) - 128.0F;
635 *tb++ = ((float)*src++) - 128.0F;
636 src++;
637 }
638 }
639
640 void transferH(float *src, float *dst)
641 {
642 int y, dx, dy;
643 float sum;
644 float *work;
645
646 for(y = 0; y < BLOCKSIZE; y++, src += BLOCKSIZE)
647 {
648 for(dy = 0; dy < BLOCKSIZE; dy++)
649 {
650 sum = 0;
651 work = src;
652 for(dx = 0; dx < BLOCKSIZE; dx++, work++)
653 sum += dctbase[dy][dx] * *work;
654
655 *dst++ = sum / BLOCKSIZE;
656 }
657 }
658 }
659
660 void transferV(float *src, float *dst)
661 {
662 int x, dy, fy;
663 float sum;
664 float *work;
665
666 for(x = 0; x < BLOCKSIZE; x++, src++, dst++)
667 {
668 for(fy = 0; fy < BLOCKSIZE; fy++)
669 {
670 sum = 0;
671 work = src;
672 for(dy = 0; dy < BLOCKSIZE; dy++, work += BLOCKSIZE)
673 sum += dctbase[fy][dy] * *work;
674
675 dst[fy * BLOCKSIZE] = sum / BLOCKSIZE;
676 }
677 }
678 }
679
680 char *Combine(byte *dst, float *p, float *q)
681 {
682 int i, j;
683 byte rlesrc[BLOCKSIZE * BLOCKSIZE];
684 int c;
685 byte *work;
686
687 work = rlesrc;
688 for(j = 0; j < BLOCKSIZE; j++)
689 for(i = 0; i < BLOCKSIZE; i++)
690 {
691 c = (int)((*p++ / *q++) + 128.5F);
692 c -= 128;
693
694 if(c < -128)
695 c = -128;
696 if(c > 127)
697 c = 127;
698
699 *work++ = (char)c;
700 }
701
702 dst = RLEZZ(rlesrc, dst);
703 return(dst);
704 }
705
706 char *CombineComponents(char *dst, int width, int height)
707 {
708 dst = Combine(dst, red, Quantise);
709 dst = Combine(dst, green, Quantise);
710 dst = Combine(dst, blue, Quantise);
711 return(dst);
712 }
713
714 void DCT(cblock_t *out, cblock_t in, int width, int height)
715 {
716 int x, y;
717 char *cursrc;
718 char *curdst;
719
720 curdst = out->data;
721 for(y = 0; y < height; y += BLOCKSIZE)
722 for(x = 0; x < width; x += BLOCKSIZE)
723 {
724 cursrc = in.data + ((y * width) + x) * 4;
725 SplitComponents(cursrc, width, height);
726 transferH(red, temp);
727 transferV(temp, red);
728 transferH(green, temp);
729 transferV(temp, green);
730 transferH(blue, temp);
731 transferV(temp, blue);
732 curdst = CombineComponents(curdst, width, height);
733 }
734 out->count = curdst - out->data;
735 }
736
737 // ==================
738 // BuildChars1
739 // ==================
740
741 void BuildChars1(int prev, int nodenum, unsigned bits, int bitcount)
742 {
743 hnode_t *node;
744
745 if(nodenum < HUF_TOKENS)
746 {
747 if (bitcount > 32)
748 Error("bitcount > 32");
749 charbits1[prev][nodenum] = bits;
750 charbitscount1[prev][nodenum] = bitcount;
751 return;
752 }
753
754 node = &hnodes1[prev][nodenum];
755 bits <<= 1;
756 BuildChars1(prev, node->children[0], bits, bitcount+1);
757 bits |= 1;
758 BuildChars1(prev, node->children[1], bits, bitcount+1);
759 }
760
761 // ==================
762 // SmallestNode1
763 // ==================
764
765 int SmallestNode1(hnode_t *hnodes, int numhnodes)
766 {
767 int i;
768 int best, bestnode;
769
770 best = 99999999;
771 bestnode = -1;
772 for(i = 0; i < numhnodes; i++)
773 {
774 if(hnodes[i].used)
775 continue;
776 if(!hnodes[i].count)
777 continue;
778 if(hnodes[i].count < best)
779 {
780 best = hnodes[i].count;
781 bestnode = i;
782 }
783 }
784
785 if (bestnode == -1)
786 return(-1);
787
788 hnodes[bestnode].used = true;
789 return(bestnode);
790 }
791
792 // ==================
793 // BuildTree1
794 // ==================
795
796 void BuildTree1(int prev)
797 {
798 hnode_t *node, *nodebase;
799 int numhnodes;
800
801 // build the nodes
802 numhnodes = HUF_TOKENS;
803 nodebase = hnodes1[prev];
804 while(1)
805 {
806 node = &nodebase[numhnodes];
807
808 // pick two lowest counts
809 node->children[0] = SmallestNode1 (nodebase, numhnodes);
810 if (node->children[0] == -1)
811 break; // no more
812
813 node->children[1] = SmallestNode1 (nodebase, numhnodes);
814 if (node->children[1] == -1)
815 break;
816
817 node->count = nodebase[node->children[0]].count +
818 nodebase[node->children[1]].count;
819 numhnodes++;
820 }
821 numhnodes1[prev] = numhnodes-1;
822 BuildChars1 (prev, numhnodes-1, 0, 0);
823 }
824
825 // ==================
826 // Huffman1_Count
827 // ==================
828
829 void Huffman1_Count(cblock_t in)
830 {
831 int i;
832 int prev;
833 int v;
834 int rept;
835
836 prev = 0;
837 for(i = 0; i < in.count; i++)
838 {
839 v = in.data[i];
840 order0counts[v]++;
841 hnodes1[prev][v].count++;
842 prev = v;
843
844 for(rept = 1; (i + rept < in.count) && (rept < MAX_REPT); rept++)
845 if(in.data[i+rept] != v)
846 break;
847 if(rept > MIN_REPT)
848 {
849 hnodes1[prev][255 + rept].count++;
850 i += rept - 1;
851 }
852 }
853 }
854
855 // ==================
856 // Huffman1_Build
857 // ==================
858
859 void Huffman1_Build()
860 {
861 int i, j, v;
862 int max;
863 int total;
864
865 for(i = 0; i < 256; i++)
866 {
867 // normalize and save the counts
868 max = 0;
869 for (j = 0; j < HUF_TOKENS; j++)
870 {
871 if (hnodes1[i][j].count > max)
872 max = hnodes1[i][j].count;
873 }
874 if (max == 0)
875 max = 1;
876 total = 0;
877 // easy to overflow 32 bits here!
878 for(j = 0; j < HUF_TOKENS; j++)
879 {
880 v = (hnodes1[i][j].count * (double) 255 + max - 1) / max;
881 if (v > 255)
882 Error ("v > 255");
883 scaled[i][j] = hnodes1[i][j].count = v;
884 if (v)
885 total++;
886 }
887 if (total == 1)
888 { // must have two tokens
889 if (!scaled[i][0])
890 scaled[i][0] = hnodes1[i][0].count = 1;
891 else
892 scaled[i][1] = hnodes1[i][1].count = 1;
893 }
894 BuildTree1 (i);
895 }
896 }
897
898 // ==================
899 // Huffman1
900 // Order 1 compression with pre-built table
901 // ==================
902
903 cblock_t Huffman1(cblock_t in)
904 {
905 int i;
906 int outbits, c;
907 unsigned bits;
908 byte *out_p;
909 cblock_t out;
910 int prev;
911 int v;
912 int rept;
913
914 out_p = out.data = SafeMalloc((in.count * 2) + 1024 + 4, "Huffman");
915 memset(out_p, 0, (in.count * 2) + 1024 + 4);
916
917 // leave space for compressed count
918 out_p += 4;
919 // write count
920 *(long *)out_p = in.count;
921 out_p += 4;
922
923 // write bits
924 outbits = 0;
925 prev = 0;
926 for(i = 0; i < in.count; i++)
927 {
928 v = in.data[i];
929
930 c = charbitscount1[prev][v];
931 bits = charbits1[prev][v];
932 if (!c)
933 Error ("!bits");
934 while (c)
935 {
936 c--;
937 if (bits & (1 << c))
938 out_p[outbits>>3] |= 1 << (outbits & 7);
939 outbits++;
940 }
941
942 prev = v;
943 // check for repeat encodes
944 for(rept = 1; (i + rept < in.count) && (rept < MAX_REPT); rept++)
945 if(in.data[i + rept] != v)
946 break;
947 if (rept > MIN_REPT)
948 {
949 c = charbitscount1[prev][255 + rept];
950 bits = charbits1[prev][255 + rept];
951 if (!c)
952 Error ("!bits");
953 while (c)
954 {
955 c--;
956 if(bits & (1 << c))
957 out_p[outbits >> 3] |= 1 << (outbits & 7);
958 outbits++;
959 }
960 i += rept - 1;
961 }
962 }
963 out_p += (outbits + 7) >> 3;
964 out.count = out_p - out.data;
965
966 out_p = out.data;
967 *(long *)out_p = out.count;
968 return(out);
969 }
970 // ===================
971 // LoadFrame
972 // ===================
973
974 void LoadFrame(cblock_t *out, char *base, int frame)
975 {
976 cblock_t in;
977 int width, height;
978 char name[1024];
979 FILE *f;
980
981 in.data = NULL;
982 in.count = -1;
983 sprintf (name, "%svideo/%s/%s%04i.tga", gamedir, base, base, frame);
984
985 f = fopen(name, "rb");
986 if (!f)
987 {
988 out->data = NULL;
989 return;
990 }
991 fclose (f);
992
993 LoadTGA(name, &in.data, &width, &height);
994 if((width != cinehead.Width) || (height != cinehead.Height))
995 {
996 free(in.data);
997 printf("Invalid picture size\n");
998 out->data = NULL;
999 return;
1000 }
1001 out->data = SafeMalloc(width * height * 3, "LoadFrame"); // rle could possibly expand file so this not 100% safe (however DCT should force a lot of compression)
1002 DCT(out, in, width, height);
1003 free(in.data);
1004 }
1005
1006 // ==================================
1007 // Cmd_Video
1008 //
1009 // video <directory> <framedigits>
1010 // ==================================
1011
1012 void Cmd_Video()
1013 {
1014 char savename[256];
1015 char name[256];
1016 FILE *output;
1017 int frame;
1018 int width, height;
1019 cblock_t in, huffman;
1020 int size;
1021 float dctconst;
1022 int maxsize, ssize;
1023 int min_rle_size, warnings;
1024 int ave_image, ave_sound;
1025
1026 GetScriptToken(false);
1027 strcpy(base, token);
1028 if (g_release)
1029 return;
1030
1031 GetScriptToken(false);
1032 dctconst = atof(token);
1033 GetScriptToken(false);
1034 maxsize = atoi(token);
1035
1036 sprintf (savename, "%svideo/%s.cin", gamedir, base);
1037
1038 // clear stuff
1039 memset(charbits1, 0, sizeof(charbits1));
1040 memset(charbitscount1, 0, sizeof(charbitscount1));
1041 memset(hnodes1, 0, sizeof(hnodes1));
1042 memset(numhnodes1, 0, sizeof(numhnodes1));
1043 memset(order0counts, 0, sizeof(order0counts));
1044
1045 // load the entire sound wav file if present
1046 LoadSoundtrack();
1047
1048 cinehead.SndRate = wavinfo.rate;
1049 cinehead.SndWidth = wavinfo.width;
1050 cinehead.SndChannels = wavinfo.channels;
1051
1052 sprintf(name, "%svideo/%s/%s0000.tga", gamedir, base, base);
1053 printf("Loading sequence : %s\n", name);
1054 printf("DCT constant : %f\n", dctconst);
1055
1056 LoadTGA (name, NULL, &width, &height);
1057
1058 output = fopen (savename, "wb");
1059 if (!output)
1060 Error ("Can't open %s", savename);
1061
1062 if((width % BLOCKSIZE) || (height % BLOCKSIZE))
1063 Error("Width and height must be a multiple of %d", BLOCKSIZE);
1064
1065 cinehead.Width = width;
1066 cinehead.Height = height;
1067 init_base(dctconst);
1068
1069 // build the dictionary
1070 printf("Counting : ");
1071 min_rle_size = 0;
1072 for (frame = 0; ; frame++)
1073 {
1074 printf(".");
1075 LoadFrame(&in, base, frame);
1076 if(!in.data)
1077 break;
1078 Huffman1_Count(in);
1079 if(in.count > min_rle_size)
1080 min_rle_size = in.count;
1081 free(in.data);
1082 }
1083 printf ("\n");
1084 cinehead.NumFrames = frame;
1085 printf("Num Frames : %d\n", frame);
1086 cinehead.MaxRleSize = (min_rle_size + 0x1f) & 0xfffffe0;
1087 cinehead.MaxSndSize = ((4 * wavinfo.rate * wavinfo.channels / 14) + 0x1f) & 0xffffffe0;
1088
1089 WriteHeader(output, FC_HEADER_NAME, FC_HEADER_VERSION, sizeof(CineHead_t), &cinehead);
1090
1091 // build nodes and write counts
1092 Huffman1_Build();
1093 WriteHeader(output, FC_HUFFBITS_NAME, FC_HUFFBITS_VERSION, sizeof(scaled), scaled);
1094 WriteHeader(output, FC_QUANT_NAME, FC_QUANT_VERSION, sizeof(Quantise), Quantise);
1095
1096 ave_image = 0;
1097 ave_sound = 0;
1098 warnings = 0;
1099 // compress it with the dictionary
1100 if(soundtrack)
1101 {
1102 ssize = WriteSound(output, frame, 4);
1103 ave_sound += ssize;
1104 }
1105
1106 for (frame = 0; frame < cinehead.NumFrames; frame++)
1107 {
1108 // save some sound samples
1109 printf ("Packing : ", frame);
1110 LoadFrame(&in, base, frame);
1111
1112 // save the image
1113 huffman = Huffman1(in);
1114 printf ("%d bytes rle, %d bytes huffman", in.count, huffman.count);
1115 size = (huffman.count + 3) & 0xfffffffc; // round up to longwords
1116 if(size > maxsize)
1117 {
1118 printf(" ** WARNING **");
1119 warnings++;
1120 }
1121 printf("\n");
1122 ave_image += huffman.count;
1123
1124 WriteHeader(output, FC_IMAGE_NAME, FC_IMAGE_VERSION, size, huffman.data);
1125 if(soundtrack)
1126 {
1127 ssize = WriteSound(output, frame + 4, 1);
1128 ave_sound += ssize;
1129 }
1130
1131 free (in.data);
1132 free (huffman.data);
1133 }
1134 printf("\nTotal size: %d (headers + %d image + %d sound)\n", ftell(output), ave_image, ave_sound);
1135 printf("Data rate : %d bytes per sec (image and sound)\n", (ave_image + ave_sound) / cinehead.NumFrames);
1136 printf("Cin created ok with %d warnings.\n", warnings);
1137 fclose (output);
1138
1139 if (soundtrack)
1140 free (soundtrack);
1141 }
1142 #endif
1143
Cmd_Video()1144 void Cmd_Video()
1145 {
1146 }
1147
1148 // end
1149
1150