/branches/JSTUDIO_VERSION_2_X/source/Engine/JetEngine/Bitmap/Compression/huffa.c

# · C · 766 lines · 587 code · 151 blank · 28 comment · 185 complexity · e3acf24fcac458dceb488245d306e21b MD5 · raw file

  1. /****************************************************************************************/
  2. /* HUFFA.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. /* #define DEBUG */
  22. #include "Utility.h"
  23. #include "StrUtil.h"
  24. #include "lbitio.h"
  25. #include "huffman2.h"
  26. #include "CodeUtil.h"
  27. #include "runtrans.h"
  28. #pragma warning(disable : 4244 4018)
  29. #include "huffa.h" /* for type defines */
  30. /*** protos **/
  31. #define CleanUp(exitmess) { HuffExitMess = exitmess; goto EndOfFunc; }
  32. long MaxIn(long *Array,long Len); /* find max utility */
  33. jeBoolean HuffArray(uint8 *RawArray,uint32 RawLen,
  34. uint8 *HuffArray,uint32 * HuffArrayLenPtr,int Type);
  35. jeBoolean O0HuffArray(uint8 *RawArray,uint32 RawLen,
  36. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag);
  37. jeBoolean O0HuffArrayNoBlock(uint8 *RawArray,uint32 RawLen,
  38. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag);
  39. jeBoolean O0HuffArrayBII_RT(uint8 *rawArray,uint32 rawLen,struct LBitIOInfo * BII,jeBoolean cFlag);
  40. jeBoolean O0HuffArrayBII(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag);
  41. jeBoolean O0HuffArrayBII_block(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag);
  42. jeBoolean O0HuffArrayBII_noblock(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag);
  43. jeBoolean O1HuffArray(uint8 *RawArray,uint32 RawLen,
  44. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag);
  45. /*********************** choose order 0 or 1 or raw ***********/
  46. jeBoolean HuffArray(uint8 *RawArray,uint32 RawLen,
  47. uint8 *HuffArray,uint32 * HuffArrayLenPtr,int Type)
  48. {
  49. char * HuffExitMess = 0;
  50. if ( RawLen == 0 ) return JE_TRUE;
  51. if ( Type == HUFFA_TYPE_BEST )
  52. {
  53. uint8 *TypePtr;
  54. uint32 BestLen,CurLen;
  55. TypePtr = HuffArray++;
  56. Type = HUFFA_TYPE_NONE;
  57. BestLen = RawLen;
  58. if ( ! O0HuffArray(RawArray,RawLen,HuffArray,&CurLen,JE_TRUE) ) return(0);
  59. if ( CurLen < BestLen ) { BestLen = CurLen; Type = HUFFA_TYPE_O0; }
  60. if ( ! O0HuffArrayNoBlock(RawArray,RawLen,HuffArray,&CurLen,JE_TRUE) ) return(0);
  61. if ( CurLen < BestLen ) { BestLen = CurLen; Type = HUFFA_TYPE_O0NB; }
  62. if ( ! O1HuffArray(RawArray,RawLen,HuffArray,&CurLen,JE_TRUE) ) return(0);
  63. if ( CurLen < BestLen ) { BestLen = CurLen; Type = HUFFA_TYPE_O1; }
  64. if ( Type == HUFFA_TYPE_O1 ) { } /* done */
  65. else if ( Type == HUFFA_TYPE_O0 )
  66. {
  67. if ( ! O0HuffArray(RawArray,RawLen,HuffArray,&CurLen,1) ) return(0);
  68. }
  69. else if ( Type == HUFFA_TYPE_NONE )
  70. {
  71. memcpy(HuffArray,RawArray,RawLen);
  72. CurLen = RawLen;
  73. }
  74. *TypePtr = Type;
  75. *HuffArrayLenPtr = CurLen+1;
  76. }
  77. else
  78. {
  79. jeBoolean success=JE_FALSE,CompressFlag;
  80. if ( Type == HUFFA_TYPE_DEC )
  81. CompressFlag = JE_FALSE;
  82. else
  83. CompressFlag = JE_TRUE;
  84. if ( CompressFlag )
  85. *HuffArray++ = Type;
  86. else
  87. Type = *HuffArray++;
  88. switch(Type)
  89. {
  90. case HUFFA_TYPE_O1:
  91. success = O1HuffArray(RawArray,RawLen,HuffArray,HuffArrayLenPtr,CompressFlag);
  92. break;
  93. case HUFFA_TYPE_O0:
  94. success = O0HuffArray(RawArray,RawLen,HuffArray,HuffArrayLenPtr,CompressFlag);
  95. break;
  96. case HUFFA_TYPE_O0NB:
  97. success = O0HuffArrayNoBlock(RawArray,RawLen,HuffArray,HuffArrayLenPtr,CompressFlag);
  98. break;
  99. case HUFFA_TYPE_NONE:
  100. if ( CompressFlag )
  101. memcpy(HuffArray,RawArray,RawLen);
  102. else
  103. memcpy(RawArray,HuffArray,RawLen);
  104. *HuffArrayLenPtr = RawLen;
  105. success = JE_TRUE;
  106. break;
  107. default:
  108. CleanUp("Got invalid type flag");
  109. break;
  110. }
  111. *HuffArrayLenPtr += 1;
  112. return(success);
  113. }
  114. EndOfFunc:
  115. if ( HuffExitMess )
  116. {
  117. BrandoError(HuffExitMess);
  118. return(JE_FALSE);
  119. }
  120. else
  121. {
  122. return(JE_TRUE);
  123. }
  124. }
  125. /************** Order 0 ******************/
  126. #define HUFF_MINLEN 8
  127. jeBoolean O0HuffArray(uint8 *RawArray,uint32 RawLen,
  128. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag)
  129. {
  130. struct LBitIOInfo * BII;
  131. jeBoolean ret;
  132. if ( RawLen == 0 ) return JE_TRUE;
  133. if ( (BII = LBitIO_Init(HuffArray)) == NULL )
  134. { BrandoError("LBitIO_Init failed!"); return(0); }
  135. if ( ! CompressFlag )
  136. {
  137. LBitIO_InitRead(BII);
  138. ret = O0HuffArrayBII(RawArray,RawLen,BII,CompressFlag);
  139. *HuffArrayLenPtr = LBitIO_GetPosD(BII);
  140. }
  141. else
  142. {
  143. ret = O0HuffArrayBII(RawArray,RawLen,BII,CompressFlag);
  144. *HuffArrayLenPtr = LBitIO_FlushWrite(BII);
  145. }
  146. LBitIO_CleanUp(BII);
  147. return(ret);
  148. }
  149. jeBoolean O0HuffArrayNoBlock(uint8 *RawArray,uint32 RawLen,
  150. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag)
  151. {
  152. struct LBitIOInfo * BII;
  153. jeBoolean ret;
  154. if ( RawLen == 0 ) return JE_TRUE;
  155. if ( (BII = LBitIO_Init(HuffArray)) == NULL )
  156. { BrandoError("LBitIO_Init failed!"); return(0); }
  157. if ( ! CompressFlag )
  158. {
  159. LBitIO_InitRead(BII);
  160. ret = O0HuffArrayBII_noblock(RawArray,RawLen,BII,CompressFlag);
  161. *HuffArrayLenPtr = LBitIO_GetPosD(BII);
  162. }
  163. else
  164. {
  165. ret = O0HuffArrayBII_noblock(RawArray,RawLen,BII,CompressFlag);
  166. *HuffArrayLenPtr = LBitIO_FlushWrite(BII);
  167. }
  168. LBitIO_CleanUp(BII);
  169. return(ret);
  170. }
  171. /** kind of a cheezy way to do the _RT **/
  172. jeBoolean O0HuffArrayBII_RT(uint8 *rawArray,uint32 rawLen,struct LBitIOInfo * BII,jeBoolean cFlag)
  173. {
  174. uint8 *runArray;
  175. uint32 runLen;
  176. jeBoolean ret;
  177. if ( (runArray = (uint8*)jeRam_Allocate(rawLen + (rawLen>>3) + 1024)) == NULL )
  178. return JE_FALSE;
  179. if ( cFlag ) {
  180. runLen = doRunTransform(rawArray,rawLen,runArray);
  181. if ( runLen < rawLen ) {
  182. LBitIO_WriteBit(BII,1);
  183. cu_putExpanding_bii(runLen,BII,14,4);
  184. ret = O0HuffArrayBII(runArray,runLen,BII,cFlag);
  185. } else {
  186. LBitIO_WriteBit(BII,0);
  187. ret = O0HuffArrayBII(rawArray,rawLen,BII,cFlag);
  188. }
  189. } else {
  190. jeBoolean doRT;
  191. LBitIO_ReadBit(BII,doRT);
  192. if ( doRT ) {
  193. runLen = cu_getExpanding_bii(BII,14,4);
  194. ret = O0HuffArrayBII(runArray,runLen,BII,cFlag);
  195. unRunTransform(rawArray,rawLen,runArray);
  196. } else {
  197. ret = O0HuffArrayBII(rawArray,rawLen,BII,cFlag);
  198. }
  199. }
  200. destroy(runArray);
  201. return ret;
  202. }
  203. #define DOBLOCK_MINLEN 1024
  204. #define DOBLOCK_DIVISOR 4
  205. jeBoolean O0HuffArrayBII(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag)
  206. {
  207. if ( RawLen == 0 ) return JE_TRUE;
  208. if ( RawLen < DOBLOCK_MINLEN )
  209. {
  210. return( O0HuffArrayBII_noblock(RawArray,RawLen,BII,CompressFlag) );
  211. }
  212. else
  213. {
  214. jeBoolean doblock=0;
  215. if ( CompressFlag )
  216. {
  217. long MaxCount,i;
  218. long * CharCounts = NULL;
  219. if ( (CharCounts = (long *)jeRam_Allocate(256*sizeof(long))) == NULL )
  220. { BrandoError("jeRam_Allocate failed!"); return(0); }
  221. memclear(CharCounts,256*sizeof(long));
  222. for(i=0;i<RawLen;i++) CharCounts[RawArray[i]] ++;
  223. MaxCount = CharCounts[MaxIn(CharCounts,256)];
  224. destroy(CharCounts);
  225. if ( (MaxCount*DOBLOCK_DIVISOR) >= RawLen ) doblock = 1;
  226. else doblock = 0;
  227. }
  228. if ( CompressFlag ) { LBitIO_WriteBit(BII,doblock); }
  229. else { LBitIO_ReadBit(BII,doblock); }
  230. if ( doblock ) return( O0HuffArrayBII_block(RawArray,RawLen,BII,CompressFlag) );
  231. else return( O0HuffArrayBII_noblock(RawArray,RawLen,BII,CompressFlag) );
  232. }
  233. return(0);
  234. }
  235. /** this is the core routine of it all, the only one that
  236. actually does huffman: **/
  237. jeBoolean O0HuffArrayBII_noblock(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag)
  238. {
  239. struct Huff2Info * HI = NULL;
  240. long * CharCounts = NULL;
  241. char * HuffExitMess = NULL;
  242. if ( RawLen == 0 ) return JE_TRUE;
  243. #ifdef DEBUG
  244. if ( CompressFlag )
  245. {
  246. LBitIO_WriteBits(BII,0xD,5);
  247. }
  248. else
  249. {
  250. int test;
  251. LBitIO_ReadBits(BII,test,5);
  252. if ( test != 0xD ) { BrandoError("o0noblock:init:didn't get tag"); return(0); }
  253. }
  254. #endif
  255. if ( RawLen < HUFF_MINLEN )
  256. {
  257. if ( CompressFlag )
  258. {
  259. while(RawLen--)
  260. {
  261. LBitIO_WriteBits(BII,*RawArray,8); RawArray++;
  262. }
  263. }
  264. else
  265. {
  266. while(RawLen--)
  267. {
  268. LBitIO_ReadBits(BII,*RawArray,8); RawArray++;
  269. }
  270. }
  271. return(1);
  272. }
  273. if ( (HI = Huff2_Init(256,BII,HUFF2_SORT_RADIX)) == NULL )
  274. CleanUp("Huff2_Init failed!");
  275. if ( ! CompressFlag )
  276. {
  277. Huff2_UnPackCodeLens(HI);
  278. Huff2_BuildFastDecodeTable(HI);
  279. Huff2_FastDecodeArray(HI,RawArray,RawLen);
  280. }
  281. else //Encode
  282. {
  283. long i;
  284. if ( (CharCounts = (long *)jeRam_Allocate(256*sizeof(long))) == NULL )
  285. CleanUp("jeRam_Allocate failed!");
  286. memclear(CharCounts,256*sizeof(long));
  287. for(i=0;i<RawLen;i++) CharCounts[RawArray[i]] ++;
  288. Huff2_ScaleCounts(HI,CharCounts,256);
  289. Huff2_BuildCodeLens(HI,CharCounts);
  290. Huff2_PackCodeLens(HI);
  291. Huff2_BuildEncodeTable(HI);
  292. Huff2_EncodeC_Macro_Init(HI);
  293. for(i=0;i<RawLen;i++)
  294. {
  295. Huff2_EncodeC_Macro(HI,RawArray[i]);
  296. }
  297. Huff2_EncodeC_Macro_Done(HI);
  298. }
  299. CleanUp(NULL);
  300. EndOfFunc:
  301. #ifdef DEBUG
  302. if ( CompressFlag )
  303. {
  304. LBitIO_WriteBits(BII,0xD,5);
  305. }
  306. else
  307. {
  308. int test;
  309. LBitIO_ReadBits(BII,test,5);
  310. if ( test != 0xD ) { BrandoError("O0noblock:EOF:didn't get tag"); }
  311. }
  312. #endif
  313. destroy(CharCounts);
  314. if ( HI ) Huff2_CleanUp(HI);
  315. if ( HuffExitMess )
  316. {
  317. BrandoError(HuffExitMess);
  318. return(JE_FALSE);
  319. }
  320. else
  321. {
  322. return(JE_TRUE);
  323. }
  324. }
  325. jeBoolean O0HuffArrayBII_block(uint8 *RawArray,uint32 RawLen,struct LBitIOInfo * BII,jeBoolean CompressFlag)
  326. {
  327. long * CharCounts = NULL;
  328. char * HuffExitMess = NULL;
  329. uint8 * BlockArray = NULL;
  330. uint8 * LitArray = NULL;
  331. uint32 BlockLen,NumLits;
  332. uint8 MPS0,MPS1,MPS2;
  333. if ( RawLen == 0 ) return JE_TRUE;
  334. BlockLen = ((RawLen-1)/4) + 1;
  335. if ( (BlockArray = (uint8*)jeRam_Allocate(BlockLen)) == NULL )
  336. CleanUp("block jeRam_Allocate failed");
  337. if ( ! CompressFlag )
  338. {
  339. long bi,v,ri,li,shift;
  340. LBitIO_ReadBits(BII,MPS0,8);
  341. LBitIO_ReadBits(BII,MPS1,8);
  342. LBitIO_ReadBits(BII,MPS2,8);
  343. if ( ! O0HuffArrayBII_noblock(BlockArray,BlockLen,BII,0) )
  344. CleanUp("o0_noblock failed");
  345. NumLits=0;
  346. for(bi=0;bi<BlockLen;bi++)
  347. {
  348. v=0x3;
  349. for(li=4;li--;)
  350. {
  351. if ( ( BlockArray[bi] & v ) == v ) NumLits++;
  352. v <<= 2;
  353. }
  354. }
  355. if ( NumLits > 0 )
  356. {
  357. if ( (LitArray = (uint8*)jeRam_Allocate(NumLits)) == NULL )
  358. CleanUp("lits jeRam_Allocate failed");
  359. if (! O0HuffArrayBII_noblock(LitArray,NumLits,BII,0) )
  360. CleanUp("o0_noblock failed");
  361. }
  362. ri = li= 0;
  363. for(bi=0;bi<BlockLen;bi++)
  364. {
  365. v = BlockArray[bi];
  366. for(shift=6;shift>=0;shift-=2)
  367. {
  368. switch( ((v>>shift)&0x3) )
  369. {
  370. case 0: RawArray[ri++] = MPS0; break;
  371. case 1: RawArray[ri++] = MPS1; break;
  372. case 2: RawArray[ri++] = MPS2; break;
  373. case 3: RawArray[ri++] = LitArray[li++]; break;
  374. }
  375. if ( ri == RawLen )
  376. {
  377. if ( bi != (BlockLen-1) ) CleanUp("HuffBlock:didn't read enough blocks!");
  378. CleanUp(NULL);
  379. }
  380. }
  381. if ( li > NumLits ) CleanUp("HuffBlock:Read too many literals!");
  382. }
  383. if ( ri != RawLen ) CleanUp("HuffBlock:Didn't write enough!");
  384. }
  385. else //Encode
  386. {
  387. long bi,bcnt,v,li,ri,c;
  388. if ( (LitArray = (uint8*)jeRam_Allocate(RawLen)) == NULL )
  389. CleanUp("jeRam_Allocate failed");
  390. if ( (CharCounts = (long *)jeRam_AllocateClear(256*sizeof(long))) == NULL )
  391. CleanUp("jeRam_Allocate failed!");
  392. for(ri=0;ri<RawLen;ri++) CharCounts[RawArray[ri]] ++;
  393. MPS0 = MaxIn(CharCounts,256); CharCounts[MPS0] = 0;
  394. MPS1 = MaxIn(CharCounts,256); CharCounts[MPS1] = 0;
  395. MPS2 = MaxIn(CharCounts,256); CharCounts[MPS2] = 0;
  396. LBitIO_WriteBits(BII,MPS0,8);
  397. LBitIO_WriteBits(BII,MPS1,8);
  398. LBitIO_WriteBits(BII,MPS2,8);
  399. ri = li= 0;
  400. for(bi=0;bi<BlockLen;bi++)
  401. {
  402. v = 0;
  403. for(bcnt=4;bcnt--;)
  404. {
  405. v <<= 2;
  406. if ( ri >= RawLen ) c = MPS0;
  407. else c = RawArray[ri++];
  408. if ( c == MPS0 ) v += 0;
  409. else if (c == MPS1 ) v += 1;
  410. else if ( c == MPS2 ) v += 2;
  411. else { v += 3; LitArray[li++] = c; }
  412. }
  413. BlockArray[bi] = v;
  414. }
  415. NumLits = li;
  416. if ( ! O0HuffArrayBII_noblock(BlockArray,BlockLen,BII,1) )
  417. CleanUp("o0_noblock failed");
  418. if ( ! O0HuffArrayBII_noblock(LitArray,NumLits,BII,1) )
  419. CleanUp("o0_noblock failed");
  420. }
  421. CleanUp(NULL);
  422. EndOfFunc:
  423. destroy(LitArray);
  424. destroy(BlockArray);
  425. destroy(CharCounts);
  426. if ( HuffExitMess )
  427. {
  428. BrandoError(HuffExitMess);
  429. return(JE_FALSE);
  430. }
  431. else
  432. {
  433. return(JE_TRUE);
  434. }
  435. }
  436. /**************** Order 1 ********************/
  437. #define MERJE_LEN 64
  438. #define BASEC ' '
  439. void o1len_write(struct LBitIOInfo * BII,uint32 len)
  440. {
  441. if ( len == 0 )
  442. {
  443. LBitIO_WriteBit(BII,0);
  444. }
  445. else
  446. {
  447. uint32 nbits,mask;
  448. LBitIO_WriteBit(BII,1);
  449. len--;
  450. nbits = 4;
  451. mask = (1<<nbits)-1;
  452. while( len >= mask )
  453. {
  454. LBitIO_WriteBits(BII,mask,nbits);
  455. len -= mask;
  456. nbits += 4;
  457. if ( nbits >= 32 ) mask = 0xFFFFFFFF;
  458. else mask = (1<<nbits)-1;
  459. }
  460. LBitIO_WriteBits(BII,len,nbits);
  461. }
  462. return;
  463. }
  464. uint32 o1len_read(struct LBitIOInfo *BII)
  465. {
  466. uint32 readval;
  467. uint32 len;
  468. LBitIO_ReadBit(BII,readval);
  469. if ( readval == 0 )
  470. {
  471. return(0);
  472. }
  473. else
  474. {
  475. uint32 nbits,mask;
  476. len = 1;
  477. nbits = 4;
  478. do
  479. {
  480. if ( nbits >= 32 ) mask = 0xFFFFFFFF;
  481. else mask = (1<<nbits)-1;
  482. LBitIO_ReadBits(BII,readval,nbits);
  483. len += readval;
  484. nbits += 4;
  485. } while(readval == mask);
  486. return(len);
  487. }
  488. }
  489. jeBoolean O1HuffArray(uint8 *RawArray,uint32 RawLen,
  490. uint8 *HuffArray,uint32 * HuffArrayLenPtr,jeBoolean CompressFlag)
  491. {
  492. struct LBitIOInfo * BII = NULL;
  493. char * HuffExitMess = NULL;
  494. uint8 ** o1Arrays = NULL;
  495. uint8 ** o1ArrayPtrs = NULL;
  496. uint32 * o1ArrayLens = NULL;
  497. int lc;
  498. uint32 len;
  499. uint8 *mergePtr;
  500. if ( RawLen == 0 ) return JE_TRUE;
  501. if ( (BII = LBitIO_Init(HuffArray)) == NULL )
  502. CleanUp("LBitIO_Init failed!");
  503. if ( (o1Arrays = (uint8**)jeRam_Allocate(257*sizeofpointer)) == NULL )
  504. CleanUp("jeRam_Allocate failed!");
  505. for(lc=0;lc<257;lc++) o1Arrays[lc] = NULL;
  506. if ( (o1ArrayPtrs = (uint8**)jeRam_Allocate(257*sizeofpointer)) == NULL )
  507. CleanUp("jeRam_Allocate failed!");
  508. if ( (o1ArrayLens = (uint32*)jeRam_Allocate(257*sizeof(uint32))) == NULL )
  509. CleanUp("jeRam_Allocate failed!");
  510. for(lc=0;lc<257;lc++) o1ArrayLens[lc] = 0;
  511. if ( ! CompressFlag )
  512. {
  513. uint32 totlen=0;
  514. LBitIO_InitRead(BII);
  515. for(lc=0;lc<257;lc++)
  516. {
  517. o1ArrayLens[lc] = len = o1len_read(BII);
  518. if ( len > 0 )
  519. {
  520. if ( lc != 256 ) totlen += len;
  521. if ( (o1Arrays[lc] = (uint8*)jeRam_Allocate(len)) == NULL )
  522. CleanUp("jeRam_Allocate failed!");
  523. o1ArrayPtrs[lc] = o1Arrays[lc];
  524. if ( len >= MERJE_LEN || lc == 256 )
  525. {
  526. if ( ! O0HuffArrayBII(o1Arrays[lc],len,BII,0) )
  527. CleanUp("O0HuffArrayBII failed");
  528. }
  529. }
  530. }
  531. if ( totlen != RawLen )
  532. CleanUp("total o1 lens != RawLen");
  533. totlen = o1ArrayLens[256];
  534. mergePtr = o1Arrays[256];
  535. for(lc=0;lc<256;lc++)
  536. {
  537. if ( o1ArrayLens[lc] < MERJE_LEN )
  538. {
  539. uint8 * aPtr;
  540. len = o1ArrayLens[lc];
  541. totlen -= len;
  542. aPtr = o1Arrays[lc];
  543. while(len--) *aPtr++ = *mergePtr++;
  544. }
  545. }
  546. if ( totlen != 0 )
  547. CleanUp("sum of merged arrays lens != MergeArrayLen");
  548. lc=BASEC;
  549. while(RawLen--) lc = *RawArray++ = *o1ArrayPtrs[lc]++;
  550. *HuffArrayLenPtr = LBitIO_GetPosD(BII);
  551. }
  552. else //Encode
  553. {
  554. uint32 i;
  555. uint8 * CurArray;
  556. lc=BASEC;
  557. for(i=0;i<RawLen;i++) { o1ArrayLens[lc]++; lc = RawArray[i]; }
  558. o1ArrayLens[256] = RawLen;
  559. for(lc=0;lc<257;lc++)
  560. {
  561. if ( o1ArrayLens[lc] > 0 )
  562. {
  563. if ( (o1Arrays[lc] = (uint8*)jeRam_Allocate(o1ArrayLens[lc])) == NULL )
  564. CleanUp("jeRam_Allocate failed!");
  565. }
  566. o1ArrayPtrs[lc] = o1Arrays[lc];
  567. }
  568. o1ArrayLens[256] = 0;
  569. lc=BASEC;
  570. for(i=0;i<RawLen;i++) lc = *o1ArrayPtrs[lc]++ = RawArray[i];
  571. mergePtr = o1Arrays[256];
  572. for(lc=0;lc<257;lc++)
  573. {
  574. len = o1ArrayLens[lc];
  575. o1len_write(BII,len);
  576. if ( len >= MERJE_LEN || lc == 256 )
  577. {
  578. if ( ! O0HuffArrayBII(o1Arrays[lc],len,BII,1) )
  579. CleanUp("O0HuffArrayBII failed");
  580. }
  581. else
  582. {
  583. o1ArrayLens[256] += len;
  584. CurArray = o1Arrays[lc];
  585. while(len--) *mergePtr++ = *CurArray++;
  586. }
  587. }
  588. *HuffArrayLenPtr = LBitIO_FlushWrite(BII);
  589. }
  590. CleanUp(NULL);
  591. EndOfFunc:
  592. destroy(o1ArrayLens);
  593. destroy(o1ArrayPtrs);
  594. if ( o1Arrays )
  595. {
  596. for(lc=0;lc<257;lc++) destroy( o1Arrays[lc] );
  597. destroy(o1Arrays);
  598. }
  599. if ( BII ) LBitIO_CleanUp(BII);
  600. if ( HuffExitMess )
  601. {
  602. BrandoError(HuffExitMess);
  603. return(JE_FALSE);
  604. }
  605. else
  606. {
  607. return(JE_TRUE);
  608. }
  609. }
  610. long MaxIn(long *Array,long Len)
  611. {
  612. long Max = -1,Found = 0,i;
  613. for(i=0;i<Len;i++) { if ( Array[i] > Max ) { Max = Array[i]; Found = i; } }
  614. return(Found);
  615. }