PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/jet3d_dev_msvc2003/source/Engine/JetEngine/Bitmap/Compression/huffman2.c

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