PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/quake2/extra/qdata/video.c

https://gitlab.com/illwieckz/netradiant
C | 1259 lines | 889 code | 198 blank | 172 comment | 165 complexity | 1b5fc863b2ebfd2094f946825bcafcc4 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake 2 Tools source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qdata.h"
  19. byte *soundtrack;
  20. char base[32];
  21. /*
  22. ===============================================================================
  23. WAV loading
  24. ===============================================================================
  25. */
  26. typedef struct
  27. {
  28. int rate;
  29. int width;
  30. int channels;
  31. int loopstart;
  32. int samples;
  33. int dataofs; // chunk starts this many bytes from file start
  34. } wavinfo_t;
  35. byte *data_p;
  36. byte *iff_end;
  37. byte *last_chunk;
  38. byte *iff_data;
  39. int iff_chunk_len;
  40. int samplecounts[0x10000];
  41. wavinfo_t wavinfo;
  42. short GetLittleShort(void)
  43. {
  44. short val = 0;
  45. val = *data_p;
  46. val = val + (*(data_p+1)<<8);
  47. data_p += 2;
  48. return val;
  49. }
  50. int GetLittleLong(void)
  51. {
  52. int val = 0;
  53. val = *data_p;
  54. val = val + (*(data_p+1)<<8);
  55. val = val + (*(data_p+2)<<16);
  56. val = val + (*(data_p+3)<<24);
  57. data_p += 4;
  58. return val;
  59. }
  60. void FindNextChunk(char *name)
  61. {
  62. while (1)
  63. {
  64. data_p=last_chunk;
  65. if (data_p >= iff_end)
  66. { // didn't find the chunk
  67. data_p = NULL;
  68. return;
  69. }
  70. data_p += 4;
  71. iff_chunk_len = GetLittleLong();
  72. if (iff_chunk_len < 0)
  73. {
  74. data_p = NULL;
  75. return;
  76. }
  77. // if (iff_chunk_len > 1024*1024)
  78. // Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
  79. data_p -= 8;
  80. last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
  81. if (!strncmp(data_p, name, 4))
  82. return;
  83. }
  84. }
  85. void FindChunk(char *name)
  86. {
  87. last_chunk = iff_data;
  88. FindNextChunk (name);
  89. }
  90. void DumpChunks(void)
  91. {
  92. char str[5];
  93. str[4] = 0;
  94. data_p=iff_data;
  95. do
  96. {
  97. memcpy (str, data_p, 4);
  98. data_p += 4;
  99. iff_chunk_len = GetLittleLong();
  100. printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
  101. data_p += (iff_chunk_len + 1) & ~1;
  102. } while (data_p < iff_end);
  103. }
  104. /*
  105. ============
  106. GetWavinfo
  107. ============
  108. */
  109. wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
  110. {
  111. wavinfo_t info;
  112. int i;
  113. int format;
  114. int samples;
  115. memset (&info, 0, sizeof(info));
  116. if (!wav)
  117. return info;
  118. iff_data = wav;
  119. iff_end = wav + wavlength;
  120. // find "RIFF" chunk
  121. FindChunk("RIFF");
  122. if (!(data_p && !strncmp(data_p+8, "WAVE", 4)))
  123. {
  124. printf("Missing RIFF/WAVE chunks\n");
  125. return info;
  126. }
  127. // get "fmt " chunk
  128. iff_data = data_p + 12;
  129. // DumpChunks ();
  130. FindChunk("fmt ");
  131. if (!data_p)
  132. {
  133. printf("Missing fmt chunk\n");
  134. return info;
  135. }
  136. data_p += 8;
  137. format = GetLittleShort();
  138. if (format != 1)
  139. {
  140. printf("Microsoft PCM format only\n");
  141. return info;
  142. }
  143. info.channels = GetLittleShort();
  144. info.rate = GetLittleLong();
  145. data_p += 4+2;
  146. info.width = GetLittleShort() / 8;
  147. // get cue chunk
  148. FindChunk("cue ");
  149. if (data_p)
  150. {
  151. data_p += 32;
  152. info.loopstart = GetLittleLong();
  153. // Com_Printf("loopstart=%d\n", sfx->loopstart);
  154. // if the next chunk is a LIST chunk, look for a cue length marker
  155. FindNextChunk ("LIST");
  156. if (data_p)
  157. {
  158. if (!strncmp (data_p + 28, "mark", 4))
  159. { // this is not a proper parse, but it works with cooledit...
  160. data_p += 24;
  161. i = GetLittleLong (); // samples in loop
  162. info.samples = info.loopstart + i;
  163. }
  164. }
  165. }
  166. else
  167. info.loopstart = -1;
  168. // find data chunk
  169. FindChunk("data");
  170. if (!data_p)
  171. {
  172. printf("Missing data chunk\n");
  173. return info;
  174. }
  175. data_p += 4;
  176. samples = GetLittleLong ();
  177. if (info.samples)
  178. {
  179. if (samples < info.samples)
  180. Error ("Sound %s has a bad loop length", name);
  181. }
  182. else
  183. info.samples = samples;
  184. info.dataofs = data_p - wav;
  185. return info;
  186. }
  187. //=====================================================================
  188. /*
  189. ==============
  190. LoadSoundtrack
  191. ==============
  192. */
  193. void LoadSoundtrack (void)
  194. {
  195. char name[1024];
  196. FILE *f;
  197. int len;
  198. int i, val, j;
  199. soundtrack = NULL;
  200. sprintf (name, "%svideo/%s/%s.wav", gamedir, base, base);
  201. printf ("%s\n", name);
  202. f = fopen (name, "rb");
  203. if (!f)
  204. {
  205. printf ("no soundtrack for %s\n", base);
  206. return;
  207. }
  208. len = Q_filelength(f);
  209. soundtrack = malloc(len);
  210. fread (soundtrack, 1, len, f);
  211. fclose (f);
  212. wavinfo = GetWavinfo (name, soundtrack, len);
  213. // count samples for compression
  214. memset (samplecounts, 0, sizeof(samplecounts));
  215. j = wavinfo.samples/2;
  216. for (i=0 ; i<j ; i++)
  217. {
  218. val = ((unsigned short *)( soundtrack + wavinfo.dataofs))[i];
  219. samplecounts[val]++;
  220. }
  221. val = 0;
  222. for (i=0 ; i<0x10000 ; i++)
  223. if (samplecounts[i])
  224. val++;
  225. printf ("%i unique sample values\n", val);
  226. }
  227. /*
  228. ==================
  229. WriteSound
  230. ==================
  231. */
  232. void WriteSound (FILE *output, int frame)
  233. {
  234. int start, end;
  235. int count;
  236. int empty = 0;
  237. int i;
  238. int sample;
  239. int width;
  240. width = wavinfo.width * wavinfo.channels;
  241. start = frame*wavinfo.rate/14;
  242. end = (frame+1)*wavinfo.rate/14;
  243. count = end - start;
  244. for (i=0 ; i<count ; i++)
  245. {
  246. sample = start+i;
  247. if (sample > wavinfo.samples || !soundtrack)
  248. fwrite (&empty, 1, width, output);
  249. else
  250. fwrite (soundtrack + wavinfo.dataofs + sample*width, 1, width,output);
  251. }
  252. }
  253. //==========================================================================
  254. /*
  255. ==================
  256. MTF
  257. ==================
  258. */
  259. cblock_t MTF (cblock_t in)
  260. {
  261. int i, j, b, code;
  262. byte *out_p;
  263. int index[256];
  264. cblock_t out;
  265. out_p = out.data = malloc(in.count + 4);
  266. // write count
  267. *out_p++ = in.count&255;
  268. *out_p++ = (in.count>>8)&255;
  269. *out_p++ = (in.count>>16)&255;
  270. *out_p++ = (in.count>>24)&255;
  271. for (i=0 ; i<256 ; i++)
  272. index[i] = i;
  273. for (i=0 ; i<in.count ; i++)
  274. {
  275. b = in.data[i];
  276. code = index[b];
  277. *out_p++ = code;
  278. // shuffle b indexes to 0
  279. for (j=0 ; j<256 ; j++)
  280. if (index[j] < code)
  281. index[j]++;
  282. index[b] = 0;
  283. }
  284. out.count = out_p - out.data;
  285. return out;
  286. }
  287. //==========================================================================
  288. int bwt_size;
  289. byte *bwt_data;
  290. int bwtCompare (const void *elem1, const void *elem2)
  291. {
  292. int i;
  293. int i1, i2;
  294. int b1, b2;
  295. i1 = *(int *)elem1;
  296. i2 = *(int *)elem2;
  297. for (i=0 ; i<bwt_size ; i++)
  298. {
  299. b1 = bwt_data[i1];
  300. b2 = bwt_data[i2];
  301. if (b1 < b2)
  302. return -1;
  303. if (b1 > b2)
  304. return 1;
  305. if (++i1 == bwt_size)
  306. i1 = 0;
  307. if (++i2 == bwt_size)
  308. i2 = 0;
  309. }
  310. return 0;
  311. }
  312. /*
  313. ==================
  314. BWT
  315. ==================
  316. */
  317. cblock_t BWT (cblock_t in)
  318. {
  319. int *sorted;
  320. int i;
  321. byte *out_p;
  322. cblock_t out;
  323. bwt_size = in.count;
  324. bwt_data = in.data;
  325. sorted = malloc(in.count*sizeof(*sorted));
  326. for (i=0 ; i<in.count ; i++)
  327. sorted[i] = i;
  328. qsort (sorted, in.count, sizeof(*sorted), bwtCompare);
  329. out_p = out.data = malloc(in.count + 8);
  330. // write count
  331. *out_p++ = in.count&255;
  332. *out_p++ = (in.count>>8)&255;
  333. *out_p++ = (in.count>>16)&255;
  334. *out_p++ = (in.count>>24)&255;
  335. // write head index
  336. for (i=0 ; i<in.count ; i++)
  337. if (sorted[i] == 0)
  338. break;
  339. *out_p++ = i&255;
  340. *out_p++ = (i>>8)&255;
  341. *out_p++ = (i>>16)&255;
  342. *out_p++ = (i>>24)&255;
  343. // write the L column
  344. for (i=0 ; i<in.count ; i++)
  345. *out_p++ = in.data[(sorted[i]+in.count-1)%in.count];
  346. free (sorted);
  347. out.count = out_p - out.data;
  348. return out;
  349. }
  350. //==========================================================================
  351. typedef struct hnode_s
  352. {
  353. int count;
  354. qboolean used;
  355. int children[2];
  356. } hnode_t;
  357. int numhnodes;
  358. hnode_t hnodes[512];
  359. unsigned charbits[256];
  360. int charbitscount[256];
  361. int SmallestNode (void)
  362. {
  363. int i;
  364. int best, bestnode;
  365. best = 99999999;
  366. bestnode = -1;
  367. for (i=0 ; i<numhnodes ; i++)
  368. {
  369. if (hnodes[i].used)
  370. continue;
  371. if (!hnodes[i].count)
  372. continue;
  373. if (hnodes[i].count < best)
  374. {
  375. best = hnodes[i].count;
  376. bestnode = i;
  377. }
  378. }
  379. if (bestnode == -1)
  380. return -1;
  381. hnodes[bestnode].used = true;
  382. return bestnode;
  383. }
  384. void BuildChars (int nodenum, unsigned bits, int bitcount)
  385. {
  386. hnode_t *node;
  387. if (nodenum < 256)
  388. {
  389. if (bitcount > 32)
  390. Error ("bitcount > 32");
  391. charbits[nodenum] = bits;
  392. charbitscount[nodenum] = bitcount;
  393. return;
  394. }
  395. node = &hnodes[nodenum];
  396. bits <<= 1;
  397. BuildChars (node->children[0], bits, bitcount+1);
  398. bits |= 1;
  399. BuildChars (node->children[1], bits, bitcount+1);
  400. }
  401. /*
  402. ==================
  403. Huffman
  404. ==================
  405. */
  406. cblock_t Huffman (cblock_t in)
  407. {
  408. int i;
  409. hnode_t *node;
  410. int outbits, c;
  411. unsigned bits;
  412. byte *out_p;
  413. cblock_t out;
  414. int max, maxchar;
  415. // count
  416. memset (hnodes, 0, sizeof(hnodes));
  417. for (i=0 ; i<in.count ; i++)
  418. hnodes[in.data[i]].count++;
  419. // normalize counts
  420. max = 0;
  421. maxchar = 0;
  422. for (i=0 ; i<256 ; i++)
  423. {
  424. if (hnodes[i].count > max)
  425. {
  426. max = hnodes[i].count;
  427. maxchar = i;
  428. }
  429. }
  430. if (max == 0)
  431. Error ("Huffman: max == 0");
  432. for (i=0 ; i<256 ; i++)
  433. {
  434. hnodes[i].count = (hnodes[i].count*255+max-1) / max;
  435. }
  436. // build the nodes
  437. numhnodes = 256;
  438. while (numhnodes != 511)
  439. {
  440. node = &hnodes[numhnodes];
  441. // pick two lowest counts
  442. node->children[0] = SmallestNode ();
  443. if (node->children[0] == -1)
  444. break; // no more
  445. node->children[1] = SmallestNode ();
  446. if (node->children[1] == -1)
  447. {
  448. if (node->children[0] != numhnodes-1)
  449. Error ("Bad smallestnode");
  450. break;
  451. }
  452. node->count = hnodes[node->children[0]].count +
  453. hnodes[node->children[1]].count;
  454. numhnodes++;
  455. }
  456. BuildChars (numhnodes-1, 0, 0);
  457. out_p = out.data = malloc(in.count*2 + 1024);
  458. memset (out_p, 0, in.count*2+1024);
  459. // write count
  460. *out_p++ = in.count&255;
  461. *out_p++ = (in.count>>8)&255;
  462. *out_p++ = (in.count>>16)&255;
  463. *out_p++ = (in.count>>24)&255;
  464. // save out the 256 normalized counts so the tree can be recreated
  465. for (i=0 ; i<256 ; i++)
  466. *out_p++ = hnodes[i].count;
  467. // write bits
  468. outbits = 0;
  469. for (i=0 ; i<in.count ; i++)
  470. {
  471. c = charbitscount[in.data[i]];
  472. bits = charbits[in.data[i]];
  473. while (c)
  474. {
  475. c--;
  476. if (bits & (1<<c))
  477. out_p[outbits>>3] |= 1<<(outbits&7);
  478. outbits++;
  479. }
  480. }
  481. out_p += (outbits+7)>>3;
  482. out.count = out_p - out.data;
  483. return out;
  484. }
  485. //==========================================================================
  486. /*
  487. ==================
  488. RLE
  489. ==================
  490. */
  491. #define RLE_CODE 0xe8
  492. #define RLE_TRIPPLE 0xe9
  493. int rle_counts[256];
  494. int rle_bytes[256];
  495. cblock_t RLE (cblock_t in)
  496. {
  497. int i;
  498. byte *out_p;
  499. int val;
  500. int repeat;
  501. cblock_t out;
  502. out_p = out.data = malloc (in.count*2);
  503. // write count
  504. *out_p++ = in.count&255;
  505. *out_p++ = (in.count>>8)&255;
  506. *out_p++ = (in.count>>16)&255;
  507. *out_p++ = (in.count>>24)&255;
  508. for (i=0 ; i<in.count ; )
  509. {
  510. val = in.data[i];
  511. rle_bytes[val]++;
  512. repeat = 1;
  513. i++;
  514. while (i<in.count && repeat < 255 && in.data[i] == val)
  515. {
  516. repeat++;
  517. i++;
  518. }
  519. if (repeat < 256)
  520. rle_counts[repeat]++;
  521. if (repeat > 3 || val == RLE_CODE)
  522. {
  523. *out_p++ = RLE_CODE;
  524. *out_p++ = val;
  525. *out_p++ = repeat;
  526. }
  527. else
  528. {
  529. while (repeat--)
  530. *out_p++ = val;
  531. }
  532. }
  533. out.count = out_p - out.data;
  534. return out;
  535. }
  536. //==========================================================================
  537. unsigned lzss_head[256];
  538. unsigned lzss_next[0x20000];
  539. /*
  540. ==================
  541. LZSS
  542. ==================
  543. */
  544. #define BACK_WINDOW 0x10000
  545. #define BACK_BITS 16
  546. #define FRONT_WINDOW 16
  547. #define FRONT_BITS 4
  548. cblock_t LZSS (cblock_t in)
  549. {
  550. int i;
  551. byte *out_p;
  552. cblock_t out;
  553. int val;
  554. int j, start, max;
  555. int bestlength, beststart;
  556. int outbits;
  557. if (in.count >= sizeof(lzss_next)/4)
  558. Error ("LZSS: too big");
  559. memset (lzss_head, -1, sizeof(lzss_head));
  560. out_p = out.data = malloc (in.count*2);
  561. memset (out.data, 0, in.count*2);
  562. // write count
  563. *out_p++ = in.count&255;
  564. *out_p++ = (in.count>>8)&255;
  565. *out_p++ = (in.count>>16)&255;
  566. *out_p++ = (in.count>>24)&255;
  567. outbits = 0;
  568. for (i=0 ; i<in.count ; )
  569. {
  570. val = in.data[i];
  571. #if 1
  572. // chained search
  573. bestlength = 0;
  574. beststart = 0;
  575. max = FRONT_WINDOW;
  576. if (i + max > in.count)
  577. max = in.count - i;
  578. start = lzss_head[val];
  579. while (start != -1 && start >= i-BACK_WINDOW)
  580. {
  581. // count match length
  582. for (j=0 ; j<max ; j++)
  583. if (in.data[start+j] != in.data[i+j])
  584. break;
  585. if (j > bestlength)
  586. {
  587. bestlength = j;
  588. beststart = start;
  589. }
  590. start = lzss_next[start];
  591. }
  592. #else
  593. // slow simple search
  594. // search for a match
  595. max = FRONT_WINDOW;
  596. if (i + max > in.count)
  597. max = in.count - i;
  598. start = i - BACK_WINDOW;
  599. if (start < 0)
  600. start = 0;
  601. bestlength = 0;
  602. beststart = 0;
  603. for ( ; start < i ; start++)
  604. {
  605. if (in.data[start] != val)
  606. continue;
  607. // count match length
  608. for (j=0 ; j<max ; j++)
  609. if (in.data[start+j] != in.data[i+j])
  610. break;
  611. if (j > bestlength)
  612. {
  613. bestlength = j;
  614. beststart = start;
  615. }
  616. }
  617. #endif
  618. beststart = BACK_WINDOW - (i-beststart);
  619. if (bestlength < 3)
  620. { // output a single char
  621. bestlength = 1;
  622. out_p[outbits>>3] |= 1<<(outbits&7); // set bit to mark char
  623. outbits++;
  624. for (j=0 ; j<8 ; j++, outbits++)
  625. if (val & (1<<j) )
  626. out_p[outbits>>3] |= 1<<(outbits&7);
  627. }
  628. else
  629. { // output a phrase
  630. outbits++; // leave a 0 bit to mark phrase
  631. for (j=0 ; j<BACK_BITS ; j++, outbits++)
  632. if (beststart & (1<<j) )
  633. out_p[outbits>>3] |= 1<<(outbits&7);
  634. for (j=0 ; j<FRONT_BITS ; j++, outbits++)
  635. if (bestlength & (1<<j) )
  636. out_p[outbits>>3] |= 1<<(outbits&7);
  637. }
  638. while (bestlength--)
  639. {
  640. val = in.data[i];
  641. lzss_next[i] = lzss_head[val];
  642. lzss_head[val] = i;
  643. i++;
  644. }
  645. }
  646. out_p += (outbits+7)>>3;
  647. out.count = out_p - out.data;
  648. return out;
  649. }
  650. //==========================================================================
  651. #define MIN_REPT 15
  652. #define MAX_REPT 0
  653. #define HUF_TOKENS (256+MAX_REPT)
  654. unsigned charbits1[256][HUF_TOKENS];
  655. int charbitscount1[256][HUF_TOKENS];
  656. hnode_t hnodes1[256][HUF_TOKENS*2];
  657. int numhnodes1[256];
  658. int order0counts[256];
  659. /*
  660. ==================
  661. SmallestNode1
  662. ==================
  663. */
  664. int SmallestNode1 (hnode_t *hnodes, int numhnodes)
  665. {
  666. int i;
  667. int best, bestnode;
  668. best = 99999999;
  669. bestnode = -1;
  670. for (i=0 ; i<numhnodes ; i++)
  671. {
  672. if (hnodes[i].used)
  673. continue;
  674. if (!hnodes[i].count)
  675. continue;
  676. if (hnodes[i].count < best)
  677. {
  678. best = hnodes[i].count;
  679. bestnode = i;
  680. }
  681. }
  682. if (bestnode == -1)
  683. return -1;
  684. hnodes[bestnode].used = true;
  685. return bestnode;
  686. }
  687. /*
  688. ==================
  689. BuildChars1
  690. ==================
  691. */
  692. void BuildChars1 (int prev, int nodenum, unsigned bits, int bitcount)
  693. {
  694. hnode_t *node;
  695. if (nodenum < HUF_TOKENS)
  696. {
  697. if (bitcount > 32)
  698. Error ("bitcount > 32");
  699. charbits1[prev][nodenum] = bits;
  700. charbitscount1[prev][nodenum] = bitcount;
  701. return;
  702. }
  703. node = &hnodes1[prev][nodenum];
  704. bits <<= 1;
  705. BuildChars1 (prev, node->children[0], bits, bitcount+1);
  706. bits |= 1;
  707. BuildChars1 (prev, node->children[1], bits, bitcount+1);
  708. }
  709. /*
  710. ==================
  711. BuildTree1
  712. ==================
  713. */
  714. void BuildTree1 (int prev)
  715. {
  716. hnode_t *node, *nodebase;
  717. int numhnodes;
  718. // build the nodes
  719. numhnodes = HUF_TOKENS;
  720. nodebase = hnodes1[prev];
  721. while (1)
  722. {
  723. node = &nodebase[numhnodes];
  724. // pick two lowest counts
  725. node->children[0] = SmallestNode1 (nodebase, numhnodes);
  726. if (node->children[0] == -1)
  727. break; // no more
  728. node->children[1] = SmallestNode1 (nodebase, numhnodes);
  729. if (node->children[1] == -1)
  730. break;
  731. node->count = nodebase[node->children[0]].count +
  732. nodebase[node->children[1]].count;
  733. numhnodes++;
  734. }
  735. numhnodes1[prev] = numhnodes-1;
  736. BuildChars1 (prev, numhnodes-1, 0, 0);
  737. }
  738. /*
  739. ==================
  740. Huffman1_Count
  741. ==================
  742. */
  743. void Huffman1_Count (cblock_t in)
  744. {
  745. int i;
  746. int prev;
  747. int v;
  748. int rept;
  749. prev = 0;
  750. for (i=0 ; i<in.count ; i++)
  751. {
  752. v = in.data[i];
  753. order0counts[v]++;
  754. hnodes1[prev][v].count++;
  755. prev = v;
  756. #if 1
  757. for (rept=1 ; i+rept < in.count && rept < MAX_REPT ; rept++)
  758. if (in.data[i+rept] != v)
  759. break;
  760. if (rept > MIN_REPT)
  761. {
  762. hnodes1[prev][255+rept].count++;
  763. i += rept-1;
  764. }
  765. #endif
  766. }
  767. }
  768. /*
  769. ==================
  770. Huffman1_Build
  771. ==================
  772. */
  773. byte scaled[256][HUF_TOKENS];
  774. void Huffman1_Build (FILE *f)
  775. {
  776. int i, j, v;
  777. int max;
  778. int total;
  779. for (i=0 ; i<256 ; i++)
  780. {
  781. // normalize and save the counts
  782. max = 0;
  783. for (j=0 ; j<HUF_TOKENS ; j++)
  784. {
  785. if (hnodes1[i][j].count > max)
  786. max = hnodes1[i][j].count;
  787. }
  788. if (max == 0)
  789. max = 1;
  790. total = 0;
  791. for (j=0 ; j<HUF_TOKENS ; j++)
  792. { // easy to overflow 32 bits here!
  793. v = (hnodes1[i][j].count*(double)255+max-1)/max;
  794. if (v > 255)
  795. Error ("v > 255");
  796. scaled[i][j] = hnodes1[i][j].count = v;
  797. if (v)
  798. total++;
  799. }
  800. if (total == 1)
  801. { // must have two tokens
  802. if (!scaled[i][0])
  803. scaled[i][0] = hnodes1[i][0].count = 1;
  804. else
  805. scaled[i][1] = hnodes1[i][1].count = 1;
  806. }
  807. BuildTree1 (i);
  808. }
  809. #if 0
  810. // count up the total bits
  811. total = 0;
  812. for (i=0 ; i<256 ; i++)
  813. for (j=0 ; j<256 ; j++)
  814. total += charbitscount1[i][j] * hnodes1[i][j].count;
  815. total = (total+7)/8;
  816. printf ("%i bytes huffman1 compressed\n", total);
  817. #endif
  818. fwrite (scaled, 1, sizeof(scaled), f);
  819. }
  820. /*
  821. ==================
  822. Huffman1
  823. Order 1 compression with pre-built table
  824. ==================
  825. */
  826. cblock_t Huffman1 (cblock_t in)
  827. {
  828. int i;
  829. int outbits, c;
  830. unsigned bits;
  831. byte *out_p;
  832. cblock_t out;
  833. int prev;
  834. int v;
  835. int rept;
  836. out_p = out.data = malloc(in.count*2 + 1024);
  837. memset (out_p, 0, in.count*2+1024);
  838. // write count
  839. *out_p++ = in.count&255;
  840. *out_p++ = (in.count>>8)&255;
  841. *out_p++ = (in.count>>16)&255;
  842. *out_p++ = (in.count>>24)&255;
  843. // write bits
  844. outbits = 0;
  845. prev = 0;
  846. for (i=0 ; i<in.count ; i++)
  847. {
  848. v = in.data[i];
  849. c = charbitscount1[prev][v];
  850. bits = charbits1[prev][v];
  851. if (!c)
  852. Error ("!bits");
  853. while (c)
  854. {
  855. c--;
  856. if (bits & (1<<c))
  857. out_p[outbits>>3] |= 1<<(outbits&7);
  858. outbits++;
  859. }
  860. prev = v;
  861. #if 1
  862. // check for repeat encodes
  863. for (rept=1 ; i+rept < in.count && rept < MAX_REPT ; rept++)
  864. if (in.data[i+rept] != v)
  865. break;
  866. if (rept > MIN_REPT)
  867. {
  868. c = charbitscount1[prev][255+rept];
  869. bits = charbits1[prev][255+rept];
  870. if (!c)
  871. Error ("!bits");
  872. while (c)
  873. {
  874. c--;
  875. if (bits & (1<<c))
  876. out_p[outbits>>3] |= 1<<(outbits&7);
  877. outbits++;
  878. }
  879. i += rept-1;
  880. }
  881. #endif
  882. }
  883. out_p += (outbits+7)>>3;
  884. out.count = out_p - out.data;
  885. return out;
  886. }
  887. //==========================================================================
  888. /*
  889. ===================
  890. LoadFrame
  891. ===================
  892. */
  893. cblock_t LoadFrame (char *base, int frame, int digits, byte **palette)
  894. {
  895. int ten3, ten2, ten1, ten0;
  896. cblock_t in;
  897. int width, height;
  898. char name[1024];
  899. FILE *f;
  900. in.data = NULL;
  901. in.count = -1;
  902. ten3 = frame/1000;
  903. ten2 = (frame-ten3*1000)/100;
  904. ten1 = (frame-ten3*1000-ten2*100)/10;
  905. ten0 = frame%10;
  906. if (digits == 4)
  907. sprintf (name, "%svideo/%s/%s%i%i%i%i.pcx", gamedir, base, base, ten3, ten2, ten1, ten0);
  908. else
  909. sprintf (name, "%svideo/%s/%s%i%i%i.pcx", gamedir, base, base, ten2, ten1, ten0);
  910. f = fopen(name, "rb");
  911. if (!f)
  912. {
  913. in.data = NULL;
  914. return in;
  915. }
  916. fclose (f);
  917. printf ("%s\n", name);
  918. Load256Image (name, &in.data, palette, &width, &height);
  919. in.count = width*height;
  920. // FIXME: map 0 and 255!
  921. #if 0
  922. // rle compress
  923. rle = RLE(in);
  924. free (in.data);
  925. return rle;
  926. #endif
  927. return in;
  928. }
  929. /*
  930. ===============
  931. Cmd_Video
  932. video <directory> <framedigits>
  933. ===============
  934. */
  935. void Cmd_Video (void)
  936. {
  937. char savename[1024];
  938. char name[1024];
  939. FILE *output;
  940. int startframe, frame;
  941. byte *palette;
  942. int width, height;
  943. byte current_palette[768];
  944. int command;
  945. int i;
  946. int digits;
  947. cblock_t in, huffman;
  948. int swap;
  949. GetToken (false);
  950. strcpy (base, token);
  951. if (g_release)
  952. {
  953. // sprintf (savename, "video/%s.cin", token);
  954. // ReleaseFile (savename);
  955. return;
  956. }
  957. GetToken (false);
  958. digits = atoi(token);
  959. // optionally skip frames
  960. if (TokenAvailable ())
  961. {
  962. GetToken (false);
  963. startframe = atoi(token);
  964. }
  965. else
  966. startframe=0;
  967. sprintf (savename, "%svideo/%s.cin", gamedir, base);
  968. // clear stuff
  969. memset (charbits1, 0, sizeof(charbits1));
  970. memset (charbitscount1, 0, sizeof(charbitscount1));
  971. memset (hnodes1, 0, sizeof(hnodes1));
  972. memset (numhnodes1, 0, sizeof(numhnodes1));
  973. memset (order0counts, 0, sizeof(order0counts));
  974. // load the entire sound wav file if present
  975. LoadSoundtrack ();
  976. if (digits == 4)
  977. sprintf (name, "%svideo/%s/%s0000.pcx", gamedir, base, base);
  978. else
  979. sprintf (name, "%svideo/%s/%s000.pcx", gamedir, base, base);
  980. printf ("%s\n", name);
  981. Load256Image (name, NULL, &palette, &width, &height);
  982. output = fopen (savename, "wb");
  983. if (!output)
  984. Error ("Can't open %s", savename);
  985. // write header info
  986. i = LittleLong (width);
  987. fwrite (&i, 4, 1, output);
  988. i = LittleLong (height);
  989. fwrite (&i, 4, 1, output);
  990. i = LittleLong (wavinfo.rate);
  991. fwrite (&i, 4, 1, output);
  992. i = LittleLong (wavinfo.width);
  993. fwrite (&i, 4, 1, output);
  994. i = LittleLong (wavinfo.channels);
  995. fwrite (&i, 4, 1, output);
  996. // build the dictionary
  997. for ( frame=startframe ; ; frame++)
  998. {
  999. printf ("counting ", frame);
  1000. in = LoadFrame (base, frame, digits, &palette);
  1001. if (!in.data)
  1002. break;
  1003. Huffman1_Count (in);
  1004. free (in.data);
  1005. }
  1006. printf ("\n");
  1007. // build nodes and write counts
  1008. Huffman1_Build (output);
  1009. memset (current_palette, 0, sizeof(current_palette));
  1010. // compress it with the dictionary
  1011. for (frame=startframe ; ; frame++)
  1012. {
  1013. printf ("packing ", frame);
  1014. in = LoadFrame (base, frame, digits, &palette);
  1015. if (!in.data)
  1016. break;
  1017. // see if the palette has changed
  1018. for (i=0 ; i<768 ; i++)
  1019. if (palette[i] != current_palette[i])
  1020. {
  1021. // write a palette change
  1022. memcpy (current_palette, palette, sizeof(current_palette));
  1023. command = LittleLong(1);
  1024. fwrite (&command, 1, 4, output);
  1025. fwrite (current_palette, 1, sizeof(current_palette), output);
  1026. break;
  1027. }
  1028. if (i == 768)
  1029. {
  1030. command = 0; // no palette change
  1031. fwrite (&command, 1, 4, output);
  1032. }
  1033. // save the image
  1034. huffman = Huffman1 (in);
  1035. printf ("%5i bytes after huffman1\n", huffman.count);
  1036. swap = LittleLong (huffman.count);
  1037. fwrite (&swap, 1, sizeof(swap), output);
  1038. fwrite (huffman.data, 1, huffman.count, output);
  1039. // save some sound samples
  1040. WriteSound (output, frame);
  1041. free (palette);
  1042. free (in.data);
  1043. free (huffman.data);
  1044. }
  1045. printf ("\n");
  1046. // write end-of-file command
  1047. command = 2;
  1048. fwrite (&command, 1, 4, output);
  1049. printf ("Total size: %i\n", ftell (output));
  1050. fclose (output);
  1051. if (soundtrack)
  1052. free (soundtrack);
  1053. }