Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ///// PUT THESE IN A .H FILE!!!!
- typedef struct bString{unsigned size,capacity;unsigned char* data;}bString;
- #define zFAST_BITS 8 /* 0...15 */
- #define zCOMPRESSION_IN_A_HURRY 1
- bString bZibUncompress(bString compressed,bString *dictionary);
- int bZibUncompressFile(char *fileCompressed,char *fileUncompressed);
- bString bZibCompress(bString uncompressed,bString *dictionary);
- void bZibCompressFile(char *fileUncompressed,char *fileCompressed);
- //////THATS ALL!!! EASY, ISNT IT? NOW SKIP TO LINE 270 !!!!!
- #ifdef __POCC__
- #define bPELLES 1
- #elif defined(__clang__)
- #define bCLANG 1
- #elif defined(_MSC_VER)
- #define bMSVC 1
- #elif defined(__MINGW32__)
- #define bMINGW 1
- #elif defined(__GNUC__)
- #define bGCC 1
- #endif //PELLES||CLANG||MSVC||MINGW
- #if bPELLES+bCLANG+bMSVC+bMINGW+bGCC!=1
- #error error error error error error
- #endif
- #if defined(__ANDROID__)
- #define bANDROID 1
- #elif defined(_WIN32)
- #define bWINDOWS 1
- #elif defined(__APPLE__)
- #define bAPPLE 1
- #elif defined(__linux__)
- #define bLINUX 1
- #endif //ANDROID||WINDOWS||OSX||LINUX
- #if bANDROID+bWINDOWS+bAPPLE+bLINUX!=1
- #error error error %$#@$#@%#@#
- #endif
- #include <limits.h>
- #include <stdarg.h>
- #include <stdint.h>
- #include <string.h>
- #include <math.h>
- #ifdef bWINDOWS
- #define UNICODE
- #define OEMRESOURCE
- #include <winsock2.h>
- #include <windows.h>
- #else //bWINDOWS||!bWINDOWS
- #define _FILE_OFFSET_BITS 64
- #include <dirent.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <time.h>
- #include <utime.h>
- #include <stdio.h>
- #include <unistd.h>
- #endif //bWINDOWS||!bWINDOWS
- #ifdef bLINUX
- #include <langinfo.h>
- #endif
- #if !defined bPELLES && !defined bMSVC
- typedef uint32_t bUnaligned32 __attribute__((aligned(1),may_alias));
- #else
- typedef __unaligned uint32_t bUnaligned32;
- #endif
- #define ARRAY_EXTRA 3
- #define bMin(a,b) (((a)<(b))?(a):(b))
- #define bGrow(from) ((unsigned)(((from)*1.2)+(3<<2>>1)))
- #define break(x) {x;break;}
- #define bMax(a,b) (((a)>(b))?(a):(b))
- #define bSwap32(v) ((uint32_t)(((v)>>24)|((uint32_t)((v))<<24)|(((v)&16711680)>>8)|(((v)&65280)<<8)))
- #define bCollate(l,r) ((l)<(r)?-1:(l)>(r)?1:0)
- #define bAddU32Ovflo(a,b) ((a)>UINT32_MAX-(b))
- #define bAssert(...)
- #define bAssertMsg(...)
- #define bLog(...)
- /////////////////////////////////////////////////////////////////////////////////////////////////////////
- #define bIndexLeft(i) ((unsigned)((2*(i))+1))
- #define bIndexRight(i) ((unsigned)((2*(i))+2))
- #define bIndexParent(i) ((unsigned)(((i)-1)/2))
- #define bIndexValid(pos,level) (((unsigned)(pos))<(unsigned)((1<<(level))-1))
- #define bIndexLevelStart(level) ((unsigned)((1<<((level)-1))-1))
- #define bIndexLevelEnd(level) (bIndexLevelStart((level)+1)-1)
- #define bIndexParentIsRight(i) ((i)&1)
- #define bIndexParentIsLeft(i) (((i)+1)&1)
- #define bDECLARE_INDEX(name,type)\
- typedef struct name{type *data;unsigned char *stat,levels;unsigned items;}name;\
- void name##Add(name *index,type item);\
- unsigned name##Next(name index,unsigned pos);\
- unsigned name##Prev(name index,unsigned pos);\
- unsigned name##Min(name index);\
- unsigned name##Max(name index);\
- unsigned name##FindIndex(name index,type item,int lowerbound);\
- int name##Delete(name *index,unsigned pos,int hideOnly);\
- void name##Free(name *idx);\
- void name##Reindex(name *idx);
- #define bDEFINE_INDEX(name,type,collator,freefunc)\
- void name##Move2(name *index,unsigned from,unsigned to,unsigned count){\
- memcpy(index->data+to,index->data+from,count*sizeof(type));\
- memcpy(index->stat+to,index->stat+from,count*sizeof(unsigned char));\
- memset(index->data+from,0,count*sizeof(type));\
- memset(index->stat+from,0,count*sizeof(unsigned char));\
- }\
- void name##Move(name *index,unsigned from,unsigned to,int baum){\
- if(!bIndexValid(from,index->levels)||!bIndexValid(to,index->levels))return;\
- unsigned count=1;\
- if(!baum){(name##Move2(index,from,to,count));return;}\
- if(to>from){\
- while(bIndexValid(bIndexLeft(to),index->levels))count*=2,from=bIndexLeft(from),to=bIndexLeft(to);\
- while(count)name##Move2(index,from,to,count),count/=2,from=bIndexParent(from),to=bIndexParent(to);\
- }else while(bIndexValid(from,index->levels))name##Move2(index,from,to,count),count*=2,\
- to=bIndexLeft(to),from=bIndexLeft(from);\
- }\
- void name##Rotate(name *index,unsigned pos,signed char r1,signed char r2){\
- unsigned p1=r1==1?bIndexRight(pos):bIndexLeft(pos),p2=r2==1?bIndexRight(p1):bIndexLeft(p1),\
- o1=r1==1?p1-1:p1+1;\
- unsigned char s=(unsigned char)7,b1=index->stat[p1]&s,b2=index->stat[p2]&s;\
- name##Move(index,o1,r1==1?bIndexLeft(o1):bIndexRight(o1),1);\
- name##Move(index,pos,o1,0);\
- name##Move(index,r1==r2?p1:p2,pos,0);\
- name##Move(index,r1==1?bIndexLeft(r1==r2?p1:p2):bIndexRight(r1==r2?p1:p2),r1==1?bIndexRight(o1):\
- bIndexLeft(o1),1);\
- name##Move(index,r1==r2?p2:r2==1?bIndexLeft(p2):bIndexRight(p2),r1==r2?p1:r2==1?bIndexRight(p1):\
- bIndexLeft(p1),1);\
- index->stat[pos]=(unsigned char)((index->stat[pos]&240)|((index->stat[pos]&8)|(b1==5?r1==1?4:6:5)));\
- index->stat[o1]=(unsigned char)((index->stat[o1]&240)|\
- ((index->stat[o1]&8)|(b1==5?r1==1?6:4:r1!=r2?b1==4&&b2==6?4:b1==6&&b2==4?6:5:5)));\
- if(r1!=r2)index->stat[p1]=(uint8_t)((index->stat[p1]&240)|((index->stat[p1]&8)|(b1==b2?r1+5:5)));\
- }\
- unsigned name##Prev(name index,unsigned pos){\
- for(unsigned r=bIndexLeft(pos);pos<(unsigned)((1<<index.levels)-1);){\
- if(bIndexValid(r,index.levels)){while(bIndexValid((r=bIndexRight(r)),index.levels));}\
- else{while(r>0&&(bIndexParentIsRight(r)))r=bIndexParent(r);}\
- if(r==0)return (unsigned)-1;\
- if((index.stat[pos=bIndexParent(r)]&8)!=0)return pos;\
- else r=bIndexLeft(pos);\
- }\
- return (unsigned)-1;\
- }\
- unsigned name##Next(name index,unsigned pos){\
- for(unsigned r=bIndexRight(pos);pos<(unsigned)((1<<index.levels)-1);){\
- if(bIndexValid(r,index.levels)){while(bIndexValid((r=bIndexLeft(r)),index.levels));}\
- else {while(r>0&&(bIndexParentIsLeft(r)))r=bIndexParent(r);}\
- if(r==0)return (unsigned)-1;\
- if((index.stat[pos=bIndexParent(r)]&8)!=0)return pos;\
- else r=bIndexRight(pos);\
- }\
- return (unsigned)-1;\
- }\
- unsigned name##Min(name index){\
- unsigned m=(unsigned)-1,min=index.levels?bIndexLevelStart(index.levels):m;\
- return ((min==m)||((index.stat[min]&8)!=0))?min:name##Next(index,min);\
- }\
- unsigned name##Max(name index){\
- unsigned m=(unsigned)-1,max=bIndexLevelEnd(index.levels);\
- return ((max==m)||((index.stat[max]&8)!=0))?max:name##Prev(index,max);\
- }\
- unsigned name##FindIndex(name index,type item,int lowerbound){\
- unsigned pos=0,m=(unsigned)-1,p=m,found=0;\
- signed col;\
- while(bIndexValid(pos,index.levels)){\
- if((col=collator(&item,&index.data[pos]))<0)pos=bIndexLeft(pos);\
- else if(col>0)pos=bIndexRight(pos);\
- else break(found=1);\
- }\
- if(lowerbound){\
- pos=found?((index.stat[pos]&8)==0)?name##Next(index,pos):pos:name##Next(index,bIndexParent(p=pos));\
- if(!found&&bIndexParentIsRight(p))return\
- (bIndexValid(pos,index.levels)&&(index.stat[pos]&8))?name##Prev(index,pos):name##Next(index,pos);\
- }\
- return bIndexValid(pos,index.levels)&&(index.stat[pos]&8)?pos:m;\
- }\
- void name##Add(name *index,type item){\
- if(index->items==(unsigned)-2)return;\
- signed char route[33];\
- unsigned pos=0,routepos=0,s;\
- signed col;\
- while(bIndexValid(pos,index->levels)){\
- if(index->stat[pos]==0)break;\
- else if((col=collator(&item,&index->data[pos]))<0)route[routepos++]=-1,pos=bIndexLeft(pos);\
- else if(col>0)route[routepos++]=1,pos=bIndexRight(pos);\
- else route[routepos++]=1,pos=bIndexRight(pos);\
- }\
- if(!bIndexValid(pos,index->levels)){\
- unsigned newlevels=index->levels+1,a,b;\
- void *r1=bRealloc(index->data,(bIndexLevelEnd(newlevels)+1)*sizeof(type));\
- void *r2=bRealloc(index->stat,(bIndexLevelEnd(newlevels)+1)*sizeof(unsigned char));\
- if(!r1||!r2){bFree(r1),bFree(r2);index->items=(unsigned)-2;return;}\
- ++index->levels,a=bIndexLevelStart(index->levels),b=index->levels-1;\
- memset(((type*)(index->data=r1))+a,0,((uint64_t)1<<(b))*sizeof(type));\
- memset(((char*)(index->stat=r2))+a,0,((uint64_t)1<<(b))*sizeof(unsigned char));\
- }\
- ++index->items,index->data[pos]=item,index->stat[pos]=8|5;\
- while(routepos--){\
- s=index->stat[(pos=bIndexParent(pos))]+=route[routepos];\
- if((s&7)==5)break;\
- if((s&3)==3)break(name##Rotate(index,pos,route[routepos],route[routepos+1]));\
- }\
- }\
- void name##FreeItems(name *idx){\
- if(idx->levels&&freefunc!=bFreeDefault)\
- for(unsigned i=0;i<=bIndexLevelEnd(idx->levels);i++)if(idx->stat[i])freefunc(&idx->data[i]);\
- }\
- void name##Free(name *idx){\
- name##FreeItems(idx);\
- bFree(idx->data),bFree(idx->stat),memset(idx,0,sizeof(*idx));\
- }\
- void name##SplitMoveBaum(unsigned pos,name *from,name *to){\
- unsigned count=1;\
- while(bIndexValid(pos,from->levels)){\
- for(unsigned i=0;i<count;i++)if(from->stat[pos+i]&8)name##Add(to,from->data[pos+i]);\
- count*=2,pos=bIndexLeft(pos);\
- }\
- }
- #define bHeapParent(i) ((i)/2)
- #define bHeapLeft(i) (2*(i))
- #define bHeapRight(i) (2*(i)+1)
- #define bDECLARE_HEAP(name,type)\
- typedef struct name{unsigned size,capacity;type *data;}name;\
- void name##Reserve(name *heap,unsigned size);\
- void name##Free(name *heap);\
- void name##Add(name *heap,type item);\
- type name##Extract(name *heap);\
- void name##Delete(name *heap,unsigned index);\
- type name##FindLast(name *heap);\
- unsigned name##FindIndex(name *heap,type item);\
- type name##Peek(name *heap);\
- void name##Set(name *heap,unsigned index,type new);\
- void name##InsertAll(name *heap,type *new,unsigned count);\
- name name##Copy(name *heap);
- #define bDEFINE_HEAP(name,type,collator)\
- void name##Reserve(name *heap,unsigned size){\
- if(heap->capacity>=size)return;\
- if((heap->data=bRealloc(heap->data,(heap->capacity=bGrow(size+3))*sizeof(type)))==0)\
- heap->capacity=(unsigned)-2;\
- }\
- void name##Free(name *heap){\
- bFree(heap->data);\
- memset(heap,0,sizeof(*heap));\
- }\
- void name##Add(name *heap,type item){\
- unsigned i=++heap->size;\
- name##Reserve(heap,i+1);\
- if(heap->capacity==(unsigned)-2)return;\
- for(;i!=1&&collator(&item,&heap->data[bHeapParent(i)])<0;\
- heap->data[i]=heap->data[bHeapParent(i)],i=bHeapParent(i));\
- heap->data[i]=item;\
- }\
- void name##Heapify(name *heap,unsigned from){\
- unsigned i=from,m,l,r;\
- for(type t;;){\
- m=i,l=bHeapLeft(i),r=bHeapRight(i);\
- if(l<=heap->size&&collator(&heap->data[l],&heap->data[m])<0)m=l;\
- if(r<=heap->size&&collator(&heap->data[r],&heap->data[m])<0)m=r;\
- if(m!=i)t=heap->data[i],heap->data[i]=heap->data[m],heap->data[m]=t,i=m;\
- else break;\
- }\
- }\
- type name##Extract(name *heap){\
- bAssert(heap->size);\
- type ret=heap->data[1];\
- heap->data[1]=heap->data[heap->size--];\
- name##Heapify(heap,1);\
- return ret;\
- }
- void bFreeDefault(void *v){}
- /////////////////////////////////////////////////////////////////////////////////////////////////////////
- typedef uint32_t zBitCentrifuge;
- uint16_t m[]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535};
- typedef struct zHuffTable{
- #if zFAST_BITS
- uint16_t litindex[1<<zFAST_BITS],distindex[1<<zFAST_BITS],lenindex[1<<zFAST_BITS];
- #endif
- uint16_t litcode[288],litlens[288],litaccum[288],litsize[15],litoffs[15],littop[15];
- uint16_t distcode[32],distlens[32],distaccum[32],distsize[15],distoffs[15],disttop[15];
- uint16_t lencode[19],lenlens[19],lenaccum[19],lensize[15],lenoffs[15],lentop[15],ok;
- }zHuffTable;
- #define zHuffTableAdd(t_,p,len_,code_){if((len_))t_.p##accum[t_.p##offs[0]]=(code_),\
- t_.p##lens[t_.p##offs[0]]=(len_),t_.p##size[(len_)-1]++,t_.p##offs[0]++;}
- #if !zFAST_BITS
- #define zHuffTableIndex(t,p)
- #else
- #define zHuffTableIndex(t_,p) for(i=0;i<zFAST_BITS;i++)for(j=0,len=i+1;j<t_.p##size[i];j++)\
- for(t_.p##lens[t_.p##offs[i]+j]=len,k=0,l=1<<(zFAST_BITS-len),m=zReverseBits(t_.p##top[i]+j\
- ,len),n=t_.p##offs[i]+j;k<l;k++)t_.p##index[(k<<len)|m]=n;
- #endif
- #define zHuffTableLockNoIndex__(t_,p) uint16_t c=0,b=1,i,j,offs_,k,l,len,m,n=(uint16_t)-1;\
- 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);\
- 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--;\
- for(t_.p##offs[0]=0,i=1,offs_=0;i<15;i++)t_.p##offs[i]=(offs_+=t_.p##size[i-1]);\
- for(i=0;i<15;i++)for(k=0,l=0;k<t_.p##size[i];l++)if(t_.p##lens[l]==i+1)\
- t_.p##code[(k++,++n)]=t_.p##accum[l];
- #define zHuffTableLock(t_,p) {zHuffTableLockNoIndex__(t_,p);zHuffTableIndex(t_,p);}
- #define zHuffTableLockNoIndex(t_,p) {zHuffTableLockNoIndex__(t_,p);}
- #define zHuffTableGetCode(t_,p,len_,code_) (code_-t_.p##top[len_-1]<t_.p##size[len_-1]?\
- t_.p##code[code_-t_.p##top[len_-1]+t_.p##offs[len_-1]]:(uint16_t)-1)
- #define zHuffTablePrint_(t_,p) {for(uint16_t i=0;i<15;i++){\
- if(t_.p##size[i])bLog("***"#p"*** lens:%d,count:%d,top:%d",i+1,t_.p##size[i],t_.p##top[i]);\
- for(uint16_t code,j=0;j<=t_.p##size[i];j++){\
- if((code=zHuffTableGetCode(t_,p,i+1,j+t_.p##top[i]))==(uint16_t)-1)continue;\
- bString bs=bStringFromFormat("%c - %d - (%d) ",\
- code>32&&code<127?(char)code:(char)'_',code,j+t_.p##top[i]),bin={0};\
- bStringAddBinary(&bin,j+t_.p##top[i],16);\
- for(uint16_t k=0;k<=i;k++)bStringAddChar(&bs,bin.data[bin.size-1-k]);\
- bLog("%s",bs.data);bStringFree(&bin),bStringFree(&bs);}}}
- #define zHuffTablePrint(t_) zHuffTablePrint_(t_,len) zHuffTablePrint_(t_,dist) zHuffTablePrint_(t_,lit)
- #define zFetchBits(n) {if(avail<n){if((pos-=avail)+n>maxpos)goto catch;\
- read=(*(bUnaligned32*)(in+(pos>>3)))>>(pos&7),pos+=(avail=(uint8_t)(32-(pos&7)));}}
- #define zReadBits(n,out) zFetchBits(n);out=(uint16_t)(read&m[n]),avail-=n,read>>=n
- #define zReadBit(out) zFetchBits(1);out=read&1,avail--,read>>=1
- #define zWriteBits(out,num,n) for(bUnaligned32 *a=(uint32_t*)(out+(pos>>3)),b=pos&7,c=m[n];\
- a;pos+=n,*a=(*a&~(c<<b))|num<<b,a=0);
- #define zTableRun_1(p) {zFetchBits(zFAST_BITS);idx=t.p##index[read&((1<<zFAST_BITS)-1)],\
- l=t.p##lens[idx];if(!l)goto delete;sym=t.p##code[idx],read>>=l,avail-=l;}
- #define zTableRun_2(p) {uint16_t accum=0,j=1,ac0,q=0,b;zReadBits(p##min-1,ac0);\
- while(q<(p##min-1))accum|=(((ac0&(1<<(q)))>>(q))<<(p##min-q-2)),j++,q++;\
- for(;j<=15;j++){zReadBit(b);accum=(accum<<1)|b;\
- if((sym=zHuffTableGetCode(t,p,j,accum))!=(uint16_t)-1)break;}\
- if(sym==(uint16_t)-1)goto delete;}
- #define zTableRun_3(p) zFetchBits(zFAST_BITS);idx=t.p##index[read&((1<<zFAST_BITS)-1)],l=t.p##lens\
- [idx];if(idx){sym=t.p##code[idx],read>>=l,avail-=l;}else zTableRun_2(p)
- #if zFAST_BITS==15
- #define zTableRun zTableRun_1
- #elif zFAST_BITS
- #define zTableRun zTableRun_3
- #else
- #define zTableRun zTableRun_2
- #endif
- #define zHuffTableMakeLens(p,go) {go:for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)if(p##freqs[i])\
- zHeapFreqToLenAdd(&ftl,(zFreqToLen){.freq=p##freqs[i],.len[0]=1});\
- for(uint16_t min_=(uint16_t)-1;ftl.size>1;){\
- zFreqToLen a=zHeapFreqToLenExtract(&ftl),b=zHeapFreqToLenExtract(&ftl);\
- if(a.len[15]+b.len[15]>0){\
- for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)\
- if(p##freqs[i]&&(min_==(uint16_t)-1||p##freqs[i]<p##freqs[min_]))min_=i;\
- p##freqs[min_]++;zHeapFreqToLenFree(&ftl);goto go;}\
- zFreqToLen new={.freq=a.freq+b.freq};\
- for(unsigned i=14;i<15;i--)new.len[i+1]+=a.len[i]+b.len[i];\
- zHeapFreqToLenAdd(&ftl,new);}\
- zFreqToLen f=zHeapFreqToLenExtract(&ftl);\
- for(uint16_t i=0;i<sizeof(t.p##code)/2;i++)\
- if(p##freqs[i])zHeapLitToFreqByFreqAdd(&l2ff,(zLitToFreq){.lit=i,.freq=p##freqs[i]});\
- for(uint16_t len=1,j;len<=15;len++){\
- for(l2fl.size=0,j=0;j<f.len[len];j++)zHeapLitToFreqByLitAdd(&l2fl,zHeapLitToFreqByFreqExtract(&l2ff));\
- while(l2fl.size)zHuffTableAdd(t,p,len,zHeapLitToFreqByLitExtract(&l2fl).lit);\
- }\
- zHuffTableLockNoIndex(t,p);\
- memset(t.p##lens,0,sizeof(t.p##lens));memset(p##sym,0,sizeof(p##sym));\
- for(uint16_t i=0;i<15;i++){\
- for(uint16_t j=0;j<t.p##size[i];j++){\
- p##sym[t.p##code[j+t.p##offs[i]]]=zReverseBits(j+t.p##top[i],i+1);\
- t.p##lens[t.p##code[j+t.p##offs[i]]]=i+1;}}\
- memcpy(t.p##code,p##sym,sizeof(p##sym));}
- #define zHuffTablePrintLens_(t_,p)\
- for(uint16_t i=0;i<sizeof(t.p##lens)/2;i++){\
- if(!t.p##lens[i])continue;\
- bString s=bStringFromFormat(""#p"sym:%c %d len:%d num:%d ",\
- i>32&&i<127?(char)i:(char)'_',i,t.p##lens[i],t.p##code[i]);\
- bStringAddBinary(&s,t.p##code[i],t.p##lens[i]);\
- bLog("%s",s.data);bStringFree(&s);}
- #define zHuffTablePrintLens(t_) zHuffTablePrintLens_(t_,lit) zHuffTablePrintLens_(t_,dist)
- #define zLogOut for(uint32_t i=0;i<s1->size;i++){\
- if(out[i]&4294901760u){\
- int ln=out[i]&65535,dst=(out[i]&4294901760u)>>16,dict=!(i-dst<s1->size);\
- bString s=bStringFrom(!dict?s1->data+(i-dst):s2->data+(i-dst+s2->size),ln);\
- bLog("%d: %d,%d (ln,dst) (%s) (%c)%s",i,ln,dst,s.data,s1->data[i],dict?" -->dict<--":"");\
- bStringFree(&s);\
- }else if(out[i]&512)bLog("%d: %c (char %d)",i,(char)(out[i]&255),(int)out[i]&255);\
- else bLog("%d: (...) (%c) (val:%d)",i,s1->data[i],out[i]);}
- /////////////////////////////////////// NOW SKIP TO LINE 700 (ok, 701) !!!!!!!!!!
- uint8_t bHiBit(uint32_t n){
- if(n==0)return 0;
- #ifdef bMSVC
- DWORD ret=0;
- _BitScanReverse(&ret,n);
- return (uint8_t)ret;
- #elif 1
- return 31-__builtin_clz(n);
- #else
- unsigned ret=0;
- while(n>>=1)ret++;
- return (uint8_t)ret;
- #endif
- }
- void *bRealloc(void *memory,unsigned size){
- #ifdef bWINDOWS
- void *r=memory?HeapReAlloc(GetProcessHeap(),0,memory,size):HeapAlloc(GetProcessHeap(),0,size);
- #else
- void *r=realloc(memory,size);
- #endif
- return /*!r?++bOom,r:*/r;
- }
- void bFree(void *memory){
- #ifdef bWINDOWS
- HeapFree(GetProcessHeap(),0,memory);
- #else
- free(memory);
- #endif
- }
- int bStringSetCapacity(bString *bs,unsigned capacity){
- bAssert(capacity>=bs->size);
- void *r=bAddU32Ovflo(capacity,ARRAY_EXTRA)?0:bRealloc(bs->data,(bs->capacity=capacity)+ARRAY_EXTRA);
- return r?(memset((bs->data=(uint8_t*)r)+(bs->size),0,ARRAY_EXTRA)!=0):(bs->capacity=(unsigned)-2,0);
- }
- int bStringReserve(bString *bs,unsigned capacity){
- return capacity<=bs->capacity?1:bStringSetCapacity(bs,bGrow(capacity));
- }
- void bStringFree(bString *bs){
- if(bs->capacity!=(unsigned)-1)bFree(bs->data);
- memset(bs,0,sizeof(*bs));
- }
- unsigned bStrlen(char *str){
- return str?(unsigned)strlen(str):0;
- }
- bString bStringFrom(char *c,unsigned len){
- bString bs={0};
- bStringSetCapacity(&bs,len||!c?len:(len=(unsigned)bStrlen(c)));
- if(bs.capacity!=(unsigned)-2){
- if(c&&(bs.data&&len>0)&&bs.capacity>=len)memcpy(bs.data,c,len);
- if(len>0&&c)memset(bs.data+(bs.size=len),0,ARRAY_EXTRA);
- }
- return bs;
- }
- void bStringErase(bString *bs,unsigned from,unsigned count){
- if(count==(unsigned)-1||from+count>bs->size)count=bs->size-from;
- if(from+count<bs->size)memmove(bs->data+from,bs->data+from+count,bs->size-(from+count));
- memset(bs->data+(bs->size-=count),0,ARRAY_EXTRA);
- }
- void bStringInsert(bString *bs,char *c,unsigned len,unsigned pos){
- if(len==0&&c&&(len=(unsigned)strlen(c))==0)return;
- bStringReserve(bs,bs->size+len);
- if(bs->capacity==(unsigned)-2)return;
- if(pos>=bs->size)pos=bs->size;
- else memmove(bs->data+pos+len,bs->data+pos,bs->size-pos);
- memcpy(bs->data+pos,c,len);
- memset(&bs->data[bs->size=bs->size+len],0,ARRAY_EXTRA);
- }
- unsigned bStringCodepointAt(bString bs,unsigned pos){
- if(pos>=bs.size)return (unsigned)-1;
- uint32_t c=bSwap32(*(bUnaligned32*)(bs.data+pos));
- if((c&((unsigned)1<<31))==0)return (c&2130706432)>>24;
- else if((c&4034953344)==4034953344)return ((c&63)|((c&16128)>>2)|((c&4128768)>>4)|(c&117440512)>>6);
- else if((c&4034953216)==3766517760)return (((c&16128)>>8)|((c&4128768)>>10)|((c&251658240)>>12));
- else if((c&3770679296)==3229614080)return (((c&4128768)>>16)|((c&520093696)>>18));
- else return (unsigned)-1;
- }
- unsigned bStringNext(bString bs,unsigned pos,int reverse){
- while(reverse?--pos:++pos)if(pos>bs.size||(bs.data[pos]>>6)!=2)break;
- return pos;
- }
- bString bStringToUtf16(bString utf8){
- bString ret=bStringFrom(NULL,(utf8.size+4)*2);
- if(ret.capacity==(unsigned)-2)return ret;
- for(unsigned cp,i=0;i<utf8.size;i=bStringNext(utf8,i,0)){
- if((cp=bStringCodepointAt(utf8,i))<=65535){
- ret.data[ret.size++]=(unsigned char)cp;
- ret.data[ret.size++]=(unsigned char)((cp&65280)>>8);
- }else if(cp<1114112&&(cp-=65536)){
- ret.data[ret.size++]=(unsigned char)((cp&261120)>>10);
- ret.data[ret.size++]=(unsigned char)((55296|((cp>>10&768)))>>8);
- ret.data[ret.size++]=(unsigned char)(cp&255);
- ret.data[ret.size++]=(unsigned char)((56320|(cp&768))>>8);
- }
- }
- return ret;
- }
- void bStringAdd(bString *bs,char *c,unsigned len){
- if(((c&&len==0)?(len=(unsigned)strlen(c)):len)==0)return;
- bStringReserve(bs,bs->size+len);
- if(!len||bs->capacity==(unsigned)-2)return;
- memcpy(bs->data+bs->size,c,len);
- memset(bs->data+(bs->size+=len),0,ARRAY_EXTRA);
- }
- void bStringAddChar(bString *bs,char c){
- bStringReserve(bs,bs->size+1);
- if(bs->capacity==(unsigned)-2)return;
- bs->data[bs->size++]=(unsigned char)c;
- memset(bs->data+bs->size,0,ARRAY_EXTRA);
- }
- 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,
- 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
- ,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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 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,
- 247,248,249,250,251,252,253,254,255};
- #define bLower(x) (bUpperToLower[(unsigned char)(x)])
- unsigned bStringFindChar(bString bs,char c,unsigned from,int ignoreCase,int reverse){
- if(ignoreCase)c=bLower(c);
- if(reverse){
- for(unsigned i=bMin(from,bs.size-1);i<bs.size;i--)
- if((ignoreCase?(bLower(bs.data[i])):(bs.data[i]))==c)return i;
- return (unsigned)-1;
- }
- unsigned ret=(unsigned)-1;
- if(ignoreCase){
- for(unsigned i=from,s;i<bs.size&&ret==-1;i+=4){
- s=*((bUnaligned32*)((char*)bs.data+i));
- if(bLower(((s&255)))==c)ret=i;
- else if(bLower(((s&65280)>>8))==c)ret=i+1;
- else if(bLower(((s&16711680)>>16))==c)ret=i+2;
- else if(bLower(((s&4278190080)>>24))==c)ret=i+3;
- }
- }else{
- for(unsigned i=from,s,cc=(unsigned)c;i<bs.size&&ret==-1;i+=4){
- s=*((bUnaligned32*)((char*)bs.data+i));
- if(((s&255))==cc)ret=i;
- else if(((s&65280)>>8)==cc)ret=i+1;
- else if(((s&16711680)>>16)==cc)ret=i+2;
- else if(((s&4278190080)>>24)==cc)ret=i+3;
- }
- }
- return ret<bs.size?ret:(unsigned)-1;
- }
- #define bFILE_READ 1
- #define bFILE_WRITE 2
- #define bFILE_CREATE_IF_NOT_EXISTS 4
- #define bFILE_DELETE_ON_CLOSE 8
- #define bFILE_WINDOWS_LONGNAME 16
- #define bFILE_OVERWRITE (bFILE_WRITE|32)
- #define bFILE_APPEND 64
- #if defined bWINDOWS
- typedef struct bFile{bString name,name16,cache,line;HANDLE h;int flags,error;unsigned pos,z;}bFile;
- #else
- typedef struct bFile{bString name,cache,line;int fd,flags,error;unsigned pos,z;}bFile;
- #endif
- void bFileUnfillCache(bFile *f){
- if(f->cache.size==0)return;
- void bFileSetCursor(bFile *f,uint64_t pos);
- uint64_t bFileGetCursor(bFile *f);
- uint64_t topos=bFileGetCursor(f);
- bStringFree(&f->cache),f->pos=0,f->z=0;
- bFileSetCursor(f,topos);
- }
- bFile bFileFrom(char *name,int flags){
- //if(!name||!*name)return bFileTempFile();
- #ifdef bWINDOWS
- bString fn=bStringFrom(name,0),fn16=bStringToUtf16(fn),s;
- if(flags&bFILE_WINDOWS_LONGNAME)bStringInsert(&fn16,(char*)L"\\\\?\\",8,0);
- DWORD acc=0,share=FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- open=(flags&bFILE_CREATE_IF_NOT_EXISTS)?OPEN_ALWAYS:OPEN_EXISTING,
- attr=(flags&bFILE_DELETE_ON_CLOSE)?FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE:0,i=0,d;
- if(fn16.size>4&&fn16.data[fn16.size-2]!='\\'
- &&((d=GetFileAttributesW((wchar_t*)fn16.data))!=(DWORD)-1)&&d&FILE_ATTRIBUTE_DIRECTORY)
- bStringAdd(&fn16,(char*)L"\\",2),bStringAddChar(&fn,'/');
- if(flags&bFILE_READ)acc|=GENERIC_READ;
- if(flags&bFILE_WRITE)acc|=GENERIC_WRITE;
- if(flags&bFILE_CREATE_IF_NOT_EXISTS)
- for(unsigned i=bStringFindChar(fn16,'\\',0,0,0);i!=(unsigned)-1;i=bStringFindChar(fn16,'\\',i+1,0,0))
- CreateDirectoryW((LPCWSTR)(s=bStringFrom((char*)fn16.data,i)).data,0),bStringFree(&s);
- HANDLE h=0;
- for(;i<11;i++){
- if((h=CreateFileW((wchar_t*)fn16.data,acc,share,NULL,open,attr|FILE_ATTRIBUTE_NORMAL,NULL))
- !=INVALID_HANDLE_VALUE)break;
- if((d=GetLastError())==ERROR_SHARED_POLICY||d==ERROR_LOCK_VIOLATION||d==ERROR_DEV_NOT_EXIST||
- d==ERROR_NETNAME_DELETED||d==ERROR_SEM_TIMEOUT||d==ERROR_NETWORK_UNREACHABLE)/*bSleep(333)*/;
- else break;
- }
- bFile ret=(bFile){.name=fn,.name16=fn16,.h=h,.flags=flags,
- .error=(h==0||h==INVALID_HANDLE_VALUE)?-1/*bErrno()*/:0};
- #else
- bString fn=bStringFrom(name,0),s;
- int of=((flags&(bFILE_READ|bFILE_WRITE))==(bFILE_READ|bFILE_WRITE))?O_RDWR:flags&bFILE_WRITE?O_WRONLY:
- O_RDONLY,cr=0666,fd=0,i;
- if(fn.data[fn.size-1]!=bFILE_DIRSEP){
- bFileinfo info=bFileinfoFrom((char*)fn.data);
- if(info.type==bFILEINFO_TYPE_DIR)bStringAddChar(&fn,bFILE_DIRSEP);
- bFileinfoFree(&info);
- }
- if(flags&bFILE_CREATE_IF_NOT_EXISTS)
- for(of|=O_CREAT,i=(signed)bStringFindChar(fn,'/',1,0,0);i!=-1;i=bStringFindChar(fn,'/',i+1,0,0))
- mkdir((char*)(s=bStringFrom((char*)fn.data,(unsigned)i)).data,0777),bStringFree(&s);
- if(fn.data[fn.size-1]==bFILE_DIRSEP)cr=0777,of=O_DIRECTORY;
- bArrayInt fds={0};
- for(int i=0;i<11;i++){
- if((fd=open((char*)fn.data,of,cr))>2)break;
- bArrayIntAdd(&fds,fd);
- if(errno!=EINTR&&fd==-1)break;
- bSleep(111);
- }
- for(unsigned i=0;i<fds.size;i++)close(fds.data[i]);
- bArrayIntFree(&fds);
- bFile ret=(bFile){.name=fn,.fd=fd,.flags=flags,.error=fd>2?0:bErrno()};
- #endif
- //if((flags&bFILE_OVERWRITE)==bFILE_OVERWRITE)bFileSetSize(&ret,0);
- //else if(flags&bFILE_APPEND)bFileSetCursor(&ret,bFileGetSize(&ret));
- return ret;
- }
- void bFileFree(bFile *f){
- //if(f->flags&bFILE_DELETE_ON_CLOSE)bFileDelete(f,NULL);
- int err=0;
- #ifdef bWINDOWS
- if(CloseHandle(f->h)==0)err=(int)GetLastError();
- bStringFree(&f->name16);
- #else
- while(close(f->fd)==-1)if(errno!=EINTR)break(err=errno);
- #endif
- bStringFree(&f->name);
- bStringFree(&f->cache);
- bStringFree(&f->line);
- memset(f,0,sizeof(bFile));
- f->error=err;
- }
- void bFileSetCursor(bFile *f,uint64_t pos){
- bFileUnfillCache(f);
- #ifdef bWINDOWS
- LARGE_INTEGER ll={.QuadPart=pos};
- if(ll.QuadPart<0)ll.QuadPart=0;
- if(!SetFilePointerEx(f->h,ll,NULL,FILE_BEGIN))f->error=(int)GetLastError();
- #else
- if(lseek(f->fd,pos,SEEK_SET)==-1)f->error=errno;
- #endif
- }
- uint64_t bFileGetCursor(bFile *f){
- #ifdef bWINDOWS
- FlushFileBuffers(NULL);
- LARGE_INTEGER ret={0},ll={0};
- if(!SetFilePointerEx(f->h,ll,&ret,FILE_CURRENT))f->error=(int)GetLastError();
- return (uint64_t)(ret.QuadPart-f->cache.size+f->pos);
- #else
- uint64_t ret=(uint64_t)lseek(f->fd,0,SEEK_CUR);
- return ret==-1?f->error=errno,(uint64_t)0:(ret-f->cache.size+f->pos);
- #endif
- }
- #define bFILE_CACHESIZE 4194304
- void bFileInitCache(bFile *f){
- if(f->z)memcpy(f->cache.data+f->pos,&f->z,3),f->z=0;
- }
- void bFileFillCache(bFile *f,unsigned size){
- bFileInitCache(f);
- if(f->cache.size-f->pos==0)f->cache.size=0,f->pos=0;
- if(size<(f->cache.size-f->pos))return;
- if(f->pos<f->cache.size)memmove(f->cache.data,f->cache.data+f->pos,f->cache.size-f->pos),
- f->cache.size-=f->pos,f->pos=0;
- if(size<bFILE_CACHESIZE)size=bFILE_CACHESIZE;
- bStringReserve(&f->cache,f->cache.size+size+3);
- #ifdef bWINDOWS
- while(size>0){
- DWORD read=0,error;
- BOOL r=ReadFile(f->h,(LPVOID)(f->cache.data+f->cache.size),(DWORD)(bMin(size,bFILE_CACHESIZE)),&read,0);
- if(r&&read)size-=read,f->cache.size+=read;
- else if(r&&!read)break;
- else if((error=GetLastError())==ERROR_HANDLE_EOF)break;
- else break(f->error=(int)error);
- }
- #else
- while(size>0){
- ssize_t r=read(f->fd,f->cache.data+f->cache.size,(size_t)(bMin(size,bFILE_CACHESIZE)));
- if(r==-1){
- if(errno==EINTR)continue;
- break(f->error=errno);
- }
- size-=r,f->cache.size+=r;
- if(r==0)break;
- }
- #endif
- }
- bString *bFileRead(bFile *f,unsigned len){
- bFileFillCache(f,len);
- if(f->cache.size==0)return bStringFree(&f->line),&f->line;
- len=bMin(f->cache.size-f->pos,len);
- memcpy(&f->z,f->cache.data+f->pos+len,3);
- memset(f->cache.data+f->pos+len,0,3);
- f->line=(bString){.data=f->cache.data+f->pos,.size=len,.capacity=(unsigned)-1};
- return f->pos+=len,&f->line;
- }
- uint32_t bFileReadUint32(bFile *f){
- bFileFillCache(f,sizeof(uint32_t));
- if(f->pos+sizeof(uint32_t)>f->cache.size)return 0;
- uint32_t ret=*(bUnaligned32*)((char*)f->cache.data+f->pos);
- f->pos+=sizeof(uint32_t);
- return ret;
- }
- void bFileWrite(bFile *f,void *data,int64_t len){
- bFileUnfillCache(f);
- unsigned write0=0;
- #ifdef bWINDOWS
- while(len>0){
- DWORD written=0;
- if(WriteFile(f->h,data,(DWORD)(bMin(len,65535)),&written,0)==0)break(f->error=(int)GetLastError());
- len-=(int)written,data=(((char*)data)+written);
- if(!written)if(++write0>11)break(f->error=(unsigned)-1);
- }
- #else
- while(len>0){
- ssize_t written=write(f->fd,data,(size_t)bMin(len,65535));
- if(written==-1){
- if(errno==EINTR)continue;
- else break(f->error=errno);
- }
- len-=written,data+=written;
- if(!written&&++write0>11)break(f->error=(unsigned)-1);
- }
- #endif
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////
- uint16_t zReverseBits(uint16_t num,uint8_t size){
- uint16_t ret=0;
- while(size--)ret=(ret<<1)|num&1,num>>=1;
- return ret;
- }
- uint16_t zDistToCode(uint32_t distance/*3...32768*/,uint16_t *extra,uint16_t *extralen){
- if(distance<3)return (*extra)=0,(*extralen)=0,distance-1;
- uint16_t hi=bHiBit(distance-1),code=hi*2;
- (*extralen)=hi-1,(*extra)=((1<<(hi))+1);
- if((distance-1)&(1<<(hi-1)))(code)++,(*extra)+=(1<<(hi-1));
- return (*extra)=distance-*extra,code;
- }
- uint16_t zLenToCode(uint16_t len/*3...284*/,uint16_t *extra,uint16_t *extralen){
- bAssert(len>=3&&len<=284);
- uint16_t e=len<7?0:bMin(5,(bHiBit(len-3)-2)&7),o=1<<(e+2)|3;
- return (*extralen)=e,(*extra)=(len-o)%(1<<e),e?(((len-o)/((1<<e)))+((e*4)+5|(1<<8))):len+254;
- }
- uint16_t zCodeToLen(uint16_t code,uint16_t *extra){
- uint16_t c=code,e=(((c&63)-1)>>2)-1,len=0;
- if((1<<(e&7))&192)e=0;
- if(e){
- while((c&=31)>8)c-=4;
- len=((c-1)<<e)|3;
- if(e==1&&(c-1)&1)len+=2;
- }else len=c==285?258:(c&31)+2;
- return (*extra)=e,len;
- }
- int bZibUncompress__(bString *ret,bString compressed,bString *dictionary,uint32_t pos,uint32_t *endpos){
- zBitCentrifuge read=0;
- uint32_t maxpos=compressed.size<<3,lastpos;
- uint16_t final,metod,hlit,hdist,hclen,i,sym=0,idx,l,len;
- uint8_t *in=compressed.data,lenmin,litmin,distmin,avail=0,lenz[320];
- for(zHuffTable t={0};;){
- lastpos=ret->size;
- zReadBits(3,i);
- if(final=i&1,(metod=i>>1)==2){
- zReadBits(14,i);
- hlit=(i&31)+257,hdist=((i&992)>>5)+1,hclen=((i&15360)>>10)+4;
- memset(&t,0,sizeof(t));
- 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};
- for(i=0;i<hclen;i++){zReadBits(3,len);hclens[hclenordr[i]]=len;}
- for(i=0;i<19;i++)zHuffTableAdd(t,len,hclens[i],i);
- zHuffTableLock(t,len);
- for(lenmin=1;!t.lensize[lenmin-1]&&lenmin<9;lenmin++);
- memset(lenz,0,320);
- for(uint16_t i=0,j,prev=0,rep;i<hlit+hdist;i++){
- zTableRun(len);
- if(sym<16)lenz[i]=(prev=sym);
- else if(sym==16){zReadBits(2,rep);rep+=3;while(rep--)lenz[i++]=prev;i--;}
- else if(sym==17){zReadBits(3,j);i+=j+2;}
- else if(sym==18){zReadBits(7,j);i+=j+10;}
- }
- for(i=0;i<hlit;i++)zHuffTableAdd(t,lit,lenz[i],i);
- for(i=hlit;i<hlit+hdist;i++)zHuffTableAdd(t,dist,lenz[i],i-hlit);
- zHuffTableLock(t,lit);
- zHuffTableLock(t,dist);
- if(t.ok!=3)goto delete;
- for(litmin=1;!t.litsize[litmin-1]&&litmin<9;litmin++);
- for(distmin=1;!t.distsize[distmin-1]&&distmin<9;distmin++);
- }else if(metod==0){
- if(pos-=avail,read=0,avail=0,pos&7)pos=(((pos+7)>>3)<<3);
- uint32_t stored=(*(bUnaligned32*)((char*)in+(pos>>3)))&65535;
- if(pos+(stored<<3)>maxpos)goto catch;
- if(!bStringReserve(ret,ret->size+stored))return 0;
- memcpy(ret->data+ret->size,in+(4+(pos>>3)),stored);
- ret->size+=stored,pos+=32+(stored<<3),(*endpos)=pos-avail;
- if(final)break;
- else continue;
- }else{
- if(litmin=7,distmin=5,t.ok!=4){
- memset(&t,0,sizeof(t));
- for(i=0;i<=143;i++)zHuffTableAdd(t,lit,8,i);
- for(i=144;i<=255;i++)zHuffTableAdd(t,lit,9,i);
- for(i=256;i<=279;i++)zHuffTableAdd(t,lit,7,i);
- for(i=280;i<=287;i++)zHuffTableAdd(t,lit,8,i);
- for(i=0;i<=29;i++)zHuffTableAdd(t,dist,5,i);
- zHuffTableLock(t,lit);
- zHuffTableLock(t,dist);
- t.ok=4;
- }
- }
- for(;;){
- zTableRun(lit);
- if(sym<256){
- if(!bStringReserve(ret,ret->size+1))return 0;
- ret->data[ret->size++]=(char)sym;
- }else if(sym==256){
- break((*endpos)=pos-avail);
- }else if(sym>=257&&sym<=285){
- 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},
- 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};
- uint16_t l1=sym-(uint16_t)257,len=ln[l1],extra=ex[l1],dst,j;
- if(extra){zReadBits(extra,j);len+=j;}
- zTableRun(dist);
- extra=((sym/2)-1)+(sym>1?0:1),dst=sym>1?1+((2+(sym&1))<<extra):++sym;
- if(extra){zReadBits(extra,j);dst+=j;}
- if(!bStringReserve(ret,ret->size+len))return 0;
- if(dst>len&&dst+len<ret->size){
- memcpy(ret->data+ret->size,ret->data+ret->size-dst,len);
- ret->size+=len;
- }else while(len--){
- unsigned char *c=ret->size-dst<ret->size?ret->data+ret->size-dst:dictionary&&dictionary->size-dst+
- ret->size<dictionary->size?dictionary->data+dictionary->size-dst+ret->size:0;
- if(c)ret->data[ret->size++]=*c;
- else goto delete;
- }
- }else goto delete;
- }
- if(final)break;
- }
- if(ret->data)memset(ret->data+ret->size,0,ARRAY_EXTRA);
- if(0)delete:return bStringFree(ret),0;
- if(0)catch:return bStringErase(ret,lastpos,(unsigned)-1),0;
- return final;
- }
- bString bZibUncompress(bString compressed,bString *dictionary){
- bString ret=bStringFrom(0,bMax(1<<17,compressed.size*3));
- if(compressed.size<5||ret.capacity==(unsigned)-2)return ret;
- uint32_t header=*(bUnaligned32*)compressed.data,pos=(header&8207)==8200?48:
- ((!(header&7))&&(((header>>8)&255)!=(~(header>>24)&255)))?16:0,endpos=pos;
- if((header&65535)==35615&&compressed.size>10)
- if(pos=80,header&134217728){while(*(compressed.data+(pos>>3)))pos+=8;pos+=8;}
- bZibUncompress__(&ret,compressed,dictionary,pos,&endpos);
- return ret;
- }
- int bZibUncompressFile(char *fileCompressed,char *fileUncompressed){
- bString s1=bStringFrom(NULL,9876789),s2={0},*l=&s1,*r=&s2,*s;
- bFile in=bFileFrom(fileCompressed,bFILE_READ),
- out=bFileFrom(fileUncompressed,bFILE_OVERWRITE|bFILE_CREATE_IF_NOT_EXISTS);
- uint32_t header=bFileReadUint32(&in),pos=(header&8207)==8200?48:((!(header&7))&&(((header>>8)&255)!=
- (~(header>>24)&255)))?16:0,endpos=pos,lastend=endpos,final=0;
- bFileSetCursor(&in,0);
- for(bString *compressed;;){
- uint64_t cursor=bFileGetCursor(&in);
- if((compressed=bFileRead(&in,33333333))->size==0)break;
- final=bZibUncompress__(r,*compressed,l,pos,&endpos);
- bFileWrite(&out,r->data,r->size);
- if(lastend==endpos||r->capacity==(unsigned)-2)break;
- bFileSetCursor(&in,cursor+((lastend=endpos)>>3));
- if(s=l,l=r,(r=s)->size=0,pos=endpos&7,final)break;
- }
- return bFileFree(&out),bFileFree(&in),bStringFree(&s2),bStringFree(&s1),
- final&&in.error==0&&out.error==0;
- }
- typedef struct zFreqToLen{uint16_t freq,len[16];}zFreqToLen;
- typedef struct zLitToFreq{uint16_t lit,freq;}zLitToFreq;
- int zCollateFreq(zFreqToLen *a,zFreqToLen *b){return bCollate(a->freq,b->freq);}
- int zCollateLitToFreqByFreq(zLitToFreq *a,zLitToFreq *b){return bCollate(b->freq,a->freq);}
- int zCollateLitToFreqByLit(zLitToFreq *a,zLitToFreq *b){return bCollate(a->lit,b->lit);}
- bDECLARE_HEAP(zHeapFreqToLen,zFreqToLen);
- bDECLARE_HEAP(zHeapLitToFreqByFreq,zLitToFreq);
- bDECLARE_HEAP(zHeapLitToFreqByLit,zLitToFreq);
- bDEFINE_HEAP(zHeapFreqToLen,zFreqToLen,zCollateFreq);
- bDEFINE_HEAP(zHeapLitToFreqByFreq,zLitToFreq,zCollateLitToFreqByFreq);
- bDEFINE_HEAP(zHeapLitToFreqByLit,zLitToFreq,zCollateLitToFreqByLit);
- #if !zCOMPRESSION_IN_A_HURRY
- typedef struct zPos{uint32_t val,pos;}zPos;
- int zCollatePos(zPos *l,zPos *r){
- int col=bCollate(l->val,r->val);
- return col?col:bCollate(r->pos,l->pos);
- }
- bDECLARE_INDEX(zIndexPos,zPos);
- bDEFINE_INDEX(zIndexPos,zPos,zCollatePos,bFreeDefault);
- #endif
- #define zBLOCK_SIZE 32768 /* ...65535 */
- bString bZibCompress__(bString uncompressed,bString *dictionary){
- bString ret=bStringFrom(0,uncompressed.size);
- zHuffTable t;
- zHeapFreqToLen ftl={0};
- zHeapLitToFreqByFreq l2ff={0};
- zHeapLitToFreqByLit l2fl={0};
- uint16_t litfreqs[288]={0},distfreqs[32]={0},litsym[288],distsym[32],e,el,de,del;
- 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},
- {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};
- bString sleft={0},sright={0},*s1=&sleft,*s2=&sright;
- #if !zCOMPRESSION_IN_A_HURRY
- zIndexPos mpos={0},mposprev={0},*ml=&mpos,*mr=&mposprev,*ms;
- if(dictionary&&(sright.data=dictionary->data)&&(sright.size=dictionary->size)){
- for(uint16_t i=2;i<s2->size;i++)zIndexPosAdd(mr,(zPos){.val=s2->data[i-2]<<16|s2->data[i-1]<<8
- |s2->data[i],.pos=i-2});
- }
- #else
- uint16_t mpos[65536],mposprev[65536]={0},*ml=mpos,*mr=mposprev,*ms;
- if(dictionary&&(sright.data=dictionary->data)&&(sright.size=dictionary->size)){
- for(uint16_t i=1;i<s2->size;i++)mr[s2->data[i-1]<<8|s2->data[i]]=i-1;
- }
- #endif
- unsigned pos=0,remaining=uncompressed.size;
- while(remaining){
- uint32_t out[zBLOCK_SIZE]={0};
- s1->data=uncompressed.data+uncompressed.size-remaining,s1->size=bMin(zBLOCK_SIZE,remaining),
- remaining-=s1->size;
- #if !zCOMPRESSION_IN_A_HURRY
- zIndexPosFree(ml);
- #else
- memset(ml,0,sizeof(mpos));
- #endif
- memset(litfreqs,0,sizeof(litfreqs));
- memset(distfreqs,0,sizeof(distfreqs));
- memset(litsym,0,sizeof(litsym));
- memset(distsym,0,sizeof(distsym));
- #if !zCOMPRESSION_IN_A_HURRY
- for(uint16_t i=2;i<s1->size;i++){
- uint16_t len=0,l2,dist=0,l,r,j=i-2,c;
- uint32_t val=(s1->data[i-2]<<16|s1->data[i-1]<<8|s1->data[i]),sm1=s1->size-1;
- unsigned m=zIndexPosFindIndex(*ml,(zPos){.val=val,.pos=(uint16_t)-1},1);
- if(m!=-1&&(dist=i-2-ml->data[m].pos)&&ml->data[m].val==val&&i-ml->data[m].pos<21){
- 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);
- len+=dist,r+=dist);
- if(c<3)len=0,dist=0;
- }
- for(;m!=-1&&ml->data[m].val==val;m=zIndexPosNext(*ml,m)){
- 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++);
- if(l2>len)len=l2,dist=i-2-ml->data[m].pos;
- }
- for(m=zIndexPosFindIndex(*mr,(zPos){.val=val,.pos=(uint16_t)-1},1);m!=-1&&mr->data[m].val==val
- &&s2->size-mr->data[m].pos+i-2<32768;m=zIndexPosNext(*mr,m)){
- 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++);
- if(l2>len)len=l2,dist=s2->size-mr->data[m].pos+i-2;
- }
- if(len>3||(len==3&&dist<8))out[i-2]=(dist<<16)|len,i+=len-1,
- litfreqs[zLenToCode(len,&e,&el)]++,distfreqs[zDistToCode(dist,&de,&del)]++;
- else cont1nue:out[i-2]=s1->data[i-2]|512,litfreqs[s1->data[i-2]]++;
- 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++)
- zIndexPosAdd(ml,(zPos){.val=v,.pos=k});
- zIndexPosAdd(ml,(zPos){.pos=j,.val=val});
- }
- if(s1->size>1)out[s1->size-2]=s1->data[s1->size-2]|512,litfreqs[s1->data[s1->size-2]]++;
- out[s1->size-1]=s1->data[s1->size-1]|512,litfreqs[s1->data[s1->size-1]]++;
- #else
- for(uint16_t i=1;i<s1->size;i++){
- uint16_t val=(s1->data[i-1]<<8|s1->data[i]),match=ml[val],len=0,len2,dist=0,l,r,j=i-1;
- if(dist=i-1-match,match&&i-match<21)
- for(l=match,r=i-1;r+dist<s1->size&&len+dist<257&&!memcmp(s1->data+l,s1->data+r,dist);
- len+=dist,r+=dist);
- for(;match &&i-1-match<32768 ;){
- 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++);
- if(len2>len)len=len2,dist=i-1-match;
- match-=(out[match]&4294901760u)?out[match]>>16:match;
- }
- if((match=mr[val])&&(s2->size-match)+i-1<32768 ){
- 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++);
- if(len2>len)len=len2,dist=(s2->size-match)+i-1;
- }
- if(len>3||(len==3&&dist<9))out[i-1]=(dist<<16)|len,i+=len-1,
- litfreqs[zLenToCode(len,&e,&el)]++,distfreqs[zDistToCode(dist,&de,&del)]++;
- else out[i-1]=s1->data[i-1]|512,litfreqs[s1->data[i-1]]++;
- ml[val]=j;
- }
- out[s1->size-1]=s1->data[s1->size-1]|512,litfreqs[s1->data[s1->size-1]]++;
- #endif
- ;uint16_t litused=0,distused=0,i;
- for(litfreqs[256]=1,i=0;i<255;i++)if(litfreqs[i]&&++litused>=4)break;
- for(i=0;i<32;i++)if(distfreqs[i]&&++distused>=4)break;
- for(i=0;litused<4;litfreqs[++i]++,++litused);
- for(i=0;distused<4;distfreqs[++i]++,++distused);
- memset(&t,0,sizeof(t));
- zHuffTableMakeLens(lit,go1);
- zHuffTableMakeLens(dist,go2);
- bStringReserve(&ret,(pos>>3)+(bMax(65535,zBLOCK_SIZE*2)));
- ret.size=ret.capacity;
- zWriteBits(ret.data,0,1);
- zWriteBits(ret.data,2,2);
- zWriteBits(ret.data,28,5);
- zWriteBits(ret.data,29,5);
- zWriteBits(ret.data,15,4);
- for(uint8_t i=0;i<19;i++)zWriteBits(ret.data,lens[i],3);
- for(unsigned repeat,i=0;i<285;i++){
- uint16_t len=t.litlens[i];
- zWriteBits(ret.data,ll[len][0],ll[len][1]);
- for(repeat=1;!len&&repeat<138&&i+repeat<285;repeat++)if(t.litlens[i+repeat])break(repeat--);
- if(repeat<12)continue;
- zWriteBits(ret.data,ll[18][0],ll[18][1]);zWriteBits(ret.data,--repeat-11,7);i+=repeat;
- }
- for(unsigned i=0,len;i<30;i++){len=t.distlens[i];zWriteBits(ret.data,ll[len][0],ll[len][1]);}
- for(uint32_t i=0;i<s1->size;i++){
- if(out[i]&4294901760u){
- uint16_t l=zLenToCode(out[i]&65535,&e,&el),d=zDistToCode((out[i]&4294901760u)>>16,&de,&del);
- zWriteBits(ret.data,t.litcode[l],t.litlens[l]);
- if(el)zWriteBits(ret.data,e,el);
- zWriteBits(ret.data,t.distcode[d],t.distlens[d]);
- if(del)zWriteBits(ret.data,de,del);
- }else if(out[i]&512)zWriteBits(ret.data,t.litcode[out[i]&255],t.litlens[out[i]&255]);
- }
- zWriteBits(ret.data,t.litcode[256],t.litlens[256]);
- s2->data=s1->data,s2->size=s1->size,ms=mr,mr=ml,ml=ms;
- }
- zHeapLitToFreqByLitFree(&l2fl);
- zHeapLitToFreqByFreqFree(&l2ff);
- zHeapFreqToLenFree(&ftl);
- #if !zCOMPRESSION_IN_A_HURRY
- zIndexPosFree(mr);
- zIndexPosFree(ml);
- #endif
- zWriteBits(ret.data,0,1);
- zWriteBits(ret.data,0,2);
- if(pos&7)pos=((pos+7)>>3)<<3;
- zWriteBits(ret.data,0,16);
- zWriteBits(ret.data,(unsigned)~0,16);
- ret.size=pos>>3;
- return ret;
- }
- bString bZibCompress(bString uncompressed,bString *dictionary){
- bString bs=bZibCompress__(uncompressed,dictionary);
- unsigned char dasendeistnah[]={1,0,0,255,255};
- for(unsigned i=0;i<sizeof(dasendeistnah);i++)bStringAddChar(&bs,dasendeistnah[i]);
- return bs;
- }
- void bZibCompressFile(char *fileUncompressed,char *fileCompressed){
- bFile in=bFileFrom(fileUncompressed,bFILE_READ),
- out=bFileFrom(fileCompressed,bFILE_OVERWRITE|bFILE_CREATE_IF_NOT_EXISTS);
- for(bString *uncompressed,compressed;;){
- if((uncompressed=bFileRead(&in,33333333))->size==0)break;
- compressed=bZibCompress__(*uncompressed,0);
- bFileWrite(&out,compressed.data,compressed.size);
- bStringFree(&compressed);
- }
- bFileWrite(&out,(unsigned char[5]){1,0,0,255,255},5);
- bFileFree(&out);
- bFileFree(&in);
- }
- ////////////////////////////THATS IT!!!!!!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement