2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
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.
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.
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
24 // Sound error handling (when sound too short)
26 // adpcm encoding of sound
36 #define HUF_TOKENS (256 + MAX_REPT)
40 #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
41 #define SQRT2 1.414213562
43 typedef struct hnode_s
57 int dataofs; // chunk starts this many bytes from file start
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.....
64 float Quantise[BLOCKSIZE * BLOCKSIZE];
66 float LUT_Quantise[BLOCKSIZE * BLOCKSIZE] =
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
78 int LUT_ZZ[BLOCKSIZE * BLOCKSIZE] =
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,
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];
106 int order0counts[256];
109 unsigned charbits[256];
110 int charbitscount[256];
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];
130 ===============================================================================
134 ===============================================================================
137 /* Intel ADPCM step variation table */
138 static int indexTable[16] =
140 -1, -1, -1, -1, 2, 4, 6, 8,
141 -1, -1, -1, -1, 2, 4, 6, 8,
144 static int stepsizeTable[89] =
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
158 static void adpcm_decoder(char *indata, short *outdata, int len, adpcm_state_t *state)
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 */
172 inp = (signed char *)indata;
174 valpred = state->valprev;
175 index = state->index;
176 step = stepsizeTable[index];
180 for(; len > 0; len--)
182 /* Step 1 - get the delta value */
184 delta = inputbuffer & 0xf;
187 inputbuffer = *inp++;
188 delta = (inputbuffer >> 4) & 0xf;
190 bufferstep = !bufferstep;
192 /* Step 2 - Find new index value (for later) */
193 index += indexTable[delta];
199 /* Step 3 - Separate sign and magnitude */
203 /* Step 4 - Compute difference and new predicted value */
205 ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
221 /* Step 5 - clamp output value */
224 else if (valpred < -32768)
227 /* Step 6 - Update step value */
228 step = stepsizeTable[index];
230 /* Step 7 - Output value */
234 state->valprev = valpred;
235 state->index = index;
239 void adpcm_coder(short *inp, adpcm_t *adpcm)
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;
255 state = &adpcm->state;
259 valpred = state->in_valprev;
260 index = state->in_index;
261 step = stepsizeTable[index];
268 /* Step 1 - compute difference with previous value */
269 diff = val - valpred;
270 sign = (diff < 0) ? 8 : 0;
274 /* Step 2 - Divide and clamp */
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.
284 vpdiff = (step >> 3);
306 /* Step 3 - Update previous value */
312 /* Step 4 - Clamp previous value to 16 bits */
315 else if (valpred < -32768)
318 /* Step 5 - Assemble value, update index and step values */
321 index += indexTable[delta];
326 step = stepsizeTable[index];
328 /* Step 6 - Output value */
330 outputbuffer = (delta << 4) & 0xf0;
332 *outp++ = (delta & 0x0f) | outputbuffer;
334 bufferstep = !bufferstep;
337 /* Output last step, if needed */
339 *outp++ = outputbuffer;
341 state->out_valprev = valpred;
342 state->out_index = index;
345 void FindNextChunk(char *name)
351 if(data_p >= iff_end)
352 { // didn't find the chunk
358 iff_chunk_len = *(long *)data_p;
360 if(iff_chunk_len < 0)
367 last_chunk = data_p + 8 + ((iff_chunk_len + 1) & ~1);
368 if (!strncmp(data_p, name, 4))
373 void FindChunk(char *name)
375 last_chunk = iff_data;
376 FindNextChunk (name);
379 void DumpChunks(void)
387 memcpy (str, data_p, 4);
389 iff_chunk_len = *(long *)data_p;
391 printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
392 data_p += (iff_chunk_len + 1) & ~1;
394 while(data_p < iff_end);
402 wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
409 memset(&info, 0, sizeof(info));
415 iff_end = wav + wavlength;
419 if (!(data_p && !strncmp(data_p + 8, "WAVE", 4)))
421 printf("Missing RIFF/WAVE chunks\n");
426 iff_data = data_p + 12;
431 printf("Missing fmt chunk\n");
435 format = *(short *)data_p;
439 printf("Microsoft PCM format only\n");
443 info.channels = *(short *)data_p;
445 info.rate = *(long *)data_p;
448 info.width = *(short *)data_p / 8;
456 info.loopstart = *(long *)data_p;
459 // if the next chunk is a LIST chunk, look for a cue length marker
460 FindNextChunk ("LIST");
463 // this is not a proper parse, but it works with cooledit...
464 if (!strncmp (data_p + 28, "mark", 4))
467 i = *(long *)data_p; // samples in loop
469 info.samples = info.loopstart + i;
480 printf("Missing data chunk\n");
485 samples = *(long *)data_p;
490 if(samples < info.samples)
491 Error ("Sound %s has a bad loop length", name);
494 info.samples = samples;
496 info.dataofs = data_p - wav;
504 void LoadSoundtrack()
511 sprintf (name, "%svideo/%s/%s.wav", gamedir, base, base);
512 printf ("\nLoading sound : %s\n", name);
513 f = fopen (name, "rb");
516 printf ("\nNo soundtrack for %s\n", base);
519 len = Q_filelength(f);
520 soundtrack = SafeMalloc(len, "LoadSoundtrack");
521 fread(soundtrack, 1, len, f);
524 wavinfo = GetWavinfo(name, soundtrack, len);
525 adpcm.state.out_valprev = 0;
526 adpcm.state.out_index = 0;
529 // ==================
531 // ==================
533 int WriteSound(FILE *output, int frame, int numframes)
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
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);
554 // ==============================
555 // Basic run length encoder
556 // ==============================
558 char *RLEZZ(char *in, char *out)
566 srun = idx; // Start of run
570 if(in[LUT_ZZ[idx]] != in[LUT_ZZ[idx + 1]])
574 count = (char)(idx - srun); // count of repeated bytes
580 if(in[LUT_ZZ[idx]] == in[LUT_ZZ[idx + 1]])
587 count = (char)(idx - srun); // count of unique bytes
590 *out++ = in[LUT_ZZ[srun++]];
594 *out++ = -(count + 1);
595 *out++ = in[LUT_ZZ[idx]];
602 // ==============================
603 // Discrete Cosine Transformation
604 // ==============================
606 void init_base(float quant)
610 for(y = 0; y < BLOCKSIZE; y++)
611 for(x = 0; x < BLOCKSIZE; x++)
616 dctbase[y][x] = SQRT2 * cos(((x * 2 + 1) * y * M_PI) / (BLOCKSIZE * 2));
619 for(y = 0; y < BLOCKSIZE * BLOCKSIZE; y++)
620 Quantise[y] = LUT_Quantise[y] / quant;
623 void SplitComponents(byte *src, int width, int height)
630 for(i = 0; i < BLOCKSIZE; i++, src += (width - BLOCKSIZE) * 4)
631 for(j = 0; j < BLOCKSIZE; j++)
633 *tr++ = ((float)*src++) - 128.0F;
634 *tg++ = ((float)*src++) - 128.0F;
635 *tb++ = ((float)*src++) - 128.0F;
640 void transferH(float *src, float *dst)
646 for(y = 0; y < BLOCKSIZE; y++, src += BLOCKSIZE)
648 for(dy = 0; dy < BLOCKSIZE; dy++)
652 for(dx = 0; dx < BLOCKSIZE; dx++, work++)
653 sum += dctbase[dy][dx] * *work;
655 *dst++ = sum / BLOCKSIZE;
660 void transferV(float *src, float *dst)
666 for(x = 0; x < BLOCKSIZE; x++, src++, dst++)
668 for(fy = 0; fy < BLOCKSIZE; fy++)
672 for(dy = 0; dy < BLOCKSIZE; dy++, work += BLOCKSIZE)
673 sum += dctbase[fy][dy] * *work;
675 dst[fy * BLOCKSIZE] = sum / BLOCKSIZE;
680 char *Combine(byte *dst, float *p, float *q)
683 byte rlesrc[BLOCKSIZE * BLOCKSIZE];
688 for(j = 0; j < BLOCKSIZE; j++)
689 for(i = 0; i < BLOCKSIZE; i++)
691 c = (int)((*p++ / *q++) + 128.5F);
702 dst = RLEZZ(rlesrc, dst);
706 char *CombineComponents(char *dst, int width, int height)
708 dst = Combine(dst, red, Quantise);
709 dst = Combine(dst, green, Quantise);
710 dst = Combine(dst, blue, Quantise);
714 void DCT(cblock_t *out, cblock_t in, int width, int height)
721 for(y = 0; y < height; y += BLOCKSIZE)
722 for(x = 0; x < width; x += BLOCKSIZE)
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);
734 out->count = curdst - out->data;
737 // ==================
739 // ==================
741 void BuildChars1(int prev, int nodenum, unsigned bits, int bitcount)
745 if(nodenum < HUF_TOKENS)
748 Error("bitcount > 32");
749 charbits1[prev][nodenum] = bits;
750 charbitscount1[prev][nodenum] = bitcount;
754 node = &hnodes1[prev][nodenum];
756 BuildChars1(prev, node->children[0], bits, bitcount+1);
758 BuildChars1(prev, node->children[1], bits, bitcount+1);
761 // ==================
763 // ==================
765 int SmallestNode1(hnode_t *hnodes, int numhnodes)
772 for(i = 0; i < numhnodes; i++)
778 if(hnodes[i].count < best)
780 best = hnodes[i].count;
788 hnodes[bestnode].used = true;
792 // ==================
794 // ==================
796 void BuildTree1(int prev)
798 hnode_t *node, *nodebase;
802 numhnodes = HUF_TOKENS;
803 nodebase = hnodes1[prev];
806 node = &nodebase[numhnodes];
808 // pick two lowest counts
809 node->children[0] = SmallestNode1 (nodebase, numhnodes);
810 if (node->children[0] == -1)
813 node->children[1] = SmallestNode1 (nodebase, numhnodes);
814 if (node->children[1] == -1)
817 node->count = nodebase[node->children[0]].count +
818 nodebase[node->children[1]].count;
821 numhnodes1[prev] = numhnodes-1;
822 BuildChars1 (prev, numhnodes-1, 0, 0);
825 // ==================
827 // ==================
829 void Huffman1_Count(cblock_t in)
837 for(i = 0; i < in.count; i++)
841 hnodes1[prev][v].count++;
844 for(rept = 1; (i + rept < in.count) && (rept < MAX_REPT); rept++)
845 if(in.data[i+rept] != v)
849 hnodes1[prev][255 + rept].count++;
855 // ==================
857 // ==================
859 void Huffman1_Build()
865 for(i = 0; i < 256; i++)
867 // normalize and save the counts
869 for (j = 0; j < HUF_TOKENS; j++)
871 if (hnodes1[i][j].count > max)
872 max = hnodes1[i][j].count;
877 // easy to overflow 32 bits here!
878 for(j = 0; j < HUF_TOKENS; j++)
880 v = (hnodes1[i][j].count * (double) 255 + max - 1) / max;
883 scaled[i][j] = hnodes1[i][j].count = v;
888 { // must have two tokens
890 scaled[i][0] = hnodes1[i][0].count = 1;
892 scaled[i][1] = hnodes1[i][1].count = 1;
898 // ==================
900 // Order 1 compression with pre-built table
901 // ==================
903 cblock_t Huffman1(cblock_t in)
914 out_p = out.data = SafeMalloc((in.count * 2) + 1024 + 4, "Huffman");
915 memset(out_p, 0, (in.count * 2) + 1024 + 4);
917 // leave space for compressed count
920 *(long *)out_p = in.count;
926 for(i = 0; i < in.count; i++)
930 c = charbitscount1[prev][v];
931 bits = charbits1[prev][v];
938 out_p[outbits>>3] |= 1 << (outbits & 7);
943 // check for repeat encodes
944 for(rept = 1; (i + rept < in.count) && (rept < MAX_REPT); rept++)
945 if(in.data[i + rept] != v)
949 c = charbitscount1[prev][255 + rept];
950 bits = charbits1[prev][255 + rept];
957 out_p[outbits >> 3] |= 1 << (outbits & 7);
963 out_p += (outbits + 7) >> 3;
964 out.count = out_p - out.data;
967 *(long *)out_p = out.count;
970 // ===================
972 // ===================
974 void LoadFrame(cblock_t *out, char *base, int frame)
983 sprintf (name, "%svideo/%s/%s%04i.tga", gamedir, base, base, frame);
985 f = fopen(name, "rb");
993 LoadTGA(name, &in.data, &width, &height);
994 if((width != cinehead.Width) || (height != cinehead.Height))
997 printf("Invalid picture size\n");
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);
1006 // ==================================
1009 // video <directory> <framedigits>
1010 // ==================================
1019 cblock_t in, huffman;
1023 int min_rle_size, warnings;
1024 int ave_image, ave_sound;
1026 GetScriptToken(false);
1027 strcpy(base, token);
1031 GetScriptToken(false);
1032 dctconst = atof(token);
1033 GetScriptToken(false);
1034 maxsize = atoi(token);
1036 sprintf (savename, "%svideo/%s.cin", gamedir, base);
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));
1045 // load the entire sound wav file if present
1048 cinehead.SndRate = wavinfo.rate;
1049 cinehead.SndWidth = wavinfo.width;
1050 cinehead.SndChannels = wavinfo.channels;
1052 sprintf(name, "%svideo/%s/%s0000.tga", gamedir, base, base);
1053 printf("Loading sequence : %s\n", name);
1054 printf("DCT constant : %f\n", dctconst);
1056 LoadTGA (name, NULL, &width, &height);
1058 output = fopen (savename, "wb");
1060 Error ("Can't open %s", savename);
1062 if((width % BLOCKSIZE) || (height % BLOCKSIZE))
1063 Error("Width and height must be a multiple of %d", BLOCKSIZE);
1065 cinehead.Width = width;
1066 cinehead.Height = height;
1067 init_base(dctconst);
1069 // build the dictionary
1070 printf("Counting : ");
1072 for (frame = 0; ; frame++)
1075 LoadFrame(&in, base, frame);
1079 if(in.count > min_rle_size)
1080 min_rle_size = in.count;
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;
1089 WriteHeader(output, FC_HEADER_NAME, FC_HEADER_VERSION, sizeof(CineHead_t), &cinehead);
1091 // build nodes and write counts
1093 WriteHeader(output, FC_HUFFBITS_NAME, FC_HUFFBITS_VERSION, sizeof(scaled), scaled);
1094 WriteHeader(output, FC_QUANT_NAME, FC_QUANT_VERSION, sizeof(Quantise), Quantise);
1099 // compress it with the dictionary
1102 ssize = WriteSound(output, frame, 4);
1106 for (frame = 0; frame < cinehead.NumFrames; frame++)
1108 // save some sound samples
1109 printf ("Packing : ", frame);
1110 LoadFrame(&in, base, frame);
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
1118 printf(" ** WARNING **");
1122 ave_image += huffman.count;
1124 WriteHeader(output, FC_IMAGE_NAME, FC_IMAGE_VERSION, size, huffman.data);
1127 ssize = WriteSound(output, frame + 4, 1);
1132 free (huffman.data);
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);