PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/quake2/qdata/video.c

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