Advertisement
mmmmkkkkzzzz

Untitled

May 27th, 2025
1,308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 43.54 KB | None | 0 0
  1. ///// PUT THESE IN A .H FILE!!!!
  2. typedef struct bString{unsigned size,capacity;unsigned char* data;}bString;
  3. #define zFAST_BITS 8 /* 0...15 */
  4. #define zCOMPRESSION_IN_A_HURRY 1
  5. bString bZibUncompress(bString compressed,bString *dictionary);
  6. int bZibUncompressFile(char *fileCompressed,char *fileUncompressed);
  7. bString bZibCompress(bString uncompressed,bString *dictionary);
  8. void bZibCompressFile(char *fileUncompressed,char *fileCompressed);
  9. //////THATS ALL!!! EASY, ISNT IT? NOW SKIP TO LINE 270 !!!!!
  10. #ifdef __POCC__
  11. #define bPELLES 1
  12. #elif defined(__clang__)
  13. #define bCLANG 1
  14. #elif defined(_MSC_VER)
  15. #define bMSVC 1
  16. #elif defined(__MINGW32__)
  17. #define bMINGW 1
  18. #elif defined(__GNUC__)
  19. #define bGCC 1
  20. #endif //PELLES||CLANG||MSVC||MINGW
  21. #if bPELLES+bCLANG+bMSVC+bMINGW+bGCC!=1
  22. #error error error error error error
  23. #endif
  24. #if defined(__ANDROID__)
  25. #define bANDROID 1
  26. #elif defined(_WIN32)
  27. #define bWINDOWS 1
  28. #elif defined(__APPLE__)
  29. #define bAPPLE 1
  30. #elif defined(__linux__)
  31. #define bLINUX 1
  32. #endif //ANDROID||WINDOWS||OSX||LINUX
  33. #if bANDROID+bWINDOWS+bAPPLE+bLINUX!=1
  34. #error error error %$#@$#@%#@#
  35. #endif
  36. #include <limits.h>
  37. #include <stdarg.h>
  38. #include <stdint.h>
  39. #include <string.h>
  40. #include <math.h>
  41. #ifdef bWINDOWS
  42. #define UNICODE
  43. #define OEMRESOURCE
  44. #include <winsock2.h>
  45. #include <windows.h>
  46. #else //bWINDOWS||!bWINDOWS
  47. #define _FILE_OFFSET_BITS 64
  48. #include <dirent.h>
  49. #include <errno.h>
  50. #include <fcntl.h>
  51. #include <signal.h>
  52. #include <sys/stat.h>
  53. #include <sys/types.h>
  54. #include <time.h>
  55. #include <utime.h>
  56. #include <stdio.h>
  57. #include <unistd.h>
  58. #endif //bWINDOWS||!bWINDOWS
  59. #ifdef bLINUX
  60. #include <langinfo.h>
  61. #endif
  62. #if !defined bPELLES && !defined bMSVC
  63. typedef uint32_t bUnaligned32 __attribute__((aligned(1),may_alias));
  64. #else
  65. typedef __unaligned uint32_t bUnaligned32;
  66. #endif
  67. #define ARRAY_EXTRA 3
  68. #define bMin(a,b) (((a)<(b))?(a):(b))
  69. #define bGrow(from) ((unsigned)(((from)*1.2)+(3<<2>>1)))
  70. #define break(x) {x;break;}
  71. #define bMax(a,b) (((a)>(b))?(a):(b))
  72. #define bSwap32(v) ((uint32_t)(((v)>>24)|((uint32_t)((v))<<24)|(((v)&16711680)>>8)|(((v)&65280)<<8)))
  73. #define bCollate(l,r) ((l)<(r)?-1:(l)>(r)?1:0)
  74. #define bAddU32Ovflo(a,b) ((a)>UINT32_MAX-(b))
  75. #define bAssert(...)
  76. #define bAssertMsg(...)
  77. #define bLog(...)
  78. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. #define bIndexLeft(i) ((unsigned)((2*(i))+1))
  80. #define bIndexRight(i) ((unsigned)((2*(i))+2))
  81. #define bIndexParent(i) ((unsigned)(((i)-1)/2))
  82. #define bIndexValid(pos,level) (((unsigned)(pos))<(unsigned)((1<<(level))-1))
  83. #define bIndexLevelStart(level) ((unsigned)((1<<((level)-1))-1))
  84. #define bIndexLevelEnd(level) (bIndexLevelStart((level)+1)-1)
  85. #define bIndexParentIsRight(i) ((i)&1)
  86. #define bIndexParentIsLeft(i) (((i)+1)&1)
  87. #define bDECLARE_INDEX(name,type)\
  88.  typedef struct name{type *data;unsigned char *stat,levels;unsigned items;}name;\
  89.  void name##Add(name *index,type item);\
  90.  unsigned name##Next(name index,unsigned pos);\
  91.  unsigned name##Prev(name index,unsigned pos);\
  92.  unsigned name##Min(name index);\
  93.  unsigned name##Max(name index);\
  94.  unsigned name##FindIndex(name index,type item,int lowerbound);\
  95.  int name##Delete(name *index,unsigned pos,int hideOnly);\
  96.  void name##Free(name *idx);\
  97.  void name##Reindex(name *idx);
  98. #define bDEFINE_INDEX(name,type,collator,freefunc)\
  99.  void name##Move2(name *index,unsigned from,unsigned to,unsigned count){\
  100.   memcpy(index->data+to,index->data+from,count*sizeof(type));\
  101.   memcpy(index->stat+to,index->stat+from,count*sizeof(unsigned char));\
  102.   memset(index->data+from,0,count*sizeof(type));\
  103.   memset(index->stat+from,0,count*sizeof(unsigned char));\
  104.  }\
  105.  void name##Move(name *index,unsigned from,unsigned to,int baum){\
  106.   if(!bIndexValid(from,index->levels)||!bIndexValid(to,index->levels))return;\
  107.   unsigned count=1;\
  108.   if(!baum){(name##Move2(index,from,to,count));return;}\
  109.   if(to>from){\
  110.    while(bIndexValid(bIndexLeft(to),index->levels))count*=2,from=bIndexLeft(from),to=bIndexLeft(to);\
  111.    while(count)name##Move2(index,from,to,count),count/=2,from=bIndexParent(from),to=bIndexParent(to);\
  112.   }else while(bIndexValid(from,index->levels))name##Move2(index,from,to,count),count*=2,\
  113.     to=bIndexLeft(to),from=bIndexLeft(from);\
  114.  }\
  115.  void name##Rotate(name *index,unsigned pos,signed char r1,signed char r2){\
  116.   unsigned p1=r1==1?bIndexRight(pos):bIndexLeft(pos),p2=r2==1?bIndexRight(p1):bIndexLeft(p1),\
  117.    o1=r1==1?p1-1:p1+1;\
  118.   unsigned char s=(unsigned char)7,b1=index->stat[p1]&s,b2=index->stat[p2]&s;\
  119.   name##Move(index,o1,r1==1?bIndexLeft(o1):bIndexRight(o1),1);\
  120.   name##Move(index,pos,o1,0);\
  121.   name##Move(index,r1==r2?p1:p2,pos,0);\
  122.   name##Move(index,r1==1?bIndexLeft(r1==r2?p1:p2):bIndexRight(r1==r2?p1:p2),r1==1?bIndexRight(o1):\
  123.    bIndexLeft(o1),1);\
  124.   name##Move(index,r1==r2?p2:r2==1?bIndexLeft(p2):bIndexRight(p2),r1==r2?p1:r2==1?bIndexRight(p1):\
  125.    bIndexLeft(p1),1);\
  126.   index->stat[pos]=(unsigned char)((index->stat[pos]&240)|((index->stat[pos]&8)|(b1==5?r1==1?4:6:5)));\
  127.   index->stat[o1]=(unsigned char)((index->stat[o1]&240)|\
  128.    ((index->stat[o1]&8)|(b1==5?r1==1?6:4:r1!=r2?b1==4&&b2==6?4:b1==6&&b2==4?6:5:5)));\
  129.   if(r1!=r2)index->stat[p1]=(uint8_t)((index->stat[p1]&240)|((index->stat[p1]&8)|(b1==b2?r1+5:5)));\
  130.  }\
  131.  unsigned name##Prev(name index,unsigned pos){\
  132.   for(unsigned r=bIndexLeft(pos);pos<(unsigned)((1<<index.levels)-1);){\
  133.    if(bIndexValid(r,index.levels)){while(bIndexValid((r=bIndexRight(r)),index.levels));}\
  134.    else{while(r>0&&(bIndexParentIsRight(r)))r=bIndexParent(r);}\
  135.    if(r==0)return (unsigned)-1;\
  136.    if((index.stat[pos=bIndexParent(r)]&8)!=0)return pos;\
  137.    else r=bIndexLeft(pos);\
  138.   }\
  139.   return (unsigned)-1;\
  140.  }\
  141.  unsigned name##Next(name index,unsigned pos){\
  142.   for(unsigned r=bIndexRight(pos);pos<(unsigned)((1<<index.levels)-1);){\
  143.    if(bIndexValid(r,index.levels)){while(bIndexValid((r=bIndexLeft(r)),index.levels));}\
  144.    else {while(r>0&&(bIndexParentIsLeft(r)))r=bIndexParent(r);}\
  145.    if(r==0)return (unsigned)-1;\
  146.    if((index.stat[pos=bIndexParent(r)]&8)!=0)return pos;\
  147.    else r=bIndexRight(pos);\
  148.   }\
  149.   return (unsigned)-1;\
  150.  }\
  151.  unsigned name##Min(name index){\
  152.   unsigned m=(unsigned)-1,min=index.levels?bIndexLevelStart(index.levels):m;\
  153.   return ((min==m)||((index.stat[min]&8)!=0))?min:name##Next(index,min);\
  154.  }\
  155.  unsigned name##Max(name index){\
  156.   unsigned m=(unsigned)-1,max=bIndexLevelEnd(index.levels);\
  157.   return ((max==m)||((index.stat[max]&8)!=0))?max:name##Prev(index,max);\
  158.  }\
  159.  unsigned name##FindIndex(name index,type item,int lowerbound){\
  160.   unsigned pos=0,m=(unsigned)-1,p=m,found=0;\
  161.   signed col;\
  162.   while(bIndexValid(pos,index.levels)){\
  163.    if((col=collator(&item,&index.data[pos]))<0)pos=bIndexLeft(pos);\
  164.    else if(col>0)pos=bIndexRight(pos);\
  165.    else break(found=1);\
  166.   }\
  167.   if(lowerbound){\
  168.    pos=found?((index.stat[pos]&8)==0)?name##Next(index,pos):pos:name##Next(index,bIndexParent(p=pos));\
  169.    if(!found&&bIndexParentIsRight(p))return\
  170.     (bIndexValid(pos,index.levels)&&(index.stat[pos]&8))?name##Prev(index,pos):name##Next(index,pos);\
  171.   }\
  172.   return bIndexValid(pos,index.levels)&&(index.stat[pos]&8)?pos:m;\
  173.  }\
  174.  void name##Add(name *index,type item){\
  175.   if(index->items==(unsigned)-2)return;\
  176.   signed char route[33];\
  177.   unsigned pos=0,routepos=0,s;\
  178.   signed col;\
  179.   while(bIndexValid(pos,index->levels)){\
  180.    if(index->stat[pos]==0)break;\
  181.    else if((col=collator(&item,&index->data[pos]))<0)route[routepos++]=-1,pos=bIndexLeft(pos);\
  182.    else if(col>0)route[routepos++]=1,pos=bIndexRight(pos);\
  183.    else route[routepos++]=1,pos=bIndexRight(pos);\
  184.   }\
  185.   if(!bIndexValid(pos,index->levels)){\
  186.    unsigned newlevels=index->levels+1,a,b;\
  187.    void *r1=bRealloc(index->data,(bIndexLevelEnd(newlevels)+1)*sizeof(type));\
  188.    void *r2=bRealloc(index->stat,(bIndexLevelEnd(newlevels)+1)*sizeof(unsigned char));\
  189.    if(!r1||!r2){bFree(r1),bFree(r2);index->items=(unsigned)-2;return;}\
  190.    ++index->levels,a=bIndexLevelStart(index->levels),b=index->levels-1;\
  191.    memset(((type*)(index->data=r1))+a,0,((uint64_t)1<<(b))*sizeof(type));\
  192.    memset(((char*)(index->stat=r2))+a,0,((uint64_t)1<<(b))*sizeof(unsigned char));\
  193.   }\
  194.   ++index->items,index->data[pos]=item,index->stat[pos]=8|5;\
  195.   while(routepos--){\
  196.    s=index->stat[(pos=bIndexParent(pos))]+=route[routepos];\
  197.    if((s&7)==5)break;\
  198.    if((s&3)==3)break(name##Rotate(index,pos,route[routepos],route[routepos+1]));\
  199.   }\
  200.  }\
  201.  void name##FreeItems(name *idx){\
  202.   if(idx->levels&&freefunc!=bFreeDefault)\
  203.    for(unsigned i=0;i<=bIndexLevelEnd(idx->levels);i++)if(idx->stat[i])freefunc(&idx->data[i]);\
  204.  }\
  205.  void name##Free(name *idx){\
  206.   name##FreeItems(idx);\
  207.   bFree(idx->data),bFree(idx->stat),memset(idx,0,sizeof(*idx));\
  208.  }\
  209.  void name##SplitMoveBaum(unsigned pos,name *from,name *to){\
  210.   unsigned count=1;\
  211.   while(bIndexValid(pos,from->levels)){\
  212.    for(unsigned i=0;i<count;i++)if(from->stat[pos+i]&8)name##Add(to,from->data[pos+i]);\
  213.    count*=2,pos=bIndexLeft(pos);\
  214.   }\
  215.  }
  216. #define bHeapParent(i) ((i)/2)
  217. #define bHeapLeft(i) (2*(i))
  218. #define bHeapRight(i) (2*(i)+1)
  219. #define bDECLARE_HEAP(name,type)\
  220.  typedef struct name{unsigned size,capacity;type *data;}name;\
  221.  void name##Reserve(name *heap,unsigned size);\
  222.  void name##Free(name *heap);\
  223.  void name##Add(name *heap,type item);\
  224.  type name##Extract(name *heap);\
  225.  void name##Delete(name *heap,unsigned index);\
  226.  type name##FindLast(name *heap);\
  227.  unsigned name##FindIndex(name *heap,type item);\
  228.  type name##Peek(name *heap);\
  229.  void name##Set(name *heap,unsigned index,type new);\
  230.  void name##InsertAll(name *heap,type *new,unsigned count);\
  231.  name name##Copy(name *heap);
  232. #define bDEFINE_HEAP(name,type,collator)\
  233.  void name##Reserve(name *heap,unsigned size){\
  234.   if(heap->capacity>=size)return;\
  235.   if((heap->data=bRealloc(heap->data,(heap->capacity=bGrow(size+3))*sizeof(type)))==0)\
  236.    heap->capacity=(unsigned)-2;\
  237.  }\
  238.  void name##Free(name *heap){\
  239.   bFree(heap->data);\
  240.   memset(heap,0,sizeof(*heap));\
  241.  }\
  242.  void name##Add(name *heap,type item){\
  243.   unsigned i=++heap->size;\
  244.   name##Reserve(heap,i+1);\
  245.   if(heap->capacity==(unsigned)-2)return;\
  246.   for(;i!=1&&collator(&item,&heap->data[bHeapParent(i)])<0;\
  247.    heap->data[i]=heap->data[bHeapParent(i)],i=bHeapParent(i));\
  248.   heap->data[i]=item;\
  249.  }\
  250.  void name##Heapify(name *heap,unsigned from){\
  251.   unsigned i=from,m,l,r;\
  252.   for(type t;;){\
  253.    m=i,l=bHeapLeft(i),r=bHeapRight(i);\
  254.    if(l<=heap->size&&collator(&heap->data[l],&heap->data[m])<0)m=l;\
  255.    if(r<=heap->size&&collator(&heap->data[r],&heap->data[m])<0)m=r;\
  256.    if(m!=i)t=heap->data[i],heap->data[i]=heap->data[m],heap->data[m]=t,i=m;\
  257.    else break;\
  258.   }\
  259.  }\
  260.  type name##Extract(name *heap){\
  261.   bAssert(heap->size);\
  262.   type ret=heap->data[1];\
  263.   heap->data[1]=heap->data[heap->size--];\
  264.   name##Heapify(heap,1);\
  265.   return ret;\
  266.  }
  267. void bFreeDefault(void *v){}
  268.  
  269. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  270. typedef uint32_t zBitCentrifuge;
  271. uint16_t m[]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
  272. typedef struct zHuffTable{
  273. #if zFAST_BITS
  274.  uint16_t litindex[1<<zFAST_BITS],distindex[1<<zFAST_BITS],lenindex[1<<zFAST_BITS];
  275. #endif
  276.  uint16_t litcode[288],litlens[288],litaccum[288],litsize[15],litoffs[15],littop[15];
  277.  uint16_t distcode[32],distlens[32],distaccum[32],distsize[15],distoffs[15],disttop[15];
  278.  uint16_t lencode[19],lenlens[19],lenaccum[19],lensize[15],lenoffs[15],lentop[15],ok;
  279. }zHuffTable;
  280. #define zHuffTableAdd(t_,p,len_,code_){if((len_))t_.p##accum[t_.p##offs[0]]=(code_),\
  281.  t_.p##lens[t_.p##offs[0]]=(len_),t_.p##size[(len_)-1]++,t_.p##offs[0]++;}
  282. #if !zFAST_BITS
  283. #define zHuffTableIndex(t,p)
  284. #else
  285. #define zHuffTableIndex(t_,p) for(i=0;i<zFAST_BITS;i++)for(j=0,len=i+1;j<t_.p##size[i];j++)\
  286.  for(t_.p##lens[t_.p##offs[i]+j]=len,k=0,l=1<<(zFAST_BITS-len),m=zReverseBits(t_.p##top[i]+j\
  287.   ,len),n=t_.p##offs[i]+j;k<l;k++)t_.p##index[(k<<len)|m]=n;
  288. #endif
  289. #define zHuffTableLockNoIndex__(t_,p) uint16_t c=0,b=1,i,j,offs_,k,l,len,m,n=(uint16_t)-1;\
  290.  for(;b<15;b++)t_.p##top[b]=(c=(c+(t_).p##size[b-1])<<1),(t_).p##top[b]-=((t_).p##size[b]?0:c);\
  291.  for(t_.ok++,i=1,j=2;i<=15;j-=t_.p##size[i++-1])if(i>1?j*=2:0,t_.p##size[i-1]>j)t_.ok--;\
  292.  for(t_.p##offs[0]=0,i=1,offs_=0;i<15;i++)t_.p##offs[i]=(offs_+=t_.p##size[i-1]);\
  293.  for(i=0;i<15;i++)for(k=0,l=0;k<t_.p##size[i];l++)if(t_.p##lens[l]==i+1)\
  294.   t_.p##code[(k++,++n)]=t_.p##accum[l];
  295. #define zHuffTableLock(t_,p) {zHuffTableLockNoIndex__(t_,p);zHuffTableIndex(t_,p);}
  296. #define zHuffTableLockNoIndex(t_,p) {zHuffTableLockNoIndex__(t_,p);}
  297. #define zHuffTableGetCode(t_,p,len_,code_) (code_-t_.p##top[len_-1]<t_.p##size[len_-1]?\
  298.  t_.p##code[code_-t_.p##top[len_-1]+t_.p##offs[len_-1]]:(uint16_t)-1)
  299. #define zHuffTablePrint_(t_,p) {for(uint16_t i=0;i<15;i++){\
  300.  if(t_.p##size[i])bLog("***"#p"*** lens:%d,count:%d,top:%d",i+1,t_.p##size[i],t_.p##top[i]);\
  301.  for(uint16_t code,j=0;j<=t_.p##size[i];j++){\
  302.   if((code=zHuffTableGetCode(t_,p,i+1,j+t_.p##top[i]))==(uint16_t)-1)continue;\
  303.   bString bs=bStringFromFormat("%c - %d - (%d) ",\
  304.    code>32&&code<127?(char)code:(char)'_',code,j+t_.p##top[i]),bin={0};\
  305.   bStringAddBinary(&bin,j+t_.p##top[i],16);\
  306.   for(uint16_t k=0;k<=i;k++)bStringAddChar(&bs,bin.data[bin.size-1-k]);\
  307.   bLog("%s",bs.data);bStringFree(&bin),bStringFree(&bs);}}}
  308. #define zHuffTablePrint(t_) zHuffTablePrint_(t_,len) zHuffTablePrint_(t_,dist) zHuffTablePrint_(t_,lit)
  309. #define zFetchBits(n) {if(avail<n){if((pos-=avail)+n>maxpos)goto catch;\
  310.  read=(*(bUnaligned32*)(in+(pos>>3)))>>(pos&7),pos+=(avail=(uint8_t)(32-(pos&7)));}}
  311. #define zReadBits(n,out) zFetchBits(n);out=(uint16_t)(read&m[n]),avail-=n,read>>=n
  312. #define zReadBit(out) zFetchBits(1);out=read&1,avail--,read>>=1
  313. #define zWriteBits(out,num,n) for(bUnaligned32 *a=(uint32_t*)(out+(pos>>3)),b=pos&7,c=m[n];\
  314.  a;pos+=n,*a=(*a&~(c<<b))|num<<b,a=0);
  315. #define zTableRun_1(p) {zFetchBits(zFAST_BITS);idx=t.p##index[read&((1<<zFAST_BITS)-1)],\
  316.  l=t.p##lens[idx];if(!l)goto delete;sym=t.p##code[idx],read>>=l,avail-=l;}
  317. #define zTableRun_2(p) {uint16_t accum=0,j=1,ac0,q=0,b;zReadBits(p##min-1,ac0);\
  318.  while(q<(p##min-1))accum|=(((ac0&(1<<(q)))>>(q))<<(p##min-q-2)),j++,q++;\
  319.  for(;j<=15;j++){zReadBit(b);accum=(accum<<1)|b;\
  320.   if((sym=zHuffTableGetCode(t,p,j,accum))!=(uint16_t)-1)break;}\
  321.  if(sym==(uint16_t)-1)goto delete;}
  322. #define zTableRun_3(p) zFetchBits(zFAST_BITS);idx=t.p##index[read&((1<<zFAST_BITS)-1)],l=t.p##lens\
  323.  [idx];if(idx){sym=t.p##code[idx],read>>=l,avail-=l;}else zTableRun_2(p)
  324. #if zFAST_BITS==15
  325. #define zTableRun zTableRun_1
  326. #elif zFAST_BITS
  327. #define zTableRun zTableRun_3
  328. #else
  329. #define zTableRun zTableRun_2
  330. #endif
  331. #define zHuffTableMakeLens(p,go) {go:for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)if(p##freqs[i])\
  332.   zHeapFreqToLenAdd(&ftl,(zFreqToLen){.freq=p##freqs[i],.len[0]=1});\
  333.  for(uint16_t min_=(uint16_t)-1;ftl.size>1;){\
  334.   zFreqToLen a=zHeapFreqToLenExtract(&ftl),b=zHeapFreqToLenExtract(&ftl);\
  335.   if(a.len[15]+b.len[15]>0){\
  336.    for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)\
  337.     if(p##freqs[i]&&(min_==(uint16_t)-1||p##freqs[i]<p##freqs[min_]))min_=i;\
  338.    p##freqs[min_]++;zHeapFreqToLenFree(&ftl);goto go;}\
  339.   zFreqToLen new={.freq=a.freq+b.freq};\
  340.   for(unsigned i=14;i<15;i--)new.len[i+1]+=a.len[i]+b.len[i];\
  341.   zHeapFreqToLenAdd(&ftl,new);}\
  342.  zFreqToLen f=zHeapFreqToLenExtract(&ftl);\
  343.  for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)\
  344.   if(p##freqs[i])zHeapLitToFreqByFreqAdd(&l2ff,(zLitToFreq){.lit=i,.freq=p##freqs[i]});\
  345.  for(uint16_t len=1,j;len<=15;len++){\
  346.   for(l2fl.size=0,j=0;j<f.len[len];j++)zHeapLitToFreqByLitAdd(&l2fl,zHeapLitToFreqByFreqExtract(&l2ff));\
  347.   while(l2fl.size)zHuffTableAdd(t,p,len,zHeapLitToFreqByLitExtract(&l2fl).lit);\
  348.  }\
  349.  zHuffTableLockNoIndex(t,p);\
  350.  memset(t.p##lens,0,sizeof(t.p##lens));memset(p##sym,0,sizeof(p##sym));\
  351.  for(uint16_t i=0;i<15;i++){\
  352.   for(uint16_t j=0;j<t.p##size[i];j++){\
  353.    p##sym[t.p##code[j+t.p##offs[i]]]=zReverseBits(j+t.p##top[i],i+1);\
  354.    t.p##lens[t.p##code[j+t.p##offs[i]]]=i+1;}}\
  355.  memcpy(t.p##code,p##sym,sizeof(p##sym));}
  356. #define zHuffTablePrintLens_(t_,p)\
  357.  for(uint16_t i=0;i<sizeof(t.p##lens)/2;i++){\
  358.   if(!t.p##lens[i])continue;\
  359.   bString s=bStringFromFormat(""#p"sym:%c %d len:%d num:%d ",\
  360.    i>32&&i<127?(char)i:(char)'_',i,t.p##lens[i],t.p##code[i]);\
  361.   bStringAddBinary(&s,t.p##code[i],t.p##lens[i]);\
  362.   bLog("%s",s.data);bStringFree(&s);}
  363. #define zHuffTablePrintLens(t_) zHuffTablePrintLens_(t_,lit) zHuffTablePrintLens_(t_,dist)
  364. #define zLogOut for(uint32_t i=0;i<s1->size;i++){\
  365.   if(out[i]&4294901760u){\
  366.    int ln=out[i]&65535,dst=(out[i]&4294901760u)>>16,dict=!(i-dst<s1->size);\
  367.    bString s=bStringFrom(!dict?s1->data+(i-dst):s2->data+(i-dst+s2->size),ln);\
  368.    bLog("%d: %d,%d (ln,dst) (%s) (%c)%s",i,ln,dst,s.data,s1->data[i],dict?" -->dict<--":"");\
  369.    bStringFree(&s);\
  370.   }else if(out[i]&512)bLog("%d: %c (char %d)",i,(char)(out[i]&255),(int)out[i]&255);\
  371.   else bLog("%d: (...) (%c) (val:%d)",i,s1->data[i],out[i]);}
  372. /////////////////////////////////////// NOW SKIP TO LINE 700  (ok, 701) !!!!!!!!!!
  373. uint8_t bHiBit(uint32_t n){
  374.  if(n==0)return 0;
  375. #ifdef bMSVC
  376.  DWORD ret=0;
  377.  _BitScanReverse(&ret,n);
  378.  return (uint8_t)ret;
  379. #elif 1
  380.  return 31-__builtin_clz(n);
  381. #else
  382.  unsigned ret=0;
  383.  while(n>>=1)ret++;
  384.  return (uint8_t)ret;
  385. #endif
  386. }
  387. void *bRealloc(void *memory,unsigned size){
  388. #ifdef bWINDOWS
  389.  void *r=memory?HeapReAlloc(GetProcessHeap(),0,memory,size):HeapAlloc(GetProcessHeap(),0,size);
  390. #else
  391.  void *r=realloc(memory,size);
  392. #endif
  393.  return /*!r?++bOom,r:*/r;
  394. }
  395. void bFree(void *memory){
  396. #ifdef bWINDOWS
  397.  HeapFree(GetProcessHeap(),0,memory);
  398. #else
  399.  free(memory);
  400. #endif
  401. }
  402. int bStringSetCapacity(bString *bs,unsigned capacity){
  403.  bAssert(capacity>=bs->size);
  404.  void *r=bAddU32Ovflo(capacity,ARRAY_EXTRA)?0:bRealloc(bs->data,(bs->capacity=capacity)+ARRAY_EXTRA);
  405.  return r?(memset((bs->data=(uint8_t*)r)+(bs->size),0,ARRAY_EXTRA)!=0):(bs->capacity=(unsigned)-2,0);
  406. }
  407. int bStringReserve(bString *bs,unsigned capacity){
  408.  return capacity<=bs->capacity?1:bStringSetCapacity(bs,bGrow(capacity));
  409. }
  410. void bStringFree(bString *bs){
  411.  if(bs->capacity!=(unsigned)-1)bFree(bs->data);
  412.  memset(bs,0,sizeof(*bs));
  413. }
  414. unsigned bStrlen(char *str){
  415.  return str?(unsigned)strlen(str):0;
  416. }
  417. bString bStringFrom(char *c,unsigned len){
  418.  bString bs={0};
  419.  bStringSetCapacity(&bs,len||!c?len:(len=(unsigned)bStrlen(c)));
  420.  if(bs.capacity!=(unsigned)-2){
  421.   if(c&&(bs.data&&len>0)&&bs.capacity>=len)memcpy(bs.data,c,len);
  422.   if(len>0&&c)memset(bs.data+(bs.size=len),0,ARRAY_EXTRA);
  423.  }
  424.  return bs;
  425. }
  426. void bStringErase(bString *bs,unsigned from,unsigned count){
  427.  if(count==(unsigned)-1||from+count>bs->size)count=bs->size-from;
  428.  if(from+count<bs->size)memmove(bs->data+from,bs->data+from+count,bs->size-(from+count));
  429.  memset(bs->data+(bs->size-=count),0,ARRAY_EXTRA);
  430. }
  431. void bStringInsert(bString *bs,char *c,unsigned len,unsigned pos){
  432.  if(len==0&&c&&(len=(unsigned)strlen(c))==0)return;
  433.  bStringReserve(bs,bs->size+len);
  434.  if(bs->capacity==(unsigned)-2)return;
  435.  if(pos>=bs->size)pos=bs->size;
  436.  else memmove(bs->data+pos+len,bs->data+pos,bs->size-pos);
  437.  memcpy(bs->data+pos,c,len);
  438.  memset(&bs->data[bs->size=bs->size+len],0,ARRAY_EXTRA);
  439. }
  440. unsigned bStringCodepointAt(bString bs,unsigned pos){
  441.  if(pos>=bs.size)return (unsigned)-1;
  442.  uint32_t c=bSwap32(*(bUnaligned32*)(bs.data+pos));
  443.  if((c&((unsigned)1<<31))==0)return (c&2130706432)>>24;
  444.  else if((c&4034953344)==4034953344)return ((c&63)|((c&16128)>>2)|((c&4128768)>>4)|(c&117440512)>>6);
  445.  else if((c&4034953216)==3766517760)return (((c&16128)>>8)|((c&4128768)>>10)|((c&251658240)>>12));
  446.  else if((c&3770679296)==3229614080)return (((c&4128768)>>16)|((c&520093696)>>18));
  447.  else return (unsigned)-1;
  448. }
  449. unsigned bStringNext(bString bs,unsigned pos,int reverse){
  450.  while(reverse?--pos:++pos)if(pos>bs.size||(bs.data[pos]>>6)!=2)break;
  451.  return pos;
  452. }
  453. bString bStringToUtf16(bString utf8){
  454.  bString ret=bStringFrom(NULL,(utf8.size+4)*2);
  455.  if(ret.capacity==(unsigned)-2)return ret;
  456.  for(unsigned cp,i=0;i<utf8.size;i=bStringNext(utf8,i,0)){
  457.   if((cp=bStringCodepointAt(utf8,i))<=65535){
  458.    ret.data[ret.size++]=(unsigned char)cp;
  459.    ret.data[ret.size++]=(unsigned char)((cp&65280)>>8);
  460.   }else if(cp<1114112&&(cp-=65536)){
  461.    ret.data[ret.size++]=(unsigned char)((cp&261120)>>10);
  462.    ret.data[ret.size++]=(unsigned char)((55296|((cp>>10&768)))>>8);
  463.    ret.data[ret.size++]=(unsigned char)(cp&255);
  464.    ret.data[ret.size++]=(unsigned char)((56320|(cp&768))>>8);
  465.   }
  466.  }
  467.  return ret;
  468. }
  469. void bStringAdd(bString *bs,char *c,unsigned len){
  470.  if(((c&&len==0)?(len=(unsigned)strlen(c)):len)==0)return;
  471.  bStringReserve(bs,bs->size+len);
  472.  if(!len||bs->capacity==(unsigned)-2)return;
  473.  memcpy(bs->data+bs->size,c,len);
  474.  memset(bs->data+(bs->size+=len),0,ARRAY_EXTRA);
  475. }
  476. void bStringAddChar(bString *bs,char c){
  477.  bStringReserve(bs,bs->size+1);
  478.  if(bs->capacity==(unsigned)-2)return;
  479.  bs->data[bs->size++]=(unsigned char)c;
  480.  memset(bs->data+bs->size,0,ARRAY_EXTRA);
  481. }
  482. const uint8_t bUpperToLower[256]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
  483.  27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61
  484.  ,62,63,64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,
  485.  121,122,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,
  486.  117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,
  487.  143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,
  488.  169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,
  489.  195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,
  490.  221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,
  491.  247,248,249,250,251,252,253,254,255};
  492. #define bLower(x)   (bUpperToLower[(unsigned char)(x)])
  493. unsigned bStringFindChar(bString bs,char c,unsigned from,int ignoreCase,int reverse){
  494.  if(ignoreCase)c=bLower(c);
  495.  if(reverse){
  496.   for(unsigned i=bMin(from,bs.size-1);i<bs.size;i--)
  497.    if((ignoreCase?(bLower(bs.data[i])):(bs.data[i]))==c)return i;
  498.   return (unsigned)-1;
  499.  }
  500.  unsigned ret=(unsigned)-1;
  501.  if(ignoreCase){
  502.   for(unsigned i=from,s;i<bs.size&&ret==-1;i+=4){
  503.    s=*((bUnaligned32*)((char*)bs.data+i));
  504.    if(bLower(((s&255)))==c)ret=i;
  505.    else if(bLower(((s&65280)>>8))==c)ret=i+1;
  506.    else if(bLower(((s&16711680)>>16))==c)ret=i+2;
  507.    else if(bLower(((s&4278190080)>>24))==c)ret=i+3;
  508.   }
  509.  }else{
  510.   for(unsigned i=from,s,cc=(unsigned)c;i<bs.size&&ret==-1;i+=4){
  511.    s=*((bUnaligned32*)((char*)bs.data+i));
  512.    if(((s&255))==cc)ret=i;
  513.    else if(((s&65280)>>8)==cc)ret=i+1;
  514.    else if(((s&16711680)>>16)==cc)ret=i+2;
  515.    else if(((s&4278190080)>>24)==cc)ret=i+3;
  516.   }
  517.  }
  518.  return ret<bs.size?ret:(unsigned)-1;
  519. }
  520. #define bFILE_READ 1
  521. #define bFILE_WRITE 2
  522. #define bFILE_CREATE_IF_NOT_EXISTS 4
  523. #define bFILE_DELETE_ON_CLOSE 8
  524. #define bFILE_WINDOWS_LONGNAME 16
  525. #define bFILE_OVERWRITE (bFILE_WRITE|32)
  526. #define bFILE_APPEND 64
  527. #if defined bWINDOWS
  528. typedef struct bFile{bString name,name16,cache,line;HANDLE h;int flags,error;unsigned pos,z;}bFile;
  529. #else
  530. typedef struct bFile{bString name,cache,line;int fd,flags,error;unsigned pos,z;}bFile;
  531. #endif
  532. void bFileUnfillCache(bFile *f){
  533.  if(f->cache.size==0)return;
  534.  void bFileSetCursor(bFile *f,uint64_t pos);
  535.  uint64_t bFileGetCursor(bFile *f);
  536.  uint64_t topos=bFileGetCursor(f);
  537.  bStringFree(&f->cache),f->pos=0,f->z=0;
  538.  bFileSetCursor(f,topos);
  539. }
  540. bFile bFileFrom(char *name,int flags){
  541.  //if(!name||!*name)return bFileTempFile();
  542. #ifdef bWINDOWS
  543.  bString fn=bStringFrom(name,0),fn16=bStringToUtf16(fn),s;
  544.  if(flags&bFILE_WINDOWS_LONGNAME)bStringInsert(&fn16,(char*)L"\\\\?\\",8,0);
  545.  DWORD acc=0,share=FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
  546.   open=(flags&bFILE_CREATE_IF_NOT_EXISTS)?OPEN_ALWAYS:OPEN_EXISTING,
  547.   attr=(flags&bFILE_DELETE_ON_CLOSE)?FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE:0,i=0,d;
  548.  if(fn16.size>4&&fn16.data[fn16.size-2]!='\\'
  549.     &&((d=GetFileAttributesW((wchar_t*)fn16.data))!=(DWORD)-1)&&d&FILE_ATTRIBUTE_DIRECTORY)
  550.   bStringAdd(&fn16,(char*)L"\\",2),bStringAddChar(&fn,'/');
  551.  if(flags&bFILE_READ)acc|=GENERIC_READ;
  552.  if(flags&bFILE_WRITE)acc|=GENERIC_WRITE;
  553.  if(flags&bFILE_CREATE_IF_NOT_EXISTS)
  554.   for(unsigned i=bStringFindChar(fn16,'\\',0,0,0);i!=(unsigned)-1;i=bStringFindChar(fn16,'\\',i+1,0,0))
  555.    CreateDirectoryW((LPCWSTR)(s=bStringFrom((char*)fn16.data,i)).data,0),bStringFree(&s);
  556.  HANDLE h=0;
  557.  for(;i<11;i++){
  558.   if((h=CreateFileW((wchar_t*)fn16.data,acc,share,NULL,open,attr|FILE_ATTRIBUTE_NORMAL,NULL))
  559.      !=INVALID_HANDLE_VALUE)break;
  560.   if((d=GetLastError())==ERROR_SHARED_POLICY||d==ERROR_LOCK_VIOLATION||d==ERROR_DEV_NOT_EXIST||
  561.    d==ERROR_NETNAME_DELETED||d==ERROR_SEM_TIMEOUT||d==ERROR_NETWORK_UNREACHABLE)/*bSleep(333)*/;
  562.   else break;
  563.  }
  564.  bFile ret=(bFile){.name=fn,.name16=fn16,.h=h,.flags=flags,
  565.   .error=(h==0||h==INVALID_HANDLE_VALUE)?-1/*bErrno()*/:0};
  566. #else
  567.  bString fn=bStringFrom(name,0),s;
  568.  int of=((flags&(bFILE_READ|bFILE_WRITE))==(bFILE_READ|bFILE_WRITE))?O_RDWR:flags&bFILE_WRITE?O_WRONLY:
  569.   O_RDONLY,cr=0666,fd=0,i;
  570.  if(fn.data[fn.size-1]!=bFILE_DIRSEP){
  571.   bFileinfo info=bFileinfoFrom((char*)fn.data);
  572.   if(info.type==bFILEINFO_TYPE_DIR)bStringAddChar(&fn,bFILE_DIRSEP);
  573.   bFileinfoFree(&info);
  574.  }
  575.  if(flags&bFILE_CREATE_IF_NOT_EXISTS)
  576.   for(of|=O_CREAT,i=(signed)bStringFindChar(fn,'/',1,0,0);i!=-1;i=bStringFindChar(fn,'/',i+1,0,0))
  577.    mkdir((char*)(s=bStringFrom((char*)fn.data,(unsigned)i)).data,0777),bStringFree(&s);
  578.  if(fn.data[fn.size-1]==bFILE_DIRSEP)cr=0777,of=O_DIRECTORY;
  579.  bArrayInt fds={0};
  580.  for(int i=0;i<11;i++){
  581.   if((fd=open((char*)fn.data,of,cr))>2)break;
  582.   bArrayIntAdd(&fds,fd);
  583.   if(errno!=EINTR&&fd==-1)break;
  584.   bSleep(111);
  585.  }
  586.  for(unsigned i=0;i<fds.size;i++)close(fds.data[i]);
  587.  bArrayIntFree(&fds);
  588.  bFile ret=(bFile){.name=fn,.fd=fd,.flags=flags,.error=fd>2?0:bErrno()};
  589. #endif
  590.  //if((flags&bFILE_OVERWRITE)==bFILE_OVERWRITE)bFileSetSize(&ret,0);
  591.  //else if(flags&bFILE_APPEND)bFileSetCursor(&ret,bFileGetSize(&ret));
  592.  return ret;
  593. }
  594. void bFileFree(bFile *f){
  595.  //if(f->flags&bFILE_DELETE_ON_CLOSE)bFileDelete(f,NULL);
  596.  int err=0;
  597. #ifdef bWINDOWS
  598.  if(CloseHandle(f->h)==0)err=(int)GetLastError();
  599.  bStringFree(&f->name16);
  600. #else
  601.  while(close(f->fd)==-1)if(errno!=EINTR)break(err=errno);
  602. #endif
  603.  bStringFree(&f->name);
  604.  bStringFree(&f->cache);
  605.  bStringFree(&f->line);
  606.  memset(f,0,sizeof(bFile));
  607.  f->error=err;
  608. }
  609. void bFileSetCursor(bFile *f,uint64_t pos){
  610.  bFileUnfillCache(f);
  611. #ifdef bWINDOWS
  612.  LARGE_INTEGER ll={.QuadPart=pos};
  613.  if(ll.QuadPart<0)ll.QuadPart=0;
  614.  if(!SetFilePointerEx(f->h,ll,NULL,FILE_BEGIN))f->error=(int)GetLastError();
  615. #else
  616.  if(lseek(f->fd,pos,SEEK_SET)==-1)f->error=errno;
  617. #endif
  618. }
  619. uint64_t bFileGetCursor(bFile *f){
  620. #ifdef bWINDOWS
  621.  FlushFileBuffers(NULL);
  622.  LARGE_INTEGER ret={0},ll={0};
  623.  if(!SetFilePointerEx(f->h,ll,&ret,FILE_CURRENT))f->error=(int)GetLastError();
  624.  return (uint64_t)(ret.QuadPart-f->cache.size+f->pos);
  625. #else
  626.  uint64_t ret=(uint64_t)lseek(f->fd,0,SEEK_CUR);
  627.  return ret==-1?f->error=errno,(uint64_t)0:(ret-f->cache.size+f->pos);
  628. #endif
  629. }
  630. #define bFILE_CACHESIZE 4194304
  631. void bFileInitCache(bFile *f){
  632.  if(f->z)memcpy(f->cache.data+f->pos,&f->z,3),f->z=0;
  633. }
  634. void bFileFillCache(bFile *f,unsigned size){
  635.  bFileInitCache(f);
  636.  if(f->cache.size-f->pos==0)f->cache.size=0,f->pos=0;
  637.  if(size<(f->cache.size-f->pos))return;
  638.  if(f->pos<f->cache.size)memmove(f->cache.data,f->cache.data+f->pos,f->cache.size-f->pos),
  639.    f->cache.size-=f->pos,f->pos=0;
  640.  if(size<bFILE_CACHESIZE)size=bFILE_CACHESIZE;
  641.  bStringReserve(&f->cache,f->cache.size+size+3);
  642. #ifdef bWINDOWS
  643.  while(size>0){
  644.   DWORD read=0,error;
  645.   BOOL r=ReadFile(f->h,(LPVOID)(f->cache.data+f->cache.size),(DWORD)(bMin(size,bFILE_CACHESIZE)),&read,0);
  646.   if(r&&read)size-=read,f->cache.size+=read;
  647.   else if(r&&!read)break;
  648.   else if((error=GetLastError())==ERROR_HANDLE_EOF)break;
  649.   else break(f->error=(int)error);
  650.  }
  651. #else
  652.  while(size>0){
  653.   ssize_t r=read(f->fd,f->cache.data+f->cache.size,(size_t)(bMin(size,bFILE_CACHESIZE)));
  654.   if(r==-1){
  655.    if(errno==EINTR)continue;
  656.    break(f->error=errno);
  657.   }
  658.   size-=r,f->cache.size+=r;
  659.   if(r==0)break;
  660.  }
  661. #endif
  662. }
  663. bString *bFileRead(bFile *f,unsigned len){
  664.  bFileFillCache(f,len);
  665.  if(f->cache.size==0)return bStringFree(&f->line),&f->line;
  666.  len=bMin(f->cache.size-f->pos,len);
  667.  memcpy(&f->z,f->cache.data+f->pos+len,3);
  668.  memset(f->cache.data+f->pos+len,0,3);
  669.  f->line=(bString){.data=f->cache.data+f->pos,.size=len,.capacity=(unsigned)-1};
  670.  return f->pos+=len,&f->line;
  671. }
  672. uint32_t bFileReadUint32(bFile *f){
  673.  bFileFillCache(f,sizeof(uint32_t));
  674.  if(f->pos+sizeof(uint32_t)>f->cache.size)return 0;
  675.  uint32_t ret=*(bUnaligned32*)((char*)f->cache.data+f->pos);
  676.  f->pos+=sizeof(uint32_t);
  677.  return ret;
  678. }
  679. void bFileWrite(bFile *f,void *data,int64_t len){
  680.  bFileUnfillCache(f);
  681.  unsigned write0=0;
  682. #ifdef bWINDOWS
  683.  while(len>0){
  684.   DWORD written=0;
  685.   if(WriteFile(f->h,data,(DWORD)(bMin(len,65535)),&written,0)==0)break(f->error=(int)GetLastError());
  686.   len-=(int)written,data=(((char*)data)+written);
  687.   if(!written)if(++write0>11)break(f->error=(unsigned)-1);
  688.  }
  689. #else
  690.  while(len>0){
  691.   ssize_t written=write(f->fd,data,(size_t)bMin(len,65535));
  692.   if(written==-1){
  693.    if(errno==EINTR)continue;
  694.    else break(f->error=errno);
  695.   }
  696.   len-=written,data+=written;
  697.   if(!written&&++write0>11)break(f->error=(unsigned)-1);
  698.  }
  699. #endif
  700. }
  701. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  702. uint16_t zReverseBits(uint16_t num,uint8_t size){
  703.  uint16_t ret=0;
  704.  while(size--)ret=(ret<<1)|num&1,num>>=1;
  705.  return ret;
  706. }
  707. uint16_t zDistToCode(uint32_t distance/*3...32768*/,uint16_t *extra,uint16_t *extralen){
  708.  if(distance<3)return (*extra)=0,(*extralen)=0,distance-1;
  709.  uint16_t hi=bHiBit(distance-1),code=hi*2;
  710.  (*extralen)=hi-1,(*extra)=((1<<(hi))+1);
  711.  if((distance-1)&(1<<(hi-1)))(code)++,(*extra)+=(1<<(hi-1));
  712.  return (*extra)=distance-*extra,code;
  713. }
  714. uint16_t zLenToCode(uint16_t len/*3...284*/,uint16_t *extra,uint16_t *extralen){
  715.  bAssert(len>=3&&len<=284);
  716.  uint16_t e=len<7?0:bMin(5,(bHiBit(len-3)-2)&7),o=1<<(e+2)|3;
  717.  return (*extralen)=e,(*extra)=(len-o)%(1<<e),e?(((len-o)/((1<<e)))+((e*4)+5|(1<<8))):len+254;
  718. }
  719. uint16_t zCodeToLen(uint16_t code,uint16_t *extra){
  720.  uint16_t c=code,e=(((c&63)-1)>>2)-1,len=0;
  721.  if((1<<(e&7))&192)e=0;
  722.  if(e){
  723.   while((c&=31)>8)c-=4;
  724.   len=((c-1)<<e)|3;
  725.   if(e==1&&(c-1)&1)len+=2;
  726.  }else len=c==285?258:(c&31)+2;
  727.  return (*extra)=e,len;
  728. }
  729. int bZibUncompress__(bString *ret,bString compressed,bString *dictionary,uint32_t pos,uint32_t *endpos){
  730.  zBitCentrifuge read=0;
  731.  uint32_t maxpos=compressed.size<<3,lastpos;
  732.  uint16_t final,metod,hlit,hdist,hclen,i,sym=0,idx,l,len;
  733.  uint8_t *in=compressed.data,lenmin,litmin,distmin,avail=0,lenz[320];
  734.  for(zHuffTable t={0};;){
  735.   lastpos=ret->size;
  736.   zReadBits(3,i);
  737.   if(final=i&1,(metod=i>>1)==2){
  738.    zReadBits(14,i);
  739.    hlit=(i&31)+257,hdist=((i&992)>>5)+1,hclen=((i&15360)>>10)+4;
  740.    memset(&t,0,sizeof(t));
  741.    uint8_t hclenordr[]={16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15},hclens[19]={0};
  742.    for(i=0;i<hclen;i++){zReadBits(3,len);hclens[hclenordr[i]]=len;}
  743.    for(i=0;i<19;i++)zHuffTableAdd(t,len,hclens[i],i);
  744.    zHuffTableLock(t,len);
  745.    for(lenmin=1;!t.lensize[lenmin-1]&&lenmin<9;lenmin++);
  746.    memset(lenz,0,320);
  747.    for(uint16_t i=0,j,prev=0,rep;i<hlit+hdist;i++){
  748.     zTableRun(len);
  749.     if(sym<16)lenz[i]=(prev=sym);
  750.     else if(sym==16){zReadBits(2,rep);rep+=3;while(rep--)lenz[i++]=prev;i--;}
  751.     else if(sym==17){zReadBits(3,j);i+=j+2;}
  752.     else if(sym==18){zReadBits(7,j);i+=j+10;}
  753.    }
  754.    for(i=0;i<hlit;i++)zHuffTableAdd(t,lit,lenz[i],i);
  755.    for(i=hlit;i<hlit+hdist;i++)zHuffTableAdd(t,dist,lenz[i],i-hlit);
  756.    zHuffTableLock(t,lit);
  757.    zHuffTableLock(t,dist);
  758.    if(t.ok!=3)goto delete;
  759.    for(litmin=1;!t.litsize[litmin-1]&&litmin<9;litmin++);
  760.    for(distmin=1;!t.distsize[distmin-1]&&distmin<9;distmin++);
  761.   }else if(metod==0){
  762.    if(pos-=avail,read=0,avail=0,pos&7)pos=(((pos+7)>>3)<<3);
  763.    uint32_t stored=(*(bUnaligned32*)((char*)in+(pos>>3)))&65535;
  764.    if(pos+(stored<<3)>maxpos)goto catch;
  765.    if(!bStringReserve(ret,ret->size+stored))return 0;
  766.    memcpy(ret->data+ret->size,in+(4+(pos>>3)),stored);
  767.    ret->size+=stored,pos+=32+(stored<<3),(*endpos)=pos-avail;
  768.    if(final)break;
  769.    else continue;
  770.   }else{
  771.    if(litmin=7,distmin=5,t.ok!=4){
  772.     memset(&t,0,sizeof(t));
  773.     for(i=0;i<=143;i++)zHuffTableAdd(t,lit,8,i);
  774.     for(i=144;i<=255;i++)zHuffTableAdd(t,lit,9,i);
  775.     for(i=256;i<=279;i++)zHuffTableAdd(t,lit,7,i);
  776.     for(i=280;i<=287;i++)zHuffTableAdd(t,lit,8,i);
  777.     for(i=0;i<=29;i++)zHuffTableAdd(t,dist,5,i);
  778.     zHuffTableLock(t,lit);
  779.     zHuffTableLock(t,dist);
  780.     t.ok=4;
  781.    }
  782.   }
  783.   for(;;){
  784.    zTableRun(lit);
  785.    if(sym<256){
  786.     if(!bStringReserve(ret,ret->size+1))return 0;
  787.     ret->data[ret->size++]=(char)sym;
  788.    }else if(sym==256){
  789.     break((*endpos)=pos-avail);
  790.    }else if(sym>=257&&sym<=285){
  791.     static const uint16_t ex[]={0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0},
  792.      ln[]={3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
  793.     uint16_t l1=sym-(uint16_t)257,len=ln[l1],extra=ex[l1],dst,j;
  794.     if(extra){zReadBits(extra,j);len+=j;}
  795.     zTableRun(dist);
  796.     extra=((sym/2)-1)+(sym>1?0:1),dst=sym>1?1+((2+(sym&1))<<extra):++sym;
  797.     if(extra){zReadBits(extra,j);dst+=j;}
  798.     if(!bStringReserve(ret,ret->size+len))return 0;
  799.     if(dst>len&&dst+len<ret->size){
  800.      memcpy(ret->data+ret->size,ret->data+ret->size-dst,len);
  801.      ret->size+=len;
  802.     }else while(len--){
  803.      unsigned char *c=ret->size-dst<ret->size?ret->data+ret->size-dst:dictionary&&dictionary->size-dst+
  804.               ret->size<dictionary->size?dictionary->data+dictionary->size-dst+ret->size:0;
  805.      if(c)ret->data[ret->size++]=*c;
  806.      else goto delete;
  807.     }
  808.    }else goto delete;
  809.   }
  810.   if(final)break;
  811.  }
  812.  if(ret->data)memset(ret->data+ret->size,0,ARRAY_EXTRA);
  813.  if(0)delete:return bStringFree(ret),0;
  814.  if(0)catch:return bStringErase(ret,lastpos,(unsigned)-1),0;
  815.  return final;
  816. }
  817. bString bZibUncompress(bString compressed,bString *dictionary){
  818.  bString ret=bStringFrom(0,bMax(1<<17,compressed.size*3));
  819.  if(compressed.size<5||ret.capacity==(unsigned)-2)return ret;
  820.  uint32_t header=*(bUnaligned32*)compressed.data,pos=(header&8207)==8200?48:
  821.   ((!(header&7))&&(((header>>8)&255)!=(~(header>>24)&255)))?16:0,endpos=pos;
  822.  if((header&65535)==35615&&compressed.size>10)
  823.   if(pos=80,header&134217728){while(*(compressed.data+(pos>>3)))pos+=8;pos+=8;}
  824.  bZibUncompress__(&ret,compressed,dictionary,pos,&endpos);
  825.  return ret;
  826. }
  827. int bZibUncompressFile(char *fileCompressed,char *fileUncompressed){
  828.  bString s1=bStringFrom(NULL,9876789),s2={0},*l=&s1,*r=&s2,*s;
  829.  bFile in=bFileFrom(fileCompressed,bFILE_READ),
  830.   out=bFileFrom(fileUncompressed,bFILE_OVERWRITE|bFILE_CREATE_IF_NOT_EXISTS);
  831.  uint32_t header=bFileReadUint32(&in),pos=(header&8207)==8200?48:((!(header&7))&&(((header>>8)&255)!=
  832.   (~(header>>24)&255)))?16:0,endpos=pos,lastend=endpos,final=0;
  833.  bFileSetCursor(&in,0);
  834.  for(bString *compressed;;){
  835.   uint64_t cursor=bFileGetCursor(&in);
  836.   if((compressed=bFileRead(&in,33333333))->size==0)break;
  837.   final=bZibUncompress__(r,*compressed,l,pos,&endpos);
  838.   bFileWrite(&out,r->data,r->size);
  839.   if(lastend==endpos||r->capacity==(unsigned)-2)break;
  840.   bFileSetCursor(&in,cursor+((lastend=endpos)>>3));
  841.   if(s=l,l=r,(r=s)->size=0,pos=endpos&7,final)break;
  842.  }
  843.  return bFileFree(&out),bFileFree(&in),bStringFree(&s2),bStringFree(&s1),
  844.   final&&in.error==0&&out.error==0;
  845. }
  846. typedef struct zFreqToLen{uint16_t freq,len[16];}zFreqToLen;
  847. typedef struct zLitToFreq{uint16_t lit,freq;}zLitToFreq;
  848. int zCollateFreq(zFreqToLen *a,zFreqToLen *b){return bCollate(a->freq,b->freq);}
  849. int zCollateLitToFreqByFreq(zLitToFreq *a,zLitToFreq *b){return bCollate(b->freq,a->freq);}
  850. int zCollateLitToFreqByLit(zLitToFreq *a,zLitToFreq *b){return bCollate(a->lit,b->lit);}
  851. bDECLARE_HEAP(zHeapFreqToLen,zFreqToLen);
  852. bDECLARE_HEAP(zHeapLitToFreqByFreq,zLitToFreq);
  853. bDECLARE_HEAP(zHeapLitToFreqByLit,zLitToFreq);
  854. bDEFINE_HEAP(zHeapFreqToLen,zFreqToLen,zCollateFreq);
  855. bDEFINE_HEAP(zHeapLitToFreqByFreq,zLitToFreq,zCollateLitToFreqByFreq);
  856. bDEFINE_HEAP(zHeapLitToFreqByLit,zLitToFreq,zCollateLitToFreqByLit);
  857. #if !zCOMPRESSION_IN_A_HURRY
  858. typedef struct zPos{uint32_t val,pos;}zPos;
  859. int zCollatePos(zPos *l,zPos *r){
  860.  int col=bCollate(l->val,r->val);
  861.  return col?col:bCollate(r->pos,l->pos);
  862. }
  863. bDECLARE_INDEX(zIndexPos,zPos);
  864. bDEFINE_INDEX(zIndexPos,zPos,zCollatePos,bFreeDefault);
  865. #endif
  866. #define zBLOCK_SIZE 32768 /* ...65535 */
  867. bString bZibCompress__(bString uncompressed,bString *dictionary){
  868.  bString ret=bStringFrom(0,uncompressed.size);
  869.  zHuffTable t;
  870.  zHeapFreqToLen ftl={0};
  871.  zHeapLitToFreqByFreq l2ff={0};
  872.  zHeapLitToFreqByLit l2fl={0};
  873.  uint16_t litfreqs[288]={0},distfreqs[32]={0},litsym[288],distsym[32],e,el,de,del;
  874.  static const uint8_t ll[][2]={{13,5},{31,7},{15,6},{29,5},{0,2},{2,2},{1,3},{5,4},{3,5},{19,5},{11,5},
  875.   {27,5},{47,6},{95,7},{63,7},{127,7},{0,0},{7,5},{23,5}},lens[]={0,5,5,5,5,4,5,3,5,2,5,2,6,5,7,6,7,7,7};
  876.  bString sleft={0},sright={0},*s1=&sleft,*s2=&sright;
  877. #if !zCOMPRESSION_IN_A_HURRY
  878.  zIndexPos mpos={0},mposprev={0},*ml=&mpos,*mr=&mposprev,*ms;
  879.  if(dictionary&&(sright.data=dictionary->data)&&(sright.size=dictionary->size)){
  880.   for(uint16_t i=2;i<s2->size;i++)zIndexPosAdd(mr,(zPos){.val=s2->data[i-2]<<16|s2->data[i-1]<<8
  881.    |s2->data[i],.pos=i-2});
  882.  }
  883. #else
  884.  uint16_t mpos[65536],mposprev[65536]={0},*ml=mpos,*mr=mposprev,*ms;
  885.  if(dictionary&&(sright.data=dictionary->data)&&(sright.size=dictionary->size)){
  886.   for(uint16_t i=1;i<s2->size;i++)mr[s2->data[i-1]<<8|s2->data[i]]=i-1;
  887.  }
  888. #endif
  889.  unsigned pos=0,remaining=uncompressed.size;
  890.  while(remaining){
  891.   uint32_t out[zBLOCK_SIZE]={0};
  892.   s1->data=uncompressed.data+uncompressed.size-remaining,s1->size=bMin(zBLOCK_SIZE,remaining),
  893.    remaining-=s1->size;
  894. #if !zCOMPRESSION_IN_A_HURRY
  895.   zIndexPosFree(ml);
  896. #else
  897.   memset(ml,0,sizeof(mpos));
  898. #endif
  899.   memset(litfreqs,0,sizeof(litfreqs));
  900.   memset(distfreqs,0,sizeof(distfreqs));
  901.   memset(litsym,0,sizeof(litsym));
  902.   memset(distsym,0,sizeof(distsym));
  903. #if !zCOMPRESSION_IN_A_HURRY
  904.   for(uint16_t i=2;i<s1->size;i++){
  905.    uint16_t len=0,l2,dist=0,l,r,j=i-2,c;
  906.    uint32_t val=(s1->data[i-2]<<16|s1->data[i-1]<<8|s1->data[i]),sm1=s1->size-1;
  907.    unsigned m=zIndexPosFindIndex(*ml,(zPos){.val=val,.pos=(uint16_t)-1},1);
  908.    if(m!=-1&&(dist=i-2-ml->data[m].pos)&&ml->data[m].val==val&&i-ml->data[m].pos<21){
  909.     for(c=0,l=ml->data[m].pos,r=i-2;r+dist<s1->size&&len+dist<257&&!memcmp(s1->data+l,s1->data+r,dist);
  910.      len+=dist,r+=dist);
  911.     if(c<3)len=0,dist=0;
  912.    }
  913.    for(;m!=-1&&ml->data[m].val==val;m=zIndexPosNext(*ml,m)){
  914.     for(l2=2,l=ml->data[m].pos+2,r=i;l<i-2&&r<sm1-1&&l2<257&&s1->data[l++]==s1->data[r++];l2++);
  915.     if(l2>len)len=l2,dist=i-2-ml->data[m].pos;
  916.    }
  917.    for(m=zIndexPosFindIndex(*mr,(zPos){.val=val,.pos=(uint16_t)-1},1);m!=-1&&mr->data[m].val==val
  918.     &&s2->size-mr->data[m].pos+i-2<32768;m=zIndexPosNext(*mr,m)){
  919.     for(l2=2,l=mr->data[m].pos+2,r=i;l<s2->size&&r<sm1-1&&l2<257&&s2->data[l++]==s1->data[r++];l2++);
  920.     if(l2>len)len=l2,dist=s2->size-mr->data[m].pos+i-2;
  921.    }
  922.    if(len>3||(len==3&&dist<8))out[i-2]=(dist<<16)|len,i+=len-1,
  923.     litfreqs[zLenToCode(len,&e,&el)]++,distfreqs[zDistToCode(dist,&de,&del)]++;
  924.    else cont1nue:out[i-2]=s1->data[i-2]|512,litfreqs[s1->data[i-2]]++;
  925.    for(uint32_t k=j+2,v;v=s1->data[k]<<16|s1->data[k+1]<<8|s1->data[k+2],k<i-1;k++)
  926.     zIndexPosAdd(ml,(zPos){.val=v,.pos=k});
  927.    zIndexPosAdd(ml,(zPos){.pos=j,.val=val});
  928.   }
  929.   if(s1->size>1)out[s1->size-2]=s1->data[s1->size-2]|512,litfreqs[s1->data[s1->size-2]]++;
  930.   out[s1->size-1]=s1->data[s1->size-1]|512,litfreqs[s1->data[s1->size-1]]++;
  931. #else
  932.   for(uint16_t i=1;i<s1->size;i++){
  933.    uint16_t val=(s1->data[i-1]<<8|s1->data[i]),match=ml[val],len=0,len2,dist=0,l,r,j=i-1;
  934.    if(dist=i-1-match,match&&i-match<21)
  935.     for(l=match,r=i-1;r+dist<s1->size&&len+dist<257&&!memcmp(s1->data+l,s1->data+r,dist);
  936.      len+=dist,r+=dist);
  937.    for(;match &&i-1-match<32768 ;){
  938.     for(len2=2,l=match+2,r=i+1;l<i-1&&r<s1->size-1&&len2<257&&s1->data[l++]==s1->data[r++];len2++);
  939.     if(len2>len)len=len2,dist=i-1-match;
  940.     match-=(out[match]&4294901760u)?out[match]>>16:match;
  941.    }
  942.    if((match=mr[val])&&(s2->size-match)+i-1<32768 ){
  943.     for(len2=2,l=match+2,r=i+1;l<s2->size&&r<s1->size-1&&len2<257&&s2->data[l++]==s1->data[r++];len2++);
  944.     if(len2>len)len=len2,dist=(s2->size-match)+i-1;
  945.    }
  946.    if(len>3||(len==3&&dist<9))out[i-1]=(dist<<16)|len,i+=len-1,
  947.     litfreqs[zLenToCode(len,&e,&el)]++,distfreqs[zDistToCode(dist,&de,&del)]++;
  948.    else out[i-1]=s1->data[i-1]|512,litfreqs[s1->data[i-1]]++;
  949.    ml[val]=j;
  950.   }
  951.   out[s1->size-1]=s1->data[s1->size-1]|512,litfreqs[s1->data[s1->size-1]]++;
  952. #endif
  953.   ;uint16_t litused=0,distused=0,i;
  954.   for(litfreqs[256]=1,i=0;i<255;i++)if(litfreqs[i]&&++litused>=4)break;
  955.   for(i=0;i<32;i++)if(distfreqs[i]&&++distused>=4)break;
  956.   for(i=0;litused<4;litfreqs[++i]++,++litused);
  957.   for(i=0;distused<4;distfreqs[++i]++,++distused);
  958.   memset(&t,0,sizeof(t));
  959.   zHuffTableMakeLens(lit,go1);
  960.   zHuffTableMakeLens(dist,go2);
  961.   bStringReserve(&ret,(pos>>3)+(bMax(65535,zBLOCK_SIZE*2)));
  962.   ret.size=ret.capacity;
  963.   zWriteBits(ret.data,0,1);
  964.   zWriteBits(ret.data,2,2);
  965.   zWriteBits(ret.data,28,5);
  966.   zWriteBits(ret.data,29,5);
  967.   zWriteBits(ret.data,15,4);
  968.   for(uint8_t i=0;i<19;i++)zWriteBits(ret.data,lens[i],3);
  969.   for(unsigned repeat,i=0;i<285;i++){
  970.    uint16_t len=t.litlens[i];
  971.    zWriteBits(ret.data,ll[len][0],ll[len][1]);
  972.    for(repeat=1;!len&&repeat<138&&i+repeat<285;repeat++)if(t.litlens[i+repeat])break(repeat--);
  973.    if(repeat<12)continue;
  974.    zWriteBits(ret.data,ll[18][0],ll[18][1]);zWriteBits(ret.data,--repeat-11,7);i+=repeat;
  975.   }
  976.   for(unsigned i=0,len;i<30;i++){len=t.distlens[i];zWriteBits(ret.data,ll[len][0],ll[len][1]);}
  977.   for(uint32_t i=0;i<s1->size;i++){
  978.    if(out[i]&4294901760u){
  979.     uint16_t l=zLenToCode(out[i]&65535,&e,&el),d=zDistToCode((out[i]&4294901760u)>>16,&de,&del);
  980.     zWriteBits(ret.data,t.litcode[l],t.litlens[l]);
  981.     if(el)zWriteBits(ret.data,e,el);
  982.     zWriteBits(ret.data,t.distcode[d],t.distlens[d]);
  983.     if(del)zWriteBits(ret.data,de,del);
  984.    }else if(out[i]&512)zWriteBits(ret.data,t.litcode[out[i]&255],t.litlens[out[i]&255]);
  985.   }
  986.   zWriteBits(ret.data,t.litcode[256],t.litlens[256]);
  987.   s2->data=s1->data,s2->size=s1->size,ms=mr,mr=ml,ml=ms;
  988.  }
  989.  zHeapLitToFreqByLitFree(&l2fl);
  990.  zHeapLitToFreqByFreqFree(&l2ff);
  991.  zHeapFreqToLenFree(&ftl);
  992. #if !zCOMPRESSION_IN_A_HURRY
  993.  zIndexPosFree(mr);
  994.  zIndexPosFree(ml);
  995. #endif
  996.  zWriteBits(ret.data,0,1);
  997.  zWriteBits(ret.data,0,2);
  998.  if(pos&7)pos=((pos+7)>>3)<<3;
  999.  zWriteBits(ret.data,0,16);
  1000.  zWriteBits(ret.data,(unsigned)~0,16);
  1001.  ret.size=pos>>3;
  1002.  return ret;
  1003. }
  1004. bString bZibCompress(bString uncompressed,bString *dictionary){
  1005.  bString bs=bZibCompress__(uncompressed,dictionary);
  1006.  unsigned char dasendeistnah[]={1,0,0,255,255};
  1007.  for(unsigned i=0;i<sizeof(dasendeistnah);i++)bStringAddChar(&bs,dasendeistnah[i]);
  1008.  return bs;
  1009. }
  1010. void bZibCompressFile(char *fileUncompressed,char *fileCompressed){
  1011.  bFile in=bFileFrom(fileUncompressed,bFILE_READ),
  1012.   out=bFileFrom(fileCompressed,bFILE_OVERWRITE|bFILE_CREATE_IF_NOT_EXISTS);
  1013.  for(bString *uncompressed,compressed;;){
  1014.   if((uncompressed=bFileRead(&in,33333333))->size==0)break;
  1015.   compressed=bZibCompress__(*uncompressed,0);
  1016.   bFileWrite(&out,compressed.data,compressed.size);
  1017.   bStringFree(&compressed);
  1018.  }
  1019.  bFileWrite(&out,(unsigned char[5]){1,0,0,255,255},5);
  1020.  bFileFree(&out);
  1021.  bFileFree(&in);
  1022. }
  1023. ////////////////////////////THATS IT!!!!!!
  1024.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement