PageRenderTime 61ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/source/Engine/JetEngine/Bitmap/Compression/huffman2.cpp

#
C++ | 1880 lines | 1310 code | 252 blank | 318 comment | 243 complexity | 006db9bc83f08d71559025f0d7cc2f2b MD5 | raw file
  1. /****************************************************************************************/
  2. /* HUFFMAN2.C */
  3. /* */
  4. /* Author: */
  5. /* Description: */
  6. /* */
  7. /* The contents of this file are subject to the Jet3D Public License */
  8. /* Version 1.02 (the "License"); you may not use this file except in */
  9. /* compliance with the License. You may obtain a copy of the License at */
  10. /* http://www.jet3d.com */
  11. /* */
  12. /* Software distributed under the License is distributed on an "AS IS" */
  13. /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
  14. /* the License for the specific language governing rights and limitations */
  15. /* under the License. */
  16. /* */
  17. /* The Original Code is Jet3D, released December 12, 1999. */
  18. /* Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved */
  19. /* */
  20. /****************************************************************************************/
  21. /******
  22. problem :
  23. encoding/decoding when GotNumSymbols == 1 needs to be handled as
  24. a special case.
  25. I think encoding is Ok, but DecodeBuildTree needs to set NodeBase->Char
  26. to be the one char to code
  27. --
  28. Macros need to be updated to handle this case
  29. *********/
  30. /*
  31. * notez : there's kind of a bug in FastDecode :
  32. * if the last code in decodes to more than one char, you might
  33. * skip more bits than were written
  34. *
  35. * this can mess you up in merge-bit-stream cases
  36. *
  37. *
  38. * note: this is handled properly by FastDecodeArray
  39. *
  40. */
  41. /*
  42. * notez : you must PackCodeLens BEFORE BuildEncodeTable
  43. * in order to set Min & Max CodeLen
  44. * if you don't PackCodeLens, call SetMinMaxCodeLen
  45. */
  46. /*
  47. *
  48. * Huffman2 : 7-5-96
  49. *
  50. * not a general purpose Huffman utility
  51. * does not generate Huffman codes. Codes have same lengths, but
  52. * values are ordered thus:
  53. * for each code length, values are ordered by alphabetic order
  54. *
  55. * ---
  56. *
  57. * Encode BuildTree time is nearly identical to old Huffman
  58. * Decode BuildTree time is MUCH shorter!
  59. * EncodeC time is identical
  60. * DecodeC time is shorter
  61. *
  62. * ---
  63. *
  64. * 7-6-95 :
  65. * FastDecode ! uses table lookup for multi-symbol-at-a-time operation!
  66. *
  67. * 7-7-95
  68. * I just peeked the IJG JPEG source & discovered that they use
  69. * this method with MaxNumMadeChars = 1
  70. *
  71. */
  72. //#define DEBUG
  73. /* DEBUG toggles some tests which
  74. garauntee proper operation, but take some time to do */
  75. //#define DO_MEMCLEARS
  76. /* DO_MEMCLEARS toggles some unnecessary memclears
  77. probably a good idea to turn it on for debug purposes */
  78. #define PACKCODES_TOPSYM
  79. /* if this is on, then in PackCodeLens, the value of the highest
  80. non-zero-count symbol is written, and codes are only written up
  81. to that symbol ; this helps compression a good deal in most cases */
  82. /*
  83. *
  84. * Modularized Static Huffman encoding
  85. *
  86. * Notes: works on a LBitIOInfo structure
  87. * this structure must be independently allocated and destroyd
  88. *
  89. * Uses the O(n) Huffman algorithm with QuickSort, RadixSort, or NoSort
  90. * NOTEZ: RadixSort assumes counts are bounded in the range [0,MaxCharCount]
  91. * if AlphaSize > 64 or so, use the RadixSort
  92. *
  93. * You are responsible for calling
  94. * LBitIO_FlushWrite(HI->BII);
  95. * yourself. It is no longer done in EncodeCDone
  96. *
  97. * You must also call
  98. * LBitIO_InitRead(HI->BII);
  99. * yourself before doing any reads. It is no longer done in DecodeCInit
  100. *
  101. * 7-4-95 new stuff:
  102. * 1. charcounts are now packed as codelengths only (much better packing)
  103. * 2. this creates a problem : two chars with different counts but the
  104. * same code length are no longer distinguishable by the decoder,
  105. * but they were distinguished by the encoder!
  106. * 3. result : Huffman2 : uses manual code assignment
  107. *
  108. *
  109. */
  110. #include "stdafx.h"
  111. #include <limits.h>
  112. #include "Utility.h"
  113. #include "MemPool.h"
  114. #include "lbitio.h"
  115. #include "IntMath.h"
  116. #pragma warning(disable : 4244)
  117. #ifdef DEBUG
  118. #include <stdio.h>
  119. #endif
  120. #include "huffman2.h"
  121. #define memclearFast(m,s) memclear(m,s*4)
  122. #define FreeMem(m,s) destroy(m)
  123. //protos:
  124. struct Huff2Info * Huff2_Init(long NumSymbols,struct LBitIOInfo * BII,long SortType);
  125. void Huff2_CleanUp(struct Huff2Info *HI);
  126. void Huff2_GetMaxCharCount(struct Huff2Info *HI,long * CharCounts);
  127. void Huff2_ScaleCounts(struct Huff2Info *HI,long * CharCounts,long MaxVal);
  128. jeBoolean Huff2_BuildCodeLens(struct Huff2Info *HI,long *CharCounts);
  129. jeBoolean Huff2_BuildEncodeTable(struct Huff2Info *HI);
  130. jeBoolean Huff2_BuildDecodeTable(struct Huff2Info *HI);
  131. jeBoolean Huff2_BuildFastDecodeTable(struct Huff2Info *HI);
  132. void Huff2_EncodeC(struct Huff2Info *HI,uint16 C);
  133. uint16 Huff2_DecodeC(struct Huff2Info *HI);
  134. uint16 Huff2_FastDecodeC(struct Huff2Info *HI);
  135. jeBoolean Huff2_FastDecodeArray(struct Huff2Info *HI,uint8 * Array,long ArrayLen);
  136. jeBoolean Huff2_FindDecodeOne(struct Huff2Info *HI);
  137. void Huff2_SetMinMaxCodeLen(struct Huff2Info *HI);
  138. void Huff2_PackCodeLens(struct Huff2Info *HI);
  139. void Huff2_UnPackCodeLens(struct Huff2Info *HI);
  140. void Huff2_PackCodeLens_Delta(struct Huff2Info *HI,long * LastCodeLens);
  141. void Huff2_UnPackCodeLens_Delta(struct Huff2Info *HI,long * LastCodeLens);
  142. //sort protos:
  143. jeBoolean Huff2RadixSort(struct Huff2CodeNode ** BucketArray,
  144. long MaxCharCount,struct Huff2CodeNode ** Array,long ArraySize);
  145. void Huff2QuickSort(long Left,long Right);
  146. struct Huff2CodeNode ** Huff2QuickSortArray; //global for recursion non-stacking
  147. //functions:
  148. /*
  149. */
  150. struct Huff2Info * Huff2_Init(long NumSymbols,struct LBitIOInfo * BII,long SortType)
  151. {
  152. struct Huff2Info * HI;
  153. if ( (HI = (struct Huff2Info *)JE_RAM_ALLOCATE_CLEAR(sizeof(struct Huff2Info))) == NULL )
  154. return(NULL);
  155. HI->GotNumSymbols = 0;
  156. HI->NumSymbols = NumSymbols;
  157. HI->MaxCharCount = LONG_MAX;
  158. HI->BII = BII;
  159. HI->SortType = SortType;
  160. HI->CodeNodeHunkI = 0;
  161. if ( (HI->CodeLenTable = (long *)JE_RAM_ALLOCATE_CLEAR(HI->NumSymbols*sizeof(long))) == NULL )
  162. {
  163. Huff2_CleanUp(HI);
  164. return(NULL);
  165. }
  166. if ( (HI->NumCodesOfLen = (long *)JE_RAM_ALLOCATE_CLEAR(32*sizeof(long))) == NULL )
  167. {
  168. Huff2_CleanUp(HI);
  169. return(NULL);
  170. }
  171. if ( (HI->CodePrefixByLen = (uint32 *)JE_RAM_ALLOCATE_CLEAR(32*sizeof(uint32))) == NULL )
  172. {
  173. Huff2_CleanUp(HI);
  174. return(NULL);
  175. }
  176. return(HI);
  177. }
  178. /*
  179. */
  180. void Huff2_CleanUp(struct Huff2Info * HI)
  181. {
  182. FreeMem(HI->NodeWork,sizeofpointer*HI->NumSymbols);
  183. FreeMem(HI->MadeNodeWork,sizeofpointer*HI->NumSymbols*2);
  184. FreeMem(HI->CodeLenTable,HI->NumSymbols*sizeof(long));
  185. FreeMem(HI->NumCodesOfLen,32*sizeof(long));
  186. FreeMem(HI->CodePrefixByLen,32*sizeof(uint32));
  187. FreeMem(HI->CodeNodeHunk,sizeof(struct Huff2CodeNode)*2*HI->NumSymbols);
  188. FreeMem(HI->StackArray,2*(HI->NumSymbols)*sizeof(uint32));
  189. FreeMem(HI->EnDe_codeTable,HI->EnDe_codeTableLen);
  190. if ( HI->SortType == HUFF2_SORT_RADIX )
  191. {
  192. FreeMem(HI->SortWork,sizeofpointer*(HI->MaxCharCount + 1));
  193. }
  194. FreeMem(HI,sizeof(struct Huff2Info));
  195. }
  196. /*
  197. * Compute the codelens into Huff2Info from the CharCounts array
  198. *
  199. NOTEZ: MadeNodeWork is large enough, but you may have the problem of looping
  200. i.e. ( (MadeNodeWorkIn - MadeNodeWorkOut) < NumSymbols ) is just fine,
  201. the problem is ( MadeNodeWorkIn < NumSymbols ) isn't JE_TRUE
  202. thus all made-array lookups are done: [MadeNodeWorkIn % NumSymbols]
  203. 10-15-95 : alloced MadeNodeWork to double length so as to eliminate this.
  204. */
  205. /*
  206. *
  207. * return values :
  208. * 1 = all ok
  209. * 0 = error
  210. *
  211. */
  212. jeBoolean Huff2_BuildCodeLens(struct Huff2Info *HI,long *CharCounts)
  213. {
  214. register struct Huff2CodeNode * CurNode;
  215. register struct Huff2CodeNode ** NodeWork;
  216. register long i,NumSymbols,GotNumSymbols;
  217. /*long swapchar;*/
  218. if ( !HI->CodeNodeHunk || !HI->NodeWork || !HI->MadeNodeWork )
  219. {
  220. if ( HI->CodeNodeHunk || HI->NodeWork || HI->MadeNodeWork )
  221. {
  222. return(0);
  223. }
  224. HI->NodeWork = (struct Huff2CodeNode **)JE_RAM_ALLOCATE(sizeofpointer*HI->NumSymbols);
  225. HI->MadeNodeWork = (struct Huff2CodeNode **)JE_RAM_ALLOCATE(sizeofpointer*2*HI->NumSymbols);
  226. HI->CodeNodeHunk = (struct Huff2CodeNode *)JE_RAM_ALLOCATE(sizeof(struct Huff2CodeNode)*2*HI->NumSymbols);
  227. if ( !HI->CodeNodeHunk || !HI->NodeWork || !HI->MadeNodeWork )
  228. {
  229. return(0);
  230. }
  231. }
  232. /* reset, if this is an already-used Huff2Info */
  233. if ( HI->NodeBase )
  234. {
  235. HI->NodeBase = NULL;
  236. HI->CodeNodeHunkI = 0;
  237. HI->GotNumSymbols = 0;
  238. HI->MaxCharCount = LONG_MAX;
  239. HI->CodeNodeHunkI = 0;
  240. HI->MinCodeLen = HI->MaxCodeLen = 0;
  241. #ifdef DO_MEMCLEARS
  242. memclearFast((long *)HI->CodeNodeHunk,sizeof(struct Huff2CodeNode)*HI->NumSymbols);
  243. memclearFast((long *)HI->NodeWork,HI->NumSymbols);
  244. memclearFast((long *)HI->MadeNodeWork,HI->NumSymbols);
  245. #endif // DO_MEMCLEARS
  246. memclearFast((long *)HI->CodeLenTable,HI->NumSymbols);
  247. memclearFast((long *)HI->NumCodesOfLen,32);
  248. memclearFast((long *)HI->CodePrefixByLen,32);
  249. }
  250. NodeWork = HI->NodeWork;
  251. NumSymbols = HI->NumSymbols;
  252. /*
  253. * Read the chars into NodeWork
  254. * packing out the NULLs
  255. *
  256. */
  257. GotNumSymbols=0;
  258. for(i=0;i<NumSymbols;i++) /* $ 12% !! */
  259. {
  260. if ( CharCounts[i] > 0 )
  261. {
  262. NodeWork[GotNumSymbols] = HI->CodeNodeHunk + HI->CodeNodeHunkI; HI->CodeNodeHunkI++;
  263. NodeWork[GotNumSymbols]->Char = i;
  264. NodeWork[GotNumSymbols]->Count = CharCounts[i];
  265. NodeWork[GotNumSymbols]->Up = NodeWork[GotNumSymbols]->Down = NULL;
  266. GotNumSymbols++;
  267. }
  268. }
  269. /* !!!! you should not do any huffman coding if this ever happens ! */
  270. /* NOTEZ: BuildEncodeTable WILL fail ! */
  271. /* PackCodeLens & UnPackCodeLens will work */
  272. HI->GotNumSymbols = GotNumSymbols;
  273. if ( GotNumSymbols < 2 )
  274. {
  275. if ( GotNumSymbols == 0 )
  276. {
  277. return(1);
  278. }
  279. else
  280. {
  281. HI->NodeBase = NodeWork[0];
  282. HI->NodeBase->Up = NULL;
  283. HI->NodeBase->Down = NULL;
  284. HI->CodeLenTable[HI->NodeBase->Char] = 1;
  285. HI->NumCodesOfLen[1] = 1;
  286. /* call PackCodeLens anyway, so the decoder knows which char to copy */
  287. return(1);
  288. }
  289. }
  290. /*
  291. * sort NodeWork in order of ascending counts
  292. *
  293. */
  294. switch(HI->SortType)
  295. {
  296. case HUFF2_SORT_NONE:
  297. break;
  298. case HUFF2_SORT_RADIX:
  299. if ( ! HI->SortWork )
  300. {
  301. if ( HI->MaxCharCount == LONG_MAX )
  302. {
  303. return(0);
  304. }
  305. if ( (HI->SortWork = JE_RAM_ALLOCATE(sizeofpointer*(HI->MaxCharCount + 1))) == NULL )
  306. {
  307. return(0);
  308. }
  309. }
  310. if ( ! Huff2RadixSort((struct Huff2CodeNode **)HI->SortWork,
  311. HI->MaxCharCount,NodeWork,GotNumSymbols) ) return(0);
  312. break;
  313. case HUFF2_SORT_QSORT:
  314. Huff2QuickSortArray = NodeWork;
  315. Huff2QuickSort(0,GotNumSymbols-1);
  316. break;
  317. default:
  318. return(0);
  319. break;
  320. }
  321. /* sort puts lowest value of ->Count first */
  322. /* register the tree-building variables */
  323. {
  324. register long MadeNodeWorkIn,MadeNodeWorkOut,NodeWorkOut;
  325. register struct Huff2CodeNode ** MadeNodeWork;
  326. MadeNodeWork = HI->MadeNodeWork;
  327. NodeWorkOut=0;
  328. MadeNodeWorkIn = 0;
  329. MadeNodeWorkOut = 0;
  330. /*
  331. * Build the tree while there are more leaf-nodes to go
  332. *
  333. */
  334. while( NodeWorkOut < (GotNumSymbols-1) ) /* $ 38 % */
  335. {
  336. CurNode = HI->CodeNodeHunk + HI->CodeNodeHunkI; HI->CodeNodeHunkI++;
  337. CurNode->Char = HUFF2_CODE_BRANCH;
  338. #ifdef DEBUG
  339. if ( HI->CodeNodeHunkI >= (NumSymbols*2) )
  340. {
  341. BrandoError(" HI->CodeNodeHunkI >= (NumSymbols*2) !");
  342. exit(1);
  343. }
  344. #endif // DEBUG
  345. /*
  346. * get the lowest two
  347. * if counts are equal, use a madenode before a leafnode
  348. *
  349. */
  350. if ( MadeNodeWorkOut < MadeNodeWorkIn )
  351. {
  352. if ( NodeWork[NodeWorkOut]->Count < MadeNodeWork[MadeNodeWorkOut]->Count )
  353. {
  354. CurNode->Down = NodeWork[NodeWorkOut]; NodeWorkOut++;
  355. }
  356. else
  357. {
  358. CurNode->Down = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  359. }
  360. if ( MadeNodeWorkOut < MadeNodeWorkIn )
  361. {
  362. if ( NodeWork[NodeWorkOut]->Count < MadeNodeWork[MadeNodeWorkOut]->Count )
  363. {
  364. CurNode->Up = NodeWork[NodeWorkOut]; NodeWorkOut++;
  365. }
  366. else
  367. {
  368. CurNode->Up = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  369. }
  370. }
  371. else
  372. {
  373. CurNode->Up = NodeWork[NodeWorkOut]; NodeWorkOut++;
  374. }
  375. }
  376. else
  377. {
  378. CurNode->Down = NodeWork[NodeWorkOut]; NodeWorkOut++;
  379. CurNode->Up = NodeWork[NodeWorkOut]; NodeWorkOut++;
  380. }
  381. /* ->Down gets the lower valued count & the lower valued character */
  382. /* make sure lower char is on the Down pointer */
  383. /* notez: this is only needed in encode ! */
  384. /* don't bother swapping the counts, they're not needed anymore */
  385. /*
  386. if ( CurNode->Down->Char != HUFF2_CODE_BRANCH &&
  387. CurNode->Up->Char != HUFF2_CODE_BRANCH )
  388. {
  389. if ( CurNode->Down->Char > CurNode->Up->Char )
  390. {
  391. swapchar = CurNode->Down->Char;
  392. CurNode->Down->Char = CurNode->Up->Char;
  393. CurNode->Up->Char = swapchar;
  394. }
  395. }
  396. */
  397. /*
  398. * put them into a MadeNode
  399. *
  400. */
  401. MadeNodeWork[MadeNodeWorkIn] = CurNode; MadeNodeWorkIn++;
  402. CurNode->Count = CurNode->Down->Count + CurNode->Up->Count;
  403. }
  404. /*
  405. * we stop the prior loop when there are less than 2 nodework symbols left
  406. * if there is only one left, this loops until it is eaten off
  407. *
  408. */
  409. while ( NodeWorkOut < GotNumSymbols && MadeNodeWorkOut < MadeNodeWorkIn )
  410. {
  411. CurNode = HI->CodeNodeHunk + HI->CodeNodeHunkI; HI->CodeNodeHunkI++;
  412. CurNode->Char = HUFF2_CODE_BRANCH;
  413. #ifdef DEBUG
  414. if ( HI->CodeNodeHunkI >= (NumSymbols*2) )
  415. {
  416. BrandoError(" HI->CodeNodeHunkI >= (NumSymbols*2) !");
  417. exit(1);
  418. }
  419. #endif // DEBUG
  420. if ( NodeWork[NodeWorkOut]->Count < MadeNodeWork[MadeNodeWorkOut]->Count )
  421. {
  422. CurNode->Down = NodeWork[NodeWorkOut]; NodeWorkOut++;
  423. }
  424. else
  425. {
  426. CurNode->Down = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  427. }
  428. if ( MadeNodeWorkOut < MadeNodeWorkIn )
  429. {
  430. if ( NodeWorkOut < GotNumSymbols )
  431. {
  432. if ( NodeWork[NodeWorkOut]->Count < MadeNodeWork[MadeNodeWorkOut]->Count )
  433. {
  434. CurNode->Up = NodeWork[NodeWorkOut]; NodeWorkOut++;
  435. }
  436. else
  437. {
  438. CurNode->Up = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  439. }
  440. }
  441. else
  442. {
  443. CurNode->Up = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  444. }
  445. }
  446. else
  447. {
  448. CurNode->Up = NodeWork[NodeWorkOut]; NodeWorkOut++;
  449. }
  450. MadeNodeWork[MadeNodeWorkIn] = CurNode; MadeNodeWorkIn++;
  451. CurNode->Count = CurNode->Down->Count + CurNode->Up->Count;
  452. }
  453. /*
  454. * there may still be extras in MadeNodeWork
  455. *
  456. */
  457. while ( MadeNodeWorkOut < (MadeNodeWorkIn-1) )
  458. {
  459. CurNode = HI->CodeNodeHunk + HI->CodeNodeHunkI; HI->CodeNodeHunkI++;
  460. CurNode->Char = HUFF2_CODE_BRANCH;
  461. CurNode->Down = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  462. CurNode->Up = MadeNodeWork[MadeNodeWorkOut]; MadeNodeWorkOut++;
  463. #ifdef DEBUG
  464. if ( HI->CodeNodeHunkI >= (NumSymbols*2) )
  465. {
  466. BrandoError(" HI->CodeNodeHunkI >= (NumSymbols*2) !");
  467. exit(1);
  468. }
  469. #endif // DEBUG
  470. MadeNodeWork[MadeNodeWorkIn] = CurNode; MadeNodeWorkIn++;
  471. CurNode->Count = CurNode->Down->Count + CurNode->Up->Count;
  472. }
  473. /*
  474. * grab the base node out
  475. *
  476. */
  477. HI->NodeBase = MadeNodeWork[(MadeNodeWorkIn-1)];
  478. if ( HI->NodeBase == NULL )
  479. {
  480. return(0); /* debugger catch point */
  481. }
  482. }
  483. /* end tree-building registered variables */
  484. /* now read out the codelens into an array */
  485. {
  486. long * CodeLenTable;
  487. long * NumCodesOfLen;
  488. register struct Huff2CodeNode * CurNode;
  489. register uint32 CurCodeLen;
  490. register uint32 GotC;
  491. register uint32 * StackArray;
  492. register long StackI;
  493. if ( ! HI->StackArray )
  494. {
  495. if ( (HI->StackArray = (uint32 *)JE_RAM_ALLOCATE(2*(HI->NumSymbols)*sizeof(uint32))) == NULL )
  496. return(0);
  497. }
  498. NumCodesOfLen = HI->NumCodesOfLen;
  499. CodeLenTable = HI->CodeLenTable;
  500. StackArray = HI->StackArray;
  501. StackArray[0] = (uint32) HI->NodeBase;
  502. StackArray[1] = 0;
  503. StackI = 2;
  504. while ( StackI > 0 ) /* $ 15% */
  505. {
  506. StackI--;
  507. CurCodeLen = StackArray[StackI];
  508. StackI--;
  509. CurNode = (struct Huff2CodeNode *) StackArray[StackI];
  510. /* traverse all Up branches w/o Stack bumping
  511. remember the Down branches as you go
  512. once you reach the end of an Up, go back and get the
  513. most recent Down & traverse it
  514. */
  515. while ( CurNode )
  516. {
  517. GotC = CurNode->Char;
  518. if ( GotC == HUFF2_CODE_BRANCH )
  519. {
  520. CurCodeLen++;
  521. #ifdef DEBUG
  522. if ( CurCodeLen > 31 )
  523. {
  524. fprintf(stderr,"CodeLen > 31 !");
  525. return(0);
  526. }
  527. #endif
  528. if ( CurNode->Down )
  529. {
  530. GotC = CurNode->Down->Char;
  531. if ( GotC == HUFF2_CODE_BRANCH )
  532. {
  533. StackArray[StackI++] = (uint32) CurNode->Down;
  534. StackArray[StackI++] = CurCodeLen;
  535. #ifdef DEBUG
  536. if ( StackI >= (HI->NumSymbols * 2) )
  537. {
  538. BrandoError("Stack usage higher than expected!");
  539. exit(10);
  540. }
  541. #endif
  542. }
  543. else
  544. {
  545. CodeLenTable[GotC] = CurCodeLen;
  546. NumCodesOfLen[CurCodeLen] ++;
  547. }
  548. }
  549. CurNode = CurNode->Up;
  550. }
  551. else
  552. {
  553. CodeLenTable[GotC] = CurCodeLen;
  554. NumCodesOfLen[CurCodeLen] ++;
  555. CurNode = NULL;
  556. }
  557. }
  558. }
  559. }
  560. /* end codelen-retrieval registered variables */
  561. return(1);
  562. }
  563. /*
  564. * at this point CodeLenTable & NumCodesOfLen are filled out
  565. *
  566. */
  567. jeBoolean Huff2_BuildEncodeTable(struct Huff2Info *HI)
  568. {
  569. uint32 LastCodePrefix;
  570. uint32 * CodePrefixByLen;
  571. uint32 * CharToCodeTable;
  572. long * CodeLenTable;
  573. long * NumCodesOfLen;
  574. long NumSymbols;
  575. long i;
  576. long CurCodeLen;
  577. uint32 CurCode;
  578. if ( HI->GotNumSymbols < 2 ) return(1);
  579. NumSymbols = HI->NumSymbols;
  580. if ( HI->MaxCodeLen == 0 )
  581. return(0);
  582. if ( HI->MaxCodeLen > 30 )
  583. return(0);
  584. if ( HI->EnDe_codeTable )
  585. {
  586. CharToCodeTable = (uint32 *) HI->EnDe_codeTable;
  587. memclear((long *)CharToCodeTable,HI->EnDe_codeTableLen);
  588. }
  589. else
  590. {
  591. if ( (CharToCodeTable = (uint32 *)JE_RAM_ALLOCATE_CLEAR(NumSymbols*sizeof(uint32))) == NULL )
  592. return(0);
  593. HI->EnDe_codeTable = (void *) CharToCodeTable;
  594. HI->EnDe_codeTableLen = NumSymbols*sizeof(uint32);
  595. }
  596. CodePrefixByLen = HI->CodePrefixByLen;
  597. CodeLenTable = HI->CodeLenTable;
  598. NumCodesOfLen = HI->NumCodesOfLen;
  599. LastCodePrefix = 0;
  600. CodePrefixByLen[HI->MinCodeLen] = 0;
  601. for(i=(HI->MinCodeLen);i<(HI->MaxCodeLen);)
  602. {
  603. LastCodePrefix = (LastCodePrefix + NumCodesOfLen[i]) << 1;
  604. i++;
  605. CodePrefixByLen[i] = LastCodePrefix;
  606. }
  607. for(i=0;i<NumSymbols;i++)
  608. {
  609. CurCodeLen = CodeLenTable[i];
  610. if ( CurCodeLen > 0 )
  611. {
  612. CurCode = CodePrefixByLen[CurCodeLen]++;
  613. CharToCodeTable[i] = CurCode;
  614. }
  615. }
  616. return(1);
  617. }
  618. /*
  619. * at this point CodeLenTable & NumCodesOfLen are filled out
  620. *
  621. */
  622. jeBoolean Huff2_BuildDecodeTable(struct Huff2Info *HI)
  623. {
  624. uint32 BaseCodeByLen[32]; /* I'm lazy! So sue me! */
  625. uint32 LastCodePrefix;
  626. uint32 * CodePrefixByLen;
  627. uint16 * DecodeTable;
  628. long * CodeLenTable;
  629. long * NumCodesOfLen;
  630. long NumSymbols;
  631. long i,CurCodeLen;
  632. uint32 CurCode,PackedCode;
  633. long NumCodesOfLowerLen;
  634. if ( HI->GotNumSymbols < 2 ) return( Huff2_FindDecodeOne(HI) );
  635. NumSymbols = HI->NumSymbols;
  636. if ( HI->MaxCodeLen == 0 )
  637. return(0);
  638. if ( HI->MaxCodeLen > 30 )
  639. return(0);
  640. if ( HI->EnDe_codeTable )
  641. {
  642. DecodeTable = (uint16 *) HI->EnDe_codeTable;
  643. memclear((long *)DecodeTable,HI->EnDe_codeTableLen);
  644. }
  645. else
  646. {
  647. HI->EnDe_codeTableLen = 2*NumSymbols*sizeof(uint16);
  648. if ( (DecodeTable = (uint16 *)JE_RAM_ALLOCATE_CLEAR(HI->EnDe_codeTableLen)) == NULL )
  649. return(0);
  650. HI->EnDe_codeTable = (void *) DecodeTable;
  651. }
  652. CodePrefixByLen = HI->CodePrefixByLen;
  653. CodeLenTable = HI->CodeLenTable;
  654. NumCodesOfLen = HI->NumCodesOfLen;
  655. LastCodePrefix = 0;
  656. NumCodesOfLowerLen = 0;
  657. CodePrefixByLen[HI->MinCodeLen] = 0;
  658. BaseCodeByLen[HI->MinCodeLen] = 0;
  659. for(i=(HI->MinCodeLen);i<(HI->MaxCodeLen);)
  660. {
  661. LastCodePrefix = (LastCodePrefix + NumCodesOfLen[i]) << 1;
  662. NumCodesOfLowerLen += NumCodesOfLen[i];
  663. i++;
  664. CodePrefixByLen[i] = LastCodePrefix;
  665. BaseCodeByLen[i] = LastCodePrefix - NumCodesOfLowerLen;
  666. }
  667. for(i=0;i<NumSymbols;i++)
  668. {
  669. CurCodeLen = CodeLenTable[i];
  670. if ( CurCodeLen > 0 )
  671. {
  672. CurCode = CodePrefixByLen[CurCodeLen]++;
  673. PackedCode = CurCode - BaseCodeByLen[CurCodeLen];
  674. DecodeTable[PackedCode] = CurCodeLen;
  675. DecodeTable[PackedCode+NumSymbols] = i;
  676. }
  677. }
  678. for(i=(HI->MinCodeLen);i<=(HI->MaxCodeLen);i++)
  679. {
  680. CodePrefixByLen[i] = BaseCodeByLen[i];
  681. }
  682. return(1);
  683. }
  684. /*
  685. * The FastDecodeTable is a raw 8 bit table (256 entries)
  686. * it is indexed by the next 8 bits of the input bitstream
  687. * and the value of the table is :
  688. * number of bits used (max of 8) = 3 bits -> 1byte
  689. * number of chars made (max of 4) = 2 bits -> 1 byte
  690. * values of chars made (max of 4) = 8 bytes
  691. * total size = 256*10 = 2560 bytes (not bad!)
  692. * ( note that this could be as low as 256*5 = 1280 bytes )
  693. *
  694. * note that you must also keep the old decodetable around,
  695. * in case the code is longer than 8 bits ( numberofcharsmade == 0 )
  696. *
  697. * <> todo: make this routine take the number of bits of the table
  698. * as a parameter
  699. *
  700. */
  701. jeBoolean Huff2_BuildFastDecodeTable(struct Huff2Info *HI)
  702. {
  703. struct FastDecodeItem * FastDecodeTable;
  704. uint16 * DecodeTable;
  705. long NumSymbols;
  706. long Huff2CodeLen;
  707. uint32 CurCode,StartCode,Huff2Code,CheckCode,ReadCodeMask,PackedCode;
  708. long DecodeTableLen,FastDecodeTableLen;
  709. long MinCodeLen,NumBitsUsed;
  710. uint16 GotChar;
  711. uint32 * CodePrefixByLen;
  712. if ( HI->GotNumSymbols < 2 ) return( Huff2_FindDecodeOne(HI) );
  713. CodePrefixByLen = HI->CodePrefixByLen;
  714. NumSymbols = HI->NumSymbols;
  715. MinCodeLen = HI->MinCodeLen;
  716. if ( HI->MaxCodeLen == 0 )
  717. return(0);
  718. if ( HI->MaxCodeLen > 30 )
  719. return(0);
  720. DecodeTableLen = 2*NumSymbols*sizeof(uint16);
  721. FastDecodeTableLen = 256*sizeof(struct FastDecodeItem);
  722. if ( HI->EnDe_codeTable )
  723. {
  724. DecodeTable = (uint16 *)HI->EnDe_codeTable;
  725. FastDecodeTable = (struct FastDecodeItem *) ( (char *)HI->EnDe_codeTable + DecodeTableLen );
  726. memclear((long *)DecodeTable,DecodeTableLen);
  727. memclear((long *)FastDecodeTable,FastDecodeTableLen);
  728. }
  729. else
  730. {
  731. HI->EnDe_codeTableLen = DecodeTableLen + FastDecodeTableLen;
  732. if ( (HI->EnDe_codeTable = JE_RAM_ALLOCATE_CLEAR(HI->EnDe_codeTableLen)) == NULL )
  733. return(0);
  734. DecodeTable = (uint16 *)HI->EnDe_codeTable;
  735. FastDecodeTable = (struct FastDecodeItem *) ( ((char *)HI->EnDe_codeTable) + DecodeTableLen );
  736. }
  737. /* build the old style table */
  738. if ( ! Huff2_BuildDecodeTable(HI) )
  739. return(0);
  740. /* now DecodeTable is filled out */
  741. /* step through all the codes & find what chars correspond to them
  742. when you find a char for a code, propagate it through all codes which
  743. have that as a prefix
  744. keep going until NumBitsFree < Huff2CodeLen for all entries */
  745. for(StartCode=0;StartCode<255;StartCode++)
  746. {
  747. NumBitsUsed = FastDecodeTable[StartCode].NumBitsUsed;
  748. while ( (8-NumBitsUsed) >= MinCodeLen && FastDecodeTable[StartCode].NumCharsMade < FD_MAXCHARSMADE )
  749. {
  750. CurCode = StartCode ;
  751. /* find char that encodes to curcode */
  752. Huff2CodeLen = MinCodeLen;
  753. Huff2Code = ( CurCode >> (8 - NumBitsUsed - Huff2CodeLen) ) & ( (1<<Huff2CodeLen) - 1 ) ;
  754. ReadCodeMask = 1 << ( 7 - NumBitsUsed - Huff2CodeLen ) ;
  755. PackedCode = Huff2Code;
  756. while( DecodeTable[PackedCode] != Huff2CodeLen )
  757. {
  758. Huff2Code += Huff2Code;
  759. if ( CurCode & ReadCodeMask ) Huff2Code++;
  760. ReadCodeMask >>= 1;
  761. Huff2CodeLen++;
  762. if ( ReadCodeMask == 0 )
  763. goto DoneWithCurCode;
  764. PackedCode = Huff2Code - CodePrefixByLen[Huff2CodeLen];
  765. }
  766. if ( Huff2CodeLen > (8 - NumBitsUsed) )
  767. goto DoneWithCurCode;
  768. GotChar = DecodeTable[PackedCode+NumSymbols];
  769. /* step through while Huff2Code is the next code
  770. all occurances of Huff2Code will be contiguous */
  771. do
  772. {
  773. if ( FastDecodeTable[CurCode].NumCharsMade < FD_MAXCHARSMADE )
  774. {
  775. FastDecodeTable[CurCode].CharsMade[FastDecodeTable[CurCode].NumCharsMade] = GotChar;
  776. FastDecodeTable[CurCode].NumCharsMade++;
  777. FastDecodeTable[CurCode].NumBitsUsed = NumBitsUsed + Huff2CodeLen;
  778. }
  779. CurCode ++;
  780. NumBitsUsed = FastDecodeTable[CurCode].NumBitsUsed;
  781. if ( Huff2CodeLen > (8-NumBitsUsed) ) break;
  782. CheckCode = ( CurCode >> (8 - NumBitsUsed - Huff2CodeLen) ) & ( (1<<Huff2CodeLen) - 1 ) ;
  783. } while ( CheckCode == Huff2Code );
  784. NumBitsUsed = FastDecodeTable[StartCode].NumBitsUsed;
  785. }
  786. DoneWithCurCode: /* see Knuth : "Structured use of Goto" :^> */
  787. continue;
  788. }
  789. HI->NumCharsWaiting = 0;
  790. return(1);
  791. }
  792. void Huff2_EncodeC(struct Huff2Info *HI,uint16 Symbol)
  793. {
  794. register uint32 CurCode;
  795. register long CurCodeLen;
  796. register struct LBitIOInfo * BII;
  797. if ( HI->GotNumSymbols < 2 ) return;
  798. CurCode = ((uint32 *)HI->EnDe_codeTable)[Symbol];
  799. CurCodeLen = HI->CodeLenTable[Symbol];
  800. BII = HI->BII;
  801. #ifdef DEBUG
  802. if ( CurCodeLen == 0 )
  803. {
  804. BrandoError("Got EncodeC for CodeLen == 0 symbol!");
  805. exit(10);
  806. }
  807. #endif
  808. LBitIO_WriteBits(BII,CurCode,CurCodeLen);
  809. }
  810. #define FASTDECODE_PAD 6
  811. jeBoolean Huff2_FastDecodeArray(struct Huff2Info *HI,uint8 * Array,long ArrayLen)
  812. {
  813. register uint32 PeekedCode;
  814. register struct FastDecodeItem * FastDecodeTable;
  815. long NumCharsMade;
  816. uint16 * CharsMade;
  817. long NumSymbols;
  818. uint16 * DecodeTable;
  819. uint32 * CodePrefixByLen;
  820. uint32 CurCode,PackedCode;
  821. long CurCodeLen;
  822. jeBoolean bit;
  823. uint8 *CurArrayPtr,*ArrayPtrDone;
  824. LocalLBitIO_Variables();
  825. if ( HI->GotNumSymbols < 2 )
  826. {
  827. if ( HI->GotNumSymbols == 0 ) return(0);
  828. else
  829. {
  830. while(ArrayLen--) *Array++ = HI->OneChar;
  831. }
  832. return(1);
  833. }
  834. LocalLBitIO_GetState(HI->BII);
  835. NumSymbols = HI->NumSymbols;
  836. FastDecodeTable = (struct FastDecodeItem *) ( ((char *)HI->EnDe_codeTable) + 2*NumSymbols*sizeof(uint16) );
  837. DecodeTable = (uint16 *)HI->EnDe_codeTable;
  838. CodePrefixByLen = HI->CodePrefixByLen;
  839. CurArrayPtr = Array;
  840. ArrayPtrDone = Array + ArrayLen - FASTDECODE_PAD;
  841. while ( CurArrayPtr < ArrayPtrDone )
  842. {
  843. LocalLBitIO_PeekBits(PeekedCode,8);
  844. NumCharsMade = FastDecodeTable[PeekedCode].NumCharsMade;
  845. if ( NumCharsMade > 0 )
  846. {
  847. CurCodeLen = FastDecodeTable[PeekedCode].NumBitsUsed;
  848. LocalLBitIO_SkipBits(CurCodeLen);
  849. switch ( NumCharsMade )
  850. {
  851. case 1:
  852. *CurArrayPtr++ = *(FastDecodeTable[PeekedCode].CharsMade);
  853. break;
  854. case 2:
  855. CharsMade = FastDecodeTable[PeekedCode].CharsMade;
  856. *CurArrayPtr++ = *CharsMade++;
  857. *CurArrayPtr++ = *CharsMade;
  858. break;
  859. case 3:
  860. CharsMade = FastDecodeTable[PeekedCode].CharsMade;
  861. *CurArrayPtr++ = *CharsMade++;
  862. *CurArrayPtr++ = *CharsMade++;
  863. *CurArrayPtr++ = *CharsMade;
  864. break;
  865. case 4:
  866. CharsMade = FastDecodeTable[PeekedCode].CharsMade;
  867. *CurArrayPtr++ = *CharsMade++;
  868. *CurArrayPtr++ = *CharsMade++;
  869. *CurArrayPtr++ = *CharsMade++;
  870. *CurArrayPtr++ = *CharsMade;
  871. break;
  872. }
  873. }
  874. else /* use old decode method, can read 9 bits automatically */
  875. {
  876. CurCodeLen = 8;
  877. CurCode = PeekedCode;
  878. LocalLBitIO_SkipBits(8);
  879. PackedCode = CurCode - CodePrefixByLen[CurCodeLen];
  880. /* could read another bit here, but who cares? */
  881. while( DecodeTable[PackedCode] != CurCodeLen )
  882. {
  883. CurCode += CurCode;
  884. LocalLBitIO_ReadBit(bit);
  885. CurCode += bit;
  886. CurCodeLen++;
  887. PackedCode = CurCode - CodePrefixByLen[CurCodeLen];
  888. }
  889. *CurArrayPtr++ = DecodeTable[PackedCode+NumSymbols];
  890. }
  891. }
  892. LocalLBitIO_PutState(HI->BII);
  893. /* do normal decode for last several to make sure we don't go too far */
  894. ArrayPtrDone += FASTDECODE_PAD;
  895. while ( CurArrayPtr < ArrayPtrDone )
  896. {
  897. *CurArrayPtr++ = Huff2_DecodeC(HI);
  898. }
  899. return(1);
  900. }
  901. jeBoolean Huff2_FindDecodeOne(struct Huff2Info *HI)
  902. {
  903. uint16 i;
  904. for(i=0;i<HI->NumSymbols;i++)
  905. {
  906. if ( HI->CodeLenTable[i] > 0 )
  907. {
  908. HI->OneChar = i;
  909. return(1);
  910. }
  911. }
  912. return(0);
  913. }
  914. uint16 Huff2_FastDecodeC(struct Huff2Info *HI)
  915. {
  916. if ( HI->GotNumSymbols < 2 ) return(HI->OneChar);
  917. #if FD_MAXCHARSMADE_SUBONE > 0
  918. if ( HI->NumCharsWaiting > 0 )
  919. {
  920. HI->NumCharsWaiting--;
  921. return(HI->CharsWaiting[HI->NumCharsWaiting]);
  922. }
  923. #endif // FD_MAXCHARSMADE_SUBONE == 0
  924. /* variables not init-ed if there are chars waiting */
  925. {
  926. struct FastDecodeItem * FastDecodeTable;
  927. uint32 PeekedCode;
  928. struct LBitIOInfo * BII;
  929. long NumSymbols;
  930. NumSymbols = HI->NumSymbols;
  931. FastDecodeTable = (struct FastDecodeItem *) ( ((char *)HI->EnDe_codeTable) + 2*NumSymbols*sizeof(uint16) );
  932. BII = HI->BII;
  933. LBitIO_PeekBits(BII,PeekedCode,8);
  934. if ( FastDecodeTable[PeekedCode].NumCharsMade > 0 )
  935. {
  936. LBitIO_SkipBits(BII,FastDecodeTable[PeekedCode].NumBitsUsed);
  937. #if FD_MAXCHARSMADE_SUBONE > 0
  938. HI->NumCharsWaiting = FastDecodeTable[PeekedCode].NumCharsMade - 1;
  939. switch ( HI->NumCharsWaiting ) /* !<>! */
  940. {
  941. case 0:
  942. break;
  943. case 1:
  944. HI->CharsWaiting[0] = FastDecodeTable[PeekedCode].CharsMade[1];
  945. break;
  946. case 2:
  947. HI->CharsWaiting[1] = FastDecodeTable[PeekedCode].CharsMade[1];
  948. HI->CharsWaiting[0] = FastDecodeTable[PeekedCode].CharsMade[2];
  949. break;
  950. case 3:
  951. HI->CharsWaiting[2] = FastDecodeTable[PeekedCode].CharsMade[1];
  952. HI->CharsWaiting[1] = FastDecodeTable[PeekedCode].CharsMade[2];
  953. HI->CharsWaiting[0] = FastDecodeTable[PeekedCode].CharsMade[3];
  954. break;
  955. }
  956. #endif // FD_MAXCHARSMADE_SUBONE == 0
  957. return( FastDecodeTable[PeekedCode].CharsMade[0] );
  958. }
  959. else /* use old decode method, can read 9 bits automatically */
  960. {
  961. uint16 * DecodeTable;
  962. uint32 * CodePrefixByLen;
  963. uint32 CurCode,PackedCode;
  964. long CurCodeLen;
  965. jeBoolean bit;
  966. DecodeTable = (uint16 *)HI->EnDe_codeTable;
  967. CodePrefixByLen = HI->CodePrefixByLen;
  968. CurCodeLen = 8;
  969. CurCode = PeekedCode;
  970. LBitIO_SkipBits(BII,8);
  971. PackedCode = CurCode - CodePrefixByLen[CurCodeLen];
  972. /* could read another bit here, but who cares? */
  973. while( DecodeTable[PackedCode] != CurCodeLen )
  974. {
  975. CurCode += CurCode;
  976. LBitIO_ReadBit(BII,bit);
  977. CurCode += bit;
  978. CurCodeLen++;
  979. PackedCode = CurCode - CodePrefixByLen[CurCodeLen];
  980. }
  981. #ifdef DEBUG
  982. if ( CurCodeLen > HI->MaxCodeLen )
  983. {
  984. BrandoError("Got code longer than MaxCodeLen!");
  985. exit(10);
  986. }
  987. #endif
  988. return(DecodeTable[PackedCode+NumSymbols]);
  989. }
  990. }
  991. /* end variable-space */
  992. }
  993. uint16 Huff2_DecodeC(struct Huff2Info *HI)
  994. {
  995. uint16 * DecodeTable;
  996. long NumSymbols;
  997. uint32 * CodePrefixByLen;
  998. uint32 CurCode,PackedCode;
  999. long CurCodeLen;
  1000. struct LBitIOInfo * BII;
  1001. jeBoolean bit;
  1002. if ( HI->GotNumSymbols < 2 ) return(HI->OneChar);
  1003. NumSymbols = HI->NumSymbols;
  1004. DecodeTable = (uint16 *) HI->EnDe_codeTable;
  1005. CodePrefixByLen = HI->CodePrefixByLen;
  1006. BII = HI->BII;
  1007. CurCodeLen = HI->MinCodeLen;
  1008. LBitIO_ReadBits(BII,CurCode,CurCodeLen);
  1009. PackedCode = CurCode;
  1010. while( DecodeTable[PackedCode] != CurCodeLen )
  1011. {
  1012. CurCode += CurCode;
  1013. LBitIO_ReadBit(BII,bit);
  1014. CurCode += bit;
  1015. CurCodeLen++;
  1016. PackedCode = CurCode - CodePrefixByLen[CurCodeLen];
  1017. }
  1018. #ifdef DEBUG
  1019. if ( CurCodeLen > HI->MaxCodeLen )
  1020. {
  1021. BrandoError("Got code longer than MaxCodeLen!");
  1022. exit(10);
  1023. }
  1024. #endif
  1025. return(DecodeTable[PackedCode+NumSymbols]);
  1026. }
  1027. /*
  1028. * Scale Counts to [0,MaxVal]
  1029. * (brackets indicate the range is "inclusive")
  1030. *
  1031. * a count which was > 0 will not be scaled to 0
  1032. *
  1033. */
  1034. void Huff2_ScaleCounts(struct Huff2Info *HI,long * CharCounts,long MaxVal)
  1035. {
  1036. long MaxCharCount;
  1037. long NumSymbols,i;
  1038. long OutCharCount;
  1039. NumSymbols = HI->NumSymbols;
  1040. //get maxcharcount
  1041. MaxCharCount = 0;
  1042. for(i=0;i<NumSymbols;i++)
  1043. {
  1044. if ( CharCounts[i] > MaxCharCount ) MaxCharCount = CharCounts[i];
  1045. }
  1046. //scale counts
  1047. if ( MaxCharCount > MaxVal )
  1048. {
  1049. for(i=0;i<NumSymbols;i++)
  1050. {
  1051. OutCharCount = ( (long)CharCounts[i] * MaxVal ) / MaxCharCount;
  1052. if ( OutCharCount > MaxVal ) OutCharCount = MaxVal;
  1053. else if ( CharCounts[i] && ! OutCharCount ) OutCharCount = 1;
  1054. CharCounts[i] = OutCharCount;
  1055. }
  1056. }
  1057. if ( HI->MaxCharCount != MaxVal && HI->SortType == HUFF2_SORT_RADIX &&
  1058. HI->SortWork != NULL )
  1059. {
  1060. FreeMem(HI->SortWork,sizeofpointer*(HI->MaxCharCount+1));
  1061. HI->SortWork = NULL;
  1062. }
  1063. HI->MaxCharCount = min(MaxCharCount,MaxVal);
  1064. }
  1065. /*
  1066. * Sets ->MaxCharCount in HI
  1067. *
  1068. */
  1069. void Huff2_GetMaxCharCount(struct Huff2Info *HI,long * CharCounts)
  1070. {
  1071. long MaxCharCount;
  1072. long NumSymbols,i;
  1073. NumSymbols = HI->NumSymbols;
  1074. //get maxcharcount
  1075. MaxCharCount = 0;
  1076. for(i=0;i<NumSymbols;i++)
  1077. {
  1078. if ( CharCounts[i] > MaxCharCount ) MaxCharCount = CharCounts[i];
  1079. }
  1080. if ( HI->MaxCharCount != MaxCharCount && HI->SortType == HUFF2_SORT_RADIX &&
  1081. HI->SortWork != NULL )
  1082. {
  1083. FreeMem(HI->SortWork,sizeofpointer*(HI->MaxCharCount+1));
  1084. HI->SortWork = NULL;
  1085. }
  1086. HI->MaxCharCount = MaxCharCount;
  1087. }
  1088. /*
  1089. * sets MinCodeLen & MaxCodeLen which must be set
  1090. * for BuildEncodeTable
  1091. *
  1092. */
  1093. void Huff2_SetMinMaxCodeLen(struct Huff2Info *HI)
  1094. {
  1095. long MinCodeLen,MaxCodeLen;
  1096. if ( HI->GotNumSymbols < 2 )
  1097. { HI->MinCodeLen = HI->MaxCodeLen = 1; return; }
  1098. MinCodeLen = 1;
  1099. while ( HI->NumCodesOfLen[MinCodeLen] == 0 ) MinCodeLen++;
  1100. MaxCodeLen = 31;
  1101. while ( HI->NumCodesOfLen[MaxCodeLen] == 0 ) MaxCodeLen--;
  1102. HI->MaxCodeLen = MaxCodeLen;
  1103. HI->MinCodeLen = MinCodeLen;
  1104. }
  1105. /*
  1106. * Writes codelens out to the BII
  1107. *
  1108. * also sets MinCodeLen & MaxCodeLen which must be set
  1109. * for BuildEncodeTable
  1110. *
  1111. */
  1112. void Huff2_PackCodeLens(struct Huff2Info *HI)
  1113. {
  1114. long MinCodeLen,MaxCodeLen;
  1115. long i,j,GotNumSymbols;
  1116. uint8 RunData[32];
  1117. long RunLen;
  1118. long CurCodeLen;
  1119. struct LBitIOInfo * BII;
  1120. BII = HI->BII;
  1121. #ifdef PACKCODES_TOPSYM
  1122. GotNumSymbols = HI->NumSymbols;
  1123. while ( HI->CodeLenTable[GotNumSymbols-1] == 0 ) GotNumSymbols--;
  1124. if ( (HI->NumSymbols - GotNumSymbols) < 32 )
  1125. {
  1126. LBitIO_WriteBit(BII,0);
  1127. GotNumSymbols = HI->NumSymbols;
  1128. }
  1129. else
  1130. {
  1131. LBitIO_WriteBit(BII,1);
  1132. CurCodeLen = intlog2(HI->NumSymbols);
  1133. LBitIO_WriteBits(BII,GotNumSymbols,CurCodeLen);
  1134. }
  1135. #else
  1136. GotNumSymbols = HI->NumSymbols;
  1137. #endif // PACKCODES_TOPSYM
  1138. MinCodeLen = 1;
  1139. while ( HI->NumCodesOfLen[MinCodeLen] == 0 ) MinCodeLen++;
  1140. MaxCodeLen = 31;
  1141. while ( HI->NumCodesOfLen[MaxCodeLen] == 0 ) MaxCodeLen--;
  1142. HI->MaxCodeLen = MaxCodeLen;
  1143. HI->MinCodeLen = MinCodeLen;
  1144. if ( MaxCodeLen >= 0xF ) {
  1145. LBitIO_WriteBits(BII,0xF,4);
  1146. LBitIO_WriteBits(BII,MaxCodeLen-0xF,4);
  1147. } else {
  1148. LBitIO_WriteBits(BII,MaxCodeLen,4);
  1149. }
  1150. for(i=0;i<GotNumSymbols;) {
  1151. RunLen = 0;
  1152. while ( HI->CodeLenTable[i] == 0 && RunLen < 32 && i<GotNumSymbols ) {
  1153. RunLen++;
  1154. i++;
  1155. }
  1156. if ( RunLen > 0 ) {
  1157. LBitIO_WriteBit(BII,0);
  1158. LBitIO_WriteBits(BII,(RunLen-1),5);
  1159. }
  1160. RunLen = 0;
  1161. while ( ( HI->CodeLenTable[i] != 0 || HI->CodeLenTable[i+1] != 0 ) && RunLen < 32 && i<GotNumSymbols )
  1162. {
  1163. RunData[RunLen] = HI->CodeLenTable[i];
  1164. RunLen++; i++;
  1165. }
  1166. if ( RunLen > 0 )
  1167. {
  1168. LBitIO_WriteBit(BII,1);
  1169. LBitIO_WriteBits(BII,(RunLen-1),5);
  1170. for(j=0;j<RunLen;j++)
  1171. {
  1172. CurCodeLen = MaxCodeLen - RunData[j];
  1173. while ( CurCodeLen >= 0x7 )
  1174. {
  1175. LBitIO_WriteBits(BII,0x7,3);
  1176. CurCodeLen -= 0x7;
  1177. }
  1178. LBitIO_WriteBits(BII,CurCodeLen,3);
  1179. }
  1180. }
  1181. }
  1182. }
  1183. /*
  1184. * reads packed codelens to CodeLenTable
  1185. *
  1186. * also sets NumCodesOfLen
  1187. *
  1188. */
  1189. void Huff2_UnPackCodeLens(struct Huff2Info *HI)
  1190. {
  1191. long i,j,GotNumSymbols;
  1192. long MinCodeLen,MaxCodeLen,CurCodeLen;
  1193. long RunLen,CurCode;
  1194. struct LBitIOInfo * BII;
  1195. jeBoolean bit;
  1196. HI->GotNumSymbols = 0;
  1197. memclearFast(HI->CodeLenTable,HI->NumSymbols);
  1198. memclearFast(HI->NumCodesOfLen,32);
  1199. HI->MinCodeLen = HI->MaxCodeLen = 0;
  1200. BII = HI->BII;
  1201. #ifdef PACKCODES_TOPSYM
  1202. LBitIO_ReadBit(BII,bit);
  1203. if ( bit )
  1204. {
  1205. CurCodeLen = intlog2(HI->NumSymbols);
  1206. LBitIO_ReadBits(BII,GotNumSymbols,CurCodeLen);
  1207. }
  1208. else
  1209. {
  1210. GotNumSymbols = HI->NumSymbols;
  1211. }
  1212. #else
  1213. GotNumSymbols = HI->NumSymbols;
  1214. #endif // PACKCODES_TOPSYM
  1215. LBitIO_ReadBits(BII,CurCode,4);
  1216. if ( CurCode == 0xF )
  1217. {
  1218. LBitIO_ReadBits(BII,CurCode,4);
  1219. MaxCodeLen = CurCode + 0xF;
  1220. }
  1221. else
  1222. {
  1223. MaxCodeLen = CurCode;
  1224. }
  1225. HI->MaxCodeLen = MaxCodeLen;
  1226. MinCodeLen = MaxCodeLen;
  1227. for(i=0;i<GotNumSymbols; )
  1228. {
  1229. LBitIO_ReadBit(BII,bit);
  1230. LBitIO_ReadBits(BII,RunLen,5);
  1231. RunLen++;
  1232. if ( bit == 0 )
  1233. {
  1234. for(j=0;j<RunLen;j++)
  1235. {
  1236. HI->CodeLenTable[i++] = 0;
  1237. }
  1238. }
  1239. else
  1240. {
  1241. HI->GotNumSymbols += RunLen;
  1242. for(j=0;j<RunLen;j++)
  1243. {
  1244. CurCodeLen = 0;
  1245. LBitIO_ReadBits(BII,CurCode,3);
  1246. while( CurCode == 0x7 )
  1247. {
  1248. CurCodeLen += 0x7;
  1249. LBitIO_ReadBits(BII,CurCode,3);
  1250. }
  1251. CurCodeLen += CurCode;
  1252. CurCodeLen = MaxCodeLen - CurCodeLen;
  1253. HI->CodeLenTable[i++] = CurCodeLen;
  1254. if ( CurCodeLen > 0 ) HI->NumCodesOfLen[CurCodeLen] ++;
  1255. if ( CurCodeLen < MinCodeLen && CurCodeLen > 0 ) MinCodeLen = CurCodeLen;
  1256. }
  1257. }
  1258. }
  1259. HI->MinCodeLen = MinCodeLen;
  1260. }
  1261. /*
  1262. * Writes codelens out to the BII
  1263. *
  1264. * compresses differences for an earlier huff build
  1265. * you must allocate lastcodelens, & set to 0 initially
  1266. *
  1267. * also sets MinCodeLen & MaxCodeLen which must be set
  1268. * for BuildEncodeTable
  1269. *
  1270. */
  1271. void Huff2_PackCodeLens_Delta(struct Huff2Info *HI,long * LastCodeLens)
  1272. {
  1273. long MinCodeLen,MaxCodeLen;
  1274. long i,j,GotNumSymbols;
  1275. uint8 RunData[512],RunDataLast[512];
  1276. long RunLen;
  1277. long CurCodeLen;
  1278. struct LBitIOInfo * BII;
  1279. BII = HI->BII;
  1280. #ifdef PACKCODES_TOPSYM
  1281. GotNumSymbols = HI->NumSymbols;
  1282. while ( HI->CodeLenTable[GotNumSymbols-1] == 0 ) GotNumSymbols--;
  1283. if ( (HI->NumSymbols - GotNumSymbols) < 32 )
  1284. {
  1285. LBitIO_WriteBit(BII,0);
  1286. GotNumSymbols = HI->NumSymbols;
  1287. }
  1288. else
  1289. {
  1290. LBitIO_WriteBit(BII,1);
  1291. CurCodeLen = intlog2(HI->NumSymbols);
  1292. LBitIO_WriteBits(BII,GotNumSymbols,CurCodeLen);
  1293. }
  1294. #else
  1295. GotNumSymbols = HI->NumSymbols;
  1296. #endif // PACKCODES_TOPSYM
  1297. MinCodeLen = 1;
  1298. while ( HI->NumCodesOfLen[MinCodeLen] == 0 ) MinCodeLen++;
  1299. MaxCodeLen = 31;
  1300. while ( HI->NumCodesOfLen[MaxCodeLen] == 0 ) MaxCodeLen--;
  1301. HI->MaxCodeLen = MaxCodeLen;
  1302. HI->MinCodeLen = MinCodeLen;
  1303. if ( MaxCodeLen >= 0xF )
  1304. {
  1305. LBitIO_WriteBits(BII,0xF,4);
  1306. LBitIO_WriteBits(BII,MaxCodeLen-0xF,4);
  1307. }
  1308. else
  1309. {
  1310. LBitIO_WriteBits(BII,MaxCodeLen,4);
  1311. }
  1312. for(i=0;i<GotNumSymbols;)
  1313. {
  1314. RunLen = 0;
  1315. while ( ( HI->CodeLenTable[i] - LastCodeLens[i] ) == 0 && i<GotNumSymbols )
  1316. {
  1317. RunLen++;
  1318. i++;
  1319. }
  1320. if ( RunLen >= 0x03 )
  1321. {
  1322. LBitIO_WriteBits(BII,0x03,2);
  1323. RunLen -= 0x3;
  1324. if ( RunLen >= 0x07 )
  1325. {
  1326. long Thresh,Bits;
  1327. LBitIO_WriteBits(BII,0x07,3);
  1328. RunLen -= 0x7;
  1329. Thresh = 0xF; Bits = 4;
  1330. while ( RunLen >= Thresh )
  1331. {
  1332. LBitIO_WriteBits(BII,Thresh,Bits);
  1333. RunLen -= Thresh;
  1334. Thresh += Thresh + 1; Bits++;
  1335. }
  1336. LBitIO_WriteBits(BII,RunLen,Bits);
  1337. }
  1338. else
  1339. {
  1340. LBitIO_WriteBits(BII,RunLen,3);
  1341. }
  1342. }
  1343. else
  1344. {
  1345. LBitIO_WriteBits(BII,RunLen,2);
  1346. }
  1347. if ( i == GotNumSymbols ) break;
  1348. RunLen = 0;
  1349. while ( ( ( HI->CodeLenTable[i] - LastCodeLens[i] ) != 0 ) && i<GotNumSymbols )
  1350. {
  1351. RunData[RunLen] = HI->CodeLenTable[i];
  1352. RunDataLast[RunLen] = LastCodeLens[i];
  1353. RunLen++; i++;
  1354. if ( RunLen == 512 ) return; /* BAD ! */
  1355. }
  1356. if ( RunLen >= 0x03 )
  1357. {
  1358. j = RunLen;
  1359. LBitIO_WriteBits(BII,0x03,2);
  1360. RunLen -= 0x3;
  1361. if ( RunLen >= 0x07 )
  1362. {
  1363. long Thresh,Bits;
  1364. LBitIO_WriteBits(BII,0x07,3);
  1365. RunLen -= 0x7;
  1366. Thresh = 0xF; Bits = 4;
  1367. while ( RunLen >= Thresh )
  1368. {
  1369. LBitIO_WriteBits(BII,Thresh,Bits);
  1370. RunLen -= Thresh;
  1371. Thresh += Thresh + 1; Bits++;
  1372. }
  1373. LBitIO_WriteBits(BII,RunLen,Bits);
  1374. }
  1375. else
  1376. {
  1377. LBitIO_WriteBits(BII,RunLen,3);
  1378. }
  1379. RunLen = j;
  1380. }
  1381. else
  1382. {
  1383. LBitIO_WriteBits(BII,RunLen,2);
  1384. }
  1385. if ( RunLen > 0 )
  1386. {
  1387. for(j=0;j<RunLen;j++)
  1388. {
  1389. if ( RunDataLast[j] == 0 )
  1390. {
  1391. CurCodeLen = MaxCodeLen - RunData[j];
  1392. while ( CurCodeLen >= 0x7 )
  1393. {
  1394. LBitIO_WriteBits(BII,0x7,3);
  1395. CurCodeLen -= 0x7;
  1396. }
  1397. LBitIO_WriteBits(BII,CurCodeLen,3);
  1398. }
  1399. else
  1400. {
  1401. CurCodeLen = RunData[j] - RunDataLast[j];
  1402. if ( CurCodeLen < 0 )
  1403. {
  1404. LBitIO_WriteBit(BII,0);
  1405. CurCodeLen = - (CurCodeLen + 1);
  1406. }
  1407. else
  1408. {
  1409. LBitIO_WriteBit(BII,1);
  1410. CurCodeLen--;
  1411. }
  1412. while ( CurCodeLen > 0 )
  1413. {
  1414. LBitIO_WriteBit(BII,0);
  1415. CurCodeLen --;
  1416. }
  1417. LBitIO_WriteBit(BII,1);
  1418. }
  1419. }
  1420. }
  1421. }
  1422. for(i=0;i<HI->NumSymbols;i++)
  1423. {
  1424. LastCodeLens[i] = HI->CodeLenTable[i];
  1425. }
  1426. }
  1427. /*
  1428. * reads packed codelens to CodeLenTable
  1429. *
  1430. * also sets NumCodesOfLen
  1431. *
  1432. * <> doesn't decode new style of runlen yet
  1433. *
  1434. */
  1435. void Huff2_UnPackCodeLens_Delta(struct Huff2Info *HI,long * LastCodeLens)
  1436. {
  1437. long i,j,GotNumSymbols;
  1438. long MinCodeLen,MaxCodeLen,CurCodeLen;
  1439. long RunLen,CurCode;
  1440. struct LBitIOInfo * BII;
  1441. jeBoolean bit;
  1442. long sign;
  1443. BII = HI->BII;
  1444. memclear((long *)HI->NumCodesOfLen,32*sizeof(long));
  1445. #ifdef PACKCODES_TOPSYM
  1446. LBitIO_ReadBit(BII,bit);
  1447. if ( bit )
  1448. {
  1449. CurCodeLen = intlog2(HI->NumSymbols);
  1450. LBitIO_ReadBits(BII,GotNumSymbols,CurCodeLen);
  1451. }
  1452. else
  1453. {
  1454. GotNumSymbols = HI->NumSymbols;
  1455. }
  1456. #else
  1457. GotNumSymbols = HI->NumSymbols;
  1458. #endif // PACKCODES_TOPSYM
  1459. LBitIO_ReadBits(BII,CurCode,4);
  1460. if ( CurCode == 0xF )
  1461. {
  1462. LBitIO_ReadBits(BII,CurCode,4);
  1463. MaxCodeLen = CurCode + 0xF;
  1464. }
  1465. else
  1466. {
  1467. MaxCodeLen = CurCode;
  1468. }
  1469. HI->MaxCodeLen = MaxCodeLen;
  1470. MinCodeLen = MaxCodeLen;
  1471. for(i=0;i<GotNumSymbols; )
  1472. {
  1473. LBitIO_ReadBit(BII,bit);
  1474. LBitIO_ReadBits(BII,RunLen,5);
  1475. RunLen++;
  1476. if ( bit == 0 )
  1477. {
  1478. for(j=0;j<RunLen;j++)
  1479. {
  1480. HI->CodeLenTable[i] = LastCodeLens[i]; i++;
  1481. }
  1482. }
  1483. else
  1484. {
  1485. for(j=0;j<RunLen;j++)
  1486. {
  1487. if ( LastCodeLens[i] > 0 )
  1488. {
  1489. LBitIO_ReadBit(BII,bit);
  1490. if ( bit ) sign = -1;
  1491. else sign = 1;
  1492. LBitIO_ReadBit(BII,bit);
  1493. CurCodeLen = 1;
  1494. while( bit == 0 )
  1495. {
  1496. CurCodeLen++;
  1497. LBitIO_ReadBit(BII,bit);
  1498. }
  1499. CurCodeLen = CurCodeLen * sign + LastCodeLens[i];
  1500. }
  1501. else
  1502. {
  1503. CurCodeLen = 0;
  1504. LBitIO_ReadBits(BII,CurCode,3);
  1505. while( CurCode == 0x7 )
  1506. {
  1507. CurCodeLen += 0x7;
  1508. LBitIO_ReadBits(BII,CurCode,3);
  1509. }
  1510. CurCodeLen += CurCode;
  1511. CurCodeLen = MaxCodeLen - CurCodeLen;
  1512. }
  1513. HI->CodeLenTable[i++] = CurCodeLen;
  1514. if ( CurCodeLen > 0 ) HI->NumCodesOfLen[CurCodeLen] ++;
  1515. if ( CurCodeLen < MinCodeLen && CurCodeLen > 0 ) MinCodeLen = CurCodeLen;
  1516. }
  1517. }
  1518. }
  1519. for(i=0;i<HI->NumSymbols;i++)
  1520. {
  1521. LastCodeLens[i] = HI->CodeLenTable[i];
  1522. }
  1523. HI->MinCodeLen = MinCodeLen;
  1524. }
  1525. /*
  1526. * QuickSort on the NodeWork array
  1527. * set Huff2QuickSortArray
  1528. *
  1529. */
  1530. void Huff2QuickSort(long Left,long Right)
  1531. {
  1532. if ( (Right - Left) > 1 )
  1533. {
  1534. long i;
  1535. {
  1536. long j;
  1537. long pivot;
  1538. struct Huff2CodeNode *swapper;
  1539. register struct Huff2CodeNode ** Array;
  1540. Array = Huff2QuickSortArray;
  1541. pivot = Array[Right]->Count;
  1542. i = Left-1;
  1543. j = Right;
  1544. for(;;)
  1545. {
  1546. /* could remove i < Right && j > Left checking by putting
  1547. dummy array slots in [-1] and [GotNumSymbols] w/ Counts 0 and LONG_MAX */
  1548. do ++i; while(Array[i]->Count < pivot && i < Right);
  1549. do --j; while(Array[j]->Count > pivot && j > Left);
  1550. if (i >= j) break;
  1551. swapper = Array[i];
  1552. Array[i] = Array[j];
  1553. Array[j] = swapper;
  1554. }
  1555. swapper = Array[i];
  1556. Array[i] = Array[Right];
  1557. Array[Right] = swapper;
  1558. }
  1559. Huff2QuickSort(Left,i-1);
  1560. Huff2QuickSort(i+1,Right);
  1561. }
  1562. else
  1563. {
  1564. if ( Right > Left )
  1565. {
  1566. if ( Huff2QuickSortArray[Right]->Count < Huff2QuickSortArray[Left]->Count )
  1567. {
  1568. struct Huff2CodeNode *swapper;
  1569. swapper = Huff2QuickSortArray[Left];
  1570. Huff2QuickSortArray[Left] = Huff2QuickSortArray[Right];
  1571. Huff2QuickSortArray[Right] = swapper;
  1572. }
  1573. }
  1574. }
  1575. }
  1576. /*
  1577. * Radix sort on the NodeWork
  1578. * counts must be bounded by [0,MaxCharCount]
  1579. * this is much faster than QuickSort for large NumSymbols
  1580. *
  1581. * I think NumSymbols as small as 256 is still faster here
  1582. * Radix = O(256 + 2*NumSymbols)
  1583. * QuickSort = O(NumSymbols*log2(NumSymbols))
  1584. * bigOs are equal for NumSymbols == 64
  1585. *
  1586. * NOTEZ: uses the ->Up in the codenode structure
  1587. * resets ->Up to NULL when its done
  1588. *
  1589. */
  1590. jeBoolean Huff2RadixSort(struct Huff2CodeNode ** BucketArray,
  1591. long MaxCharCount,struct Huff2CodeNode ** Array,long ArraySize)
  1592. {
  1593. register struct Huff2CodeNode * CurNode;
  1594. register long i,j;
  1595. memclear((long *)BucketArray,sizeofpointer*(MaxCharCount+1));
  1596. /* go backwards so that alphabetic order is preserved */
  1597. for(i=(ArraySize-1);i>=0;i--)
  1598. {
  1599. Array[i]->Up = BucketArray[Array[i]->Count];
  1600. BucketArray[Array[i]->Count] = Array[i];
  1601. }
  1602. j=0;
  1603. for(i=0;i<=MaxCharCount;i++)
  1604. {
  1605. CurNode = BucketArray[i];
  1606. while(CurNode) /* $ 15% */
  1607. {
  1608. Array[j] = CurNode;
  1609. CurNode = CurNode->Up;
  1610. Array[j]->Up = NULL;
  1611. j++;
  1612. }
  1613. }
  1614. if ( j != ArraySize )
  1615. {
  1616. return(0);
  1617. }
  1618. return(1);
  1619. }