huffman.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena 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 III Arena 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 Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. /* This is based on the Adaptive Huffman algorithm described in Sayood's Data
  19. * Compression book. The ranks are not actually stored, but implicitly defined
  20. * by the location of a node within a doubly-linked list */
  21. #include "../game/q_shared.h"
  22. #include "qcommon.h"
  23. static int bloc = 0;
  24. void Huff_putBit( int bit, byte *fout, int *offset) {
  25. bloc = *offset;
  26. if ((bloc&7) == 0) {
  27. fout[(bloc>>3)] = 0;
  28. }
  29. fout[(bloc>>3)] |= bit << (bloc&7);
  30. bloc++;
  31. *offset = bloc;
  32. }
  33. int Huff_getBit( byte *fin, int *offset) {
  34. int t;
  35. bloc = *offset;
  36. t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1;
  37. bloc++;
  38. *offset = bloc;
  39. return t;
  40. }
  41. /* Add a bit to the output file (buffered) */
  42. static void add_bit (char bit, byte *fout) {
  43. if ((bloc&7) == 0) {
  44. fout[(bloc>>3)] = 0;
  45. }
  46. fout[(bloc>>3)] |= bit << (bloc&7);
  47. bloc++;
  48. }
  49. /* Receive one bit from the input file (buffered) */
  50. static int get_bit (byte *fin) {
  51. int t;
  52. t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1;
  53. bloc++;
  54. return t;
  55. }
  56. static node_t **get_ppnode(huff_t* huff) {
  57. node_t **tppnode;
  58. if (!huff->freelist) {
  59. return &(huff->nodePtrs[huff->blocPtrs++]);
  60. } else {
  61. tppnode = huff->freelist;
  62. huff->freelist = (node_t **)*tppnode;
  63. return tppnode;
  64. }
  65. }
  66. static void free_ppnode(huff_t* huff, node_t **ppnode) {
  67. *ppnode = (node_t *)huff->freelist;
  68. huff->freelist = ppnode;
  69. }
  70. /* Swap the location of these two nodes in the tree */
  71. static void swap (huff_t* huff, node_t *node1, node_t *node2) {
  72. node_t *par1, *par2;
  73. par1 = node1->parent;
  74. par2 = node2->parent;
  75. if (par1) {
  76. if (par1->left == node1) {
  77. par1->left = node2;
  78. } else {
  79. par1->right = node2;
  80. }
  81. } else {
  82. huff->tree = node2;
  83. }
  84. if (par2) {
  85. if (par2->left == node2) {
  86. par2->left = node1;
  87. } else {
  88. par2->right = node1;
  89. }
  90. } else {
  91. huff->tree = node1;
  92. }
  93. node1->parent = par2;
  94. node2->parent = par1;
  95. }
  96. /* Swap these two nodes in the linked list (update ranks) */
  97. static void swaplist(node_t *node1, node_t *node2) {
  98. node_t *par1;
  99. par1 = node1->next;
  100. node1->next = node2->next;
  101. node2->next = par1;
  102. par1 = node1->prev;
  103. node1->prev = node2->prev;
  104. node2->prev = par1;
  105. if (node1->next == node1) {
  106. node1->next = node2;
  107. }
  108. if (node2->next == node2) {
  109. node2->next = node1;
  110. }
  111. if (node1->next) {
  112. node1->next->prev = node1;
  113. }
  114. if (node2->next) {
  115. node2->next->prev = node2;
  116. }
  117. if (node1->prev) {
  118. node1->prev->next = node1;
  119. }
  120. if (node2->prev) {
  121. node2->prev->next = node2;
  122. }
  123. }
  124. /* Do the increments */
  125. static void increment(huff_t* huff, node_t *node) {
  126. node_t *lnode;
  127. if (!node) {
  128. return;
  129. }
  130. if (node->next != NULL && node->next->weight == node->weight) {
  131. lnode = *node->head;
  132. if (lnode != node->parent) {
  133. swap(huff, lnode, node);
  134. }
  135. swaplist(lnode, node);
  136. }
  137. if (node->prev && node->prev->weight == node->weight) {
  138. *node->head = node->prev;
  139. } else {
  140. *node->head = NULL;
  141. free_ppnode(huff, node->head);
  142. }
  143. node->weight++;
  144. if (node->next && node->next->weight == node->weight) {
  145. node->head = node->next->head;
  146. } else {
  147. node->head = get_ppnode(huff);
  148. *node->head = node;
  149. }
  150. if (node->parent) {
  151. increment(huff, node->parent);
  152. if (node->prev == node->parent) {
  153. swaplist(node, node->parent);
  154. if (*node->head == node) {
  155. *node->head = node->parent;
  156. }
  157. }
  158. }
  159. }
  160. void Huff_addRef(huff_t* huff, byte ch) {
  161. node_t *tnode, *tnode2;
  162. if (huff->loc[ch] == NULL) { /* if this is the first transmission of this node */
  163. tnode = &(huff->nodeList[huff->blocNode++]);
  164. tnode2 = &(huff->nodeList[huff->blocNode++]);
  165. tnode2->symbol = INTERNAL_NODE;
  166. tnode2->weight = 1;
  167. tnode2->next = huff->lhead->next;
  168. if (huff->lhead->next) {
  169. huff->lhead->next->prev = tnode2;
  170. if (huff->lhead->next->weight == 1) {
  171. tnode2->head = huff->lhead->next->head;
  172. } else {
  173. tnode2->head = get_ppnode(huff);
  174. *tnode2->head = tnode2;
  175. }
  176. } else {
  177. tnode2->head = get_ppnode(huff);
  178. *tnode2->head = tnode2;
  179. }
  180. huff->lhead->next = tnode2;
  181. tnode2->prev = huff->lhead;
  182. tnode->symbol = ch;
  183. tnode->weight = 1;
  184. tnode->next = huff->lhead->next;
  185. if (huff->lhead->next) {
  186. huff->lhead->next->prev = tnode;
  187. if (huff->lhead->next->weight == 1) {
  188. tnode->head = huff->lhead->next->head;
  189. } else {
  190. /* this should never happen */
  191. tnode->head = get_ppnode(huff);
  192. *tnode->head = tnode2;
  193. }
  194. } else {
  195. /* this should never happen */
  196. tnode->head = get_ppnode(huff);
  197. *tnode->head = tnode;
  198. }
  199. huff->lhead->next = tnode;
  200. tnode->prev = huff->lhead;
  201. tnode->left = tnode->right = NULL;
  202. if (huff->lhead->parent) {
  203. if (huff->lhead->parent->left == huff->lhead) { /* lhead is guaranteed to by the NYT */
  204. huff->lhead->parent->left = tnode2;
  205. } else {
  206. huff->lhead->parent->right = tnode2;
  207. }
  208. } else {
  209. huff->tree = tnode2;
  210. }
  211. tnode2->right = tnode;
  212. tnode2->left = huff->lhead;
  213. tnode2->parent = huff->lhead->parent;
  214. huff->lhead->parent = tnode->parent = tnode2;
  215. huff->loc[ch] = tnode;
  216. increment(huff, tnode2->parent);
  217. } else {
  218. increment(huff, huff->loc[ch]);
  219. }
  220. }
  221. /* Get a symbol */
  222. int Huff_Receive (node_t *node, int *ch, byte *fin) {
  223. while (node && node->symbol == INTERNAL_NODE) {
  224. if (get_bit(fin)) {
  225. node = node->right;
  226. } else {
  227. node = node->left;
  228. }
  229. }
  230. if (!node) {
  231. return 0;
  232. // Com_Error(ERR_DROP, "Illegal tree!\n");
  233. }
  234. return (*ch = node->symbol);
  235. }
  236. /* Get a symbol */
  237. void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) {
  238. bloc = *offset;
  239. while (node && node->symbol == INTERNAL_NODE) {
  240. if (get_bit(fin)) {
  241. node = node->right;
  242. } else {
  243. node = node->left;
  244. }
  245. }
  246. if (!node) {
  247. *ch = 0;
  248. return;
  249. // Com_Error(ERR_DROP, "Illegal tree!\n");
  250. }
  251. *ch = node->symbol;
  252. *offset = bloc;
  253. }
  254. /* Send the prefix code for this node */
  255. static void send(node_t *node, node_t *child, byte *fout) {
  256. if (node->parent) {
  257. send(node->parent, node, fout);
  258. }
  259. if (child) {
  260. if (node->right == child) {
  261. add_bit(1, fout);
  262. } else {
  263. add_bit(0, fout);
  264. }
  265. }
  266. }
  267. /* Send a symbol */
  268. void Huff_transmit (huff_t *huff, int ch, byte *fout) {
  269. int i;
  270. if (huff->loc[ch] == NULL) {
  271. /* node_t hasn't been transmitted, send a NYT, then the symbol */
  272. Huff_transmit(huff, NYT, fout);
  273. for (i = 7; i >= 0; i--) {
  274. add_bit((char)((ch >> i) & 0x1), fout);
  275. }
  276. } else {
  277. send(huff->loc[ch], NULL, fout);
  278. }
  279. }
  280. void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset) {
  281. bloc = *offset;
  282. send(huff->loc[ch], NULL, fout);
  283. *offset = bloc;
  284. }
  285. void Huff_Decompress(msg_t *mbuf, int offset) {
  286. int ch, cch, i, j, size;
  287. byte seq[65536];
  288. byte* buffer;
  289. huff_t huff;
  290. size = mbuf->cursize - offset;
  291. buffer = mbuf->data + offset;
  292. if ( size <= 0 ) {
  293. return;
  294. }
  295. Com_Memset(&huff, 0, sizeof(huff_t));
  296. // Initialize the tree & list with the NYT node
  297. huff.tree = huff.lhead = huff.ltail = huff.loc[NYT] = &(huff.nodeList[huff.blocNode++]);
  298. huff.tree->symbol = NYT;
  299. huff.tree->weight = 0;
  300. huff.lhead->next = huff.lhead->prev = NULL;
  301. huff.tree->parent = huff.tree->left = huff.tree->right = NULL;
  302. cch = buffer[0]*256 + buffer[1];
  303. // don't overflow with bad messages
  304. if ( cch > mbuf->maxsize - offset ) {
  305. cch = mbuf->maxsize - offset;
  306. }
  307. bloc = 16;
  308. for ( j = 0; j < cch; j++ ) {
  309. ch = 0;
  310. // don't overflow reading from the messages
  311. // FIXME: would it be better to have a overflow check in get_bit ?
  312. if ( (bloc >> 3) > size ) {
  313. seq[j] = 0;
  314. break;
  315. }
  316. Huff_Receive(huff.tree, &ch, buffer); /* Get a character */
  317. if ( ch == NYT ) { /* We got a NYT, get the symbol associated with it */
  318. ch = 0;
  319. for ( i = 0; i < 8; i++ ) {
  320. ch = (ch<<1) + get_bit(buffer);
  321. }
  322. }
  323. seq[j] = ch; /* Write symbol */
  324. Huff_addRef(&huff, (byte)ch); /* Increment node */
  325. }
  326. mbuf->cursize = cch + offset;
  327. Com_Memcpy(mbuf->data + offset, seq, cch);
  328. }
  329. extern int oldsize;
  330. void Huff_Compress(msg_t *mbuf, int offset) {
  331. int i, ch, size;
  332. byte seq[65536];
  333. byte* buffer;
  334. huff_t huff;
  335. size = mbuf->cursize - offset;
  336. buffer = mbuf->data+ + offset;
  337. if (size<=0) {
  338. return;
  339. }
  340. Com_Memset(&huff, 0, sizeof(huff_t));
  341. // Add the NYT (not yet transmitted) node into the tree/list */
  342. huff.tree = huff.lhead = huff.loc[NYT] = &(huff.nodeList[huff.blocNode++]);
  343. huff.tree->symbol = NYT;
  344. huff.tree->weight = 0;
  345. huff.lhead->next = huff.lhead->prev = NULL;
  346. huff.tree->parent = huff.tree->left = huff.tree->right = NULL;
  347. huff.loc[NYT] = huff.tree;
  348. seq[0] = (size>>8);
  349. seq[1] = size&0xff;
  350. bloc = 16;
  351. for (i=0; i<size; i++ ) {
  352. ch = buffer[i];
  353. Huff_transmit(&huff, ch, seq); /* Transmit symbol */
  354. Huff_addRef(&huff, (byte)ch); /* Do update */
  355. }
  356. bloc += 8; // next byte
  357. mbuf->cursize = (bloc>>3) + offset;
  358. Com_Memcpy(mbuf->data+offset, seq, (bloc>>3));
  359. }
  360. void Huff_Init(huffman_t *huff) {
  361. Com_Memset(&huff->compressor, 0, sizeof(huff_t));
  362. Com_Memset(&huff->decompressor, 0, sizeof(huff_t));
  363. // Initialize the tree & list with the NYT node
  364. huff->decompressor.tree = huff->decompressor.lhead = huff->decompressor.ltail = huff->decompressor.loc[NYT] = &(huff->decompressor.nodeList[huff->decompressor.blocNode++]);
  365. huff->decompressor.tree->symbol = NYT;
  366. huff->decompressor.tree->weight = 0;
  367. huff->decompressor.lhead->next = huff->decompressor.lhead->prev = NULL;
  368. huff->decompressor.tree->parent = huff->decompressor.tree->left = huff->decompressor.tree->right = NULL;
  369. // Add the NYT (not yet transmitted) node into the tree/list */
  370. huff->compressor.tree = huff->compressor.lhead = huff->compressor.loc[NYT] = &(huff->compressor.nodeList[huff->compressor.blocNode++]);
  371. huff->compressor.tree->symbol = NYT;
  372. huff->compressor.tree->weight = 0;
  373. huff->compressor.lhead->next = huff->compressor.lhead->prev = NULL;
  374. huff->compressor.tree->parent = huff->compressor.tree->left = huff->compressor.tree->right = NULL;
  375. huff->compressor.loc[NYT] = huff->compressor.tree;
  376. }