├── .gitattributes ├── BSDiff-GUI.pro ├── README.md ├── compilewin32 ├── docs ├── image1.png └── image2.png ├── include └── bsdifflib │ ├── LICENSE │ ├── README.md │ ├── bsdiff.c │ ├── bsdifflib.c │ ├── bsdifflib.h │ ├── bspatch.c │ ├── bspatchlib.c │ ├── bspatchlib.h │ └── bzip2 │ ├── LICENSE │ ├── blocksort.c │ ├── bzlib.c │ ├── bzlib.h │ ├── bzlib_private.h │ ├── compress.c │ ├── crctable.c │ ├── decompress.c │ ├── huffman.c │ └── randtable.c ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui /.gitattributes: -------------------------------------------------------------------------------- 1 | include/* linguist-vendored 2 | -------------------------------------------------------------------------------- /BSDiff-GUI.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2020-07-06T12:09:34 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = BSDiff-GUI 12 | TEMPLATE = app 13 | 14 | # The following define makes your compiler emit warnings if you use 15 | # any feature of Qt which has been marked as deprecated (the exact warnings 16 | # depend on your compiler). Please consult the documentation of the 17 | # deprecated API in order to know how to port your code away from it. 18 | DEFINES += QT_DEPRECATED_WARNINGS 19 | 20 | # You can also make your code fail to compile if you use deprecated APIs. 21 | # In order to do so, uncomment the following line. 22 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 24 | 25 | CONFIG += c++11 26 | 27 | SOURCES += \ 28 | main.cpp \ 29 | mainwindow.cpp \ 30 | include/bsdifflib/bzip2/blocksort.c \ 31 | include/bsdifflib/bzip2/bzlib.c \ 32 | include/bsdifflib/bzip2/compress.c \ 33 | include/bsdifflib/bzip2/crctable.c \ 34 | include/bsdifflib/bzip2/decompress.c \ 35 | include/bsdifflib/bzip2/huffman.c \ 36 | include/bsdifflib/bzip2/randtable.c \ 37 | include/bsdifflib/bsdifflib.c \ 38 | include/bsdifflib/bspatchlib.c 39 | 40 | HEADERS += \ 41 | mainwindow.h \ 42 | include/bsdifflib/bzip2/bzlib.h \ 43 | include/bsdifflib/bzip2/bzlib_private.h \ 44 | include/bsdifflib/bsdifflib.h \ 45 | include/bsdifflib/bspatchlib.h 46 | 47 | FORMS += \ 48 | mainwindow.ui 49 | 50 | # Default rules for deployment. 51 | qnx: target.path = /tmp/$${TARGET}/bin 52 | else: unix:!android: target.path = /opt/$${TARGET}/bin 53 | !isEmpty(target.path): INSTALLS += target 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PatchGUI 2 | A cross-platform desktop application for creating and applying patches to binary files. 3 | 4 | [Video Demonstration](https://www.fullstackglobal.com/patchgui-tool/) 5 | 6 | ## Releases 7 | [Releases Page](https://github.com/Raflos10/PatchGUI/releases/) 8 | 9 | ## Creating a Patch 10 | To create a patch for a file, the source file and new file must both be supplied. 11 | 12 | 1. The source file is the current version of a file to which the patch will be applicable. 13 | 2. The new file is a new version of the source file with differences that the patch should apply. 14 | 3. Filename and path for the patch file to be created. 15 | 16 | ![Preview1](docs/image1.png) 17 | 18 | After creating the patch file, it can be used to update any copies of the source file, applying the changes on a binary level. 19 | 20 | ## Applying a Patch 21 | To apply a patch on a file, the source file and patch file must both be supplied. 22 | 23 | 1. The old file is the previous version of a file, in which the changes specified in the patch file will be applied. 24 | 2. The patch file is the file containing the changes to be applied. 25 | 3. Filename and path for the new version of the source file to be created. 26 | 27 | ![Preview2](docs/image2.png) 28 | 29 | After applying the patch file to the old file, the new file will perfectly match the one used to generate the patch file. 30 | 31 | ## Use-case 32 | The main use-case for this software is to generate update files that are vastly smaller and faster to download than entirely new files. These patch files can be generated and applied using this tool, or they can be generated with this tool, distributed to users, and applied using an update software that includes the bsdiff library. 33 | This makes downloading updates for applications much faster and take up much less space. 34 | 35 | By using suffix sorting (specifically, Larsson and Sadakane's qsufsort) and taking advantage of how executable files change, bsdiff routinely produces binary patches 50-80% smaller than those produced by Xdelta, and 15% smaller than those produced by .RTPatch (a $2750/seat commercial patch tool). 36 | 37 | Bsdiff runs in O((n+m) log n) time; on a 200MHz Pentium Pro, building a binary patch for a 4MB file takes about 90 seconds. bspatch runs in O(n+m) time; on the same machine, applying that patch takes about two seconds. 38 | 39 | ## Libraries Used 40 | Bsdifflib: 41 | https://github.com/petervas/bsdifflib (based on Binary diff/patch utility version 4.3, written by Copyright 2003-2005 Colin Percival cperciva@freebsd.org available at http://www.daemonology.net/bsdiff/) 42 | 43 | Qt5 44 | https://github.com/qt 45 | -------------------------------------------------------------------------------- /compilewin32: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /opt/mxe/usr/bin/i686-w64-mingw32.static-qmake-qt5 && make && make clean 4 | -------------------------------------------------------------------------------- /docs/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Raflos10/PatchGUI/014873a94e8554d0429c8b45b73d936d46c5769b/docs/image1.png -------------------------------------------------------------------------------- /docs/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Raflos10/PatchGUI/014873a94e8554d0429c8b45b73d936d46c5769b/docs/image2.png -------------------------------------------------------------------------------- /include/bsdifflib/LICENSE: -------------------------------------------------------------------------------- 1 | BSD Protection License 2 | February 2002 3 | 4 | Preamble 5 | -------- 6 | 7 | The Berkeley Software Distribution ("BSD") license has proven very effective 8 | over the years at allowing for a wide spread of work throughout both 9 | commercial and non-commercial products. For programmers whose primary 10 | intention is to improve the general quality of available software, it is 11 | arguable that there is no better license than the BSD license, as it 12 | permits improvements to be used wherever they will help, without idealogical 13 | or metallic constraint. 14 | 15 | This is of particular value to those who produce reference implementations 16 | of proposed standards: The case of TCP/IP clearly illustrates that freely 17 | and universally available implementations leads the rapid acceptance of 18 | standards -- often even being used instead of a de jure standard (eg, OSI 19 | network models). 20 | 21 | With the rapid proliferation of software licensed under the GNU General 22 | Public License, however, the continued success of this role is called into 23 | question. Given that the inclusion of a few lines of "GPL-tainted" work 24 | into a larger body of work will result in restricted distribution -- and 25 | given that further work will likely build upon the "tainted" portions, 26 | making them difficult to remove at a future date -- there are inevitable 27 | circumstances where authors would, in order to protect their goal of 28 | providing for the widespread usage of their work, wish to guard against 29 | such "GPL-taint". 30 | 31 | In addition, one can imagine that companies which operate by producing and 32 | selling (possibly closed-source) code would wish to protect themselves 33 | against the rise of a GPL-licensed competitor. While under existing 34 | licenses this would mean not releasing their code under any form of open 35 | license, if a license existed under which they could incorporate any 36 | improvements back into their own (commercial) products then they might be 37 | far more willing to provide for non-closed distribution. 38 | 39 | For the above reasons, we put forth this "BSD Protection License": A 40 | license designed to retain the freedom granted by the BSD license to use 41 | licensed works in a wide variety of settings, both non-commercial and 42 | commercial, while protecting the work from having future contributors 43 | restrict that freedom. 44 | 45 | The precise terms and conditions for copying, distribution, and 46 | modification follow. 47 | 48 | BSD PROTECTION LICENSE 49 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION 50 | ---------------------------------------------------------------- 51 | 52 | 0. Definitions. 53 | a) "Program", below, refers to any program or work distributed under 54 | the terms of this license. 55 | b) A "work based on the Program", below, refers to either the Program 56 | or any derivative work under copyright law. 57 | c) "Modification", below, refers to the act of creating derivative works. 58 | d) "You", below, refers to each licensee. 59 | 60 | 1. Scope. 61 | This license governs the copying, distribution, and modification of the 62 | Program. Other activities are outside the scope of this license; The 63 | act of running the Program is not restricted, and the output from the 64 | Program is covered only if its contents constitute a work based on the 65 | Program. 66 | 67 | 2. Verbatim copies. 68 | You may copy and distribute verbatim copies of the Program as you 69 | receive it, in any medium, provided that you conspicuously and 70 | appropriately publish on each copy an appropriate copyright notice; keep 71 | intact all the notices that refer to this License and to the absence of 72 | any warranty; and give any other recipients of the Program a copy of this 73 | License along with the Program. 74 | 75 | 3. Modification and redistribution under closed license. 76 | You may modify your copy or copies of the Program, and distribute 77 | the resulting derivative works, provided that you meet the 78 | following conditions: 79 | a) The copyright notice and disclaimer on the Program must be reproduced 80 | and included in the source code, documentation, and/or other materials 81 | provided in a manner in which such notices are normally distributed. 82 | b) The derivative work must be clearly identified as such, in order that 83 | it may not be confused with the original work. 84 | c) The license under which the derivative work is distributed must 85 | expressly prohibit the distribution of further derivative works. 86 | 87 | 4. Modification and redistribution under open license. 88 | You may modify your copy or copies of the Program, and distribute 89 | the resulting derivative works, provided that you meet the 90 | following conditions: 91 | a) The copyright notice and disclaimer on the Program must be reproduced 92 | and included in the source code, documentation, and/or other materials 93 | provided in a manner in which such notices are normally distributed. 94 | b) You must clearly indicate the nature and date of any changes made 95 | to the Program. The full details need not necessarily be included in 96 | the individual modified files, provided that each modified file is 97 | clearly marked as such and instructions are included on where the 98 | full details of the modifications may be found. 99 | c) You must cause any work that you distribute or publish, that in whole 100 | or in part contains or is derived from the Program or any part 101 | thereof, to be licensed as a whole at no charge to all third 102 | parties under the terms of this License. 103 | 104 | 5. Implied acceptance. 105 | You may not copy or distribute the Program or any derivative works except 106 | as expressly provided under this license. Consequently, any such action 107 | will be taken as implied acceptance of the terms of this license. 108 | 109 | 6. NO WARRANTY. 110 | THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 111 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 112 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 113 | THE COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 114 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE FOR ANY DIRECT, 115 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 116 | ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING, BUT 117 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 118 | USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 119 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 120 | TORT, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 121 | POSSIBILITY OF SUCH DAMAGES. 122 | -------------------------------------------------------------------------------- /include/bsdifflib/README.md: -------------------------------------------------------------------------------- 1 | Binary diff/patch library (bsdifflib/bspatchlib) 1.1 merges the original 2 | Binary diff/patch utility (bsdiff/bspatch) and the Win32 port and adds a 3 | middle layer of code to make it usable as an ANSI C compliant 4 | cross-platform C/C++ library. See bsdiff.c/bspatch.c for example usage. 5 | Copyright 2010 Peter Vaskovic 6 | 7 | based on Binary diff/patch utility version 4.3, written by 8 | Copyright 2003-2005 Colin Percival 9 | available at http://www.daemonology.net/bsdiff/ 10 | 11 | based on bsdiff/bspatch native Win32-Port (May 2007), written by 12 | Copyright 2007 Andreas John 13 | available at http://sites.inka.de/tesla/others.html#bsdiff 14 | 15 | source release includes files from libbzip2 1.0.6 (20 September 2010) 16 | Copyright 1996-2010 Julian R Seward 17 | available at http://www.bzip.org/ 18 | 19 | error handling was inspired by GetWAD, written by 20 | Copyright 2003-2010 Hippocrates Sendoukas 21 | available at http://getwad.keystone.gr/ 22 | 23 | The source code was formatted with Artistic Style 1.24 24 | available at http://astyle.sourceforge.net/ 25 | using the options "-A1txjz1f". 26 | 27 | I would like to thank Hippocrates Sendoukas for helping me out with some 28 | C related questions and giving me helpful coding suggestions in general. 29 | You can visit his site at http://hs.keystone.gr/ 30 | 31 | Changelog: 32 | 33 | bsdifflib/bspatchlib 1.0 (26 May 2010) 34 | 35 | Initial release. 36 | 37 | bsdifflib/bspatchlib 1.1 (9 November 2010) 38 | 39 | Included own header in source files. 40 | Hippocrates Sendoukas optimized the patching process to 41 | take place in memory. New functions have been added to the bspatchlib 42 | API to make use of the optimizations for certain use cases. 43 | Updated libbzip2 to 1.0.6. 44 | 45 | ------------------------------------------------------------------------- 46 | Quick overview from the homepage of these tools: 47 | http://www.daemonology.net/bsdiff/ 48 | 49 | Binary diff/patch utility 50 | bsdiff and bspatch are tools for building and applying patches to binary 51 | files. By using suffix sorting (specifically, Larsson and Sadakane's 52 | qsufsort) and taking advantage of how executable files change, bsdiff 53 | routinely produces binary patches 50-80% smaller than those produced by 54 | Xdelta, and 15% smaller than those produced by .RTPatch (a $2750/seat 55 | commercial patch tool). 56 | 57 | These programs were originally named bdiff and bpatch, but the large 58 | number of other programs using those names lead to confusion; I'm not 59 | sure if the "bs" in refers to "binary software" (because bsdiff produces 60 | exceptionally small patches for executable files) or "bytewise 61 | subtraction" (which is the key to how well it performs). Feel free to 62 | offer other suggestions. 63 | 64 | bsdiff and bspatch use bzip2; by default they assume it is in /usr/bin. 65 | 66 | bsdiff is quite memory-hungry. It requires max(17*n,9*n+m)+O(1) bytes of 67 | memory, where n is the size of the old file and m is the size of the new 68 | file. bspatch requires n+m+O(1) bytes. 69 | 70 | bsdiff runs in O((n+m) log n) time; on a 200MHz Pentium Pro, building a 71 | binary patch for a 4MB file takes about 90 seconds. bspatch runs in 72 | O(n+m) time; on the same machine, applying that patch takes about two 73 | seconds. 74 | 75 | Providing that off_t is defined properly, bsdiff and bspatch support 76 | files of up to 2^61-1 = 2Ei-1 bytes. 77 | ------------------------------------------------------------------------- 78 | -------------------------------------------------------------------------------- /include/bsdifflib/bsdiff.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2010, Peter Vaskovic, (petervaskovic@yahoo.de) 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #include 28 | #include "bsdifflib.h" 29 | 30 | int main(int argc,char * argv[]) 31 | { 32 | char *errmsg; 33 | 34 | if(argc!=4) 35 | { 36 | printf("usage: %s oldfile newfile patchfile\n",argv[0]); 37 | return 1; 38 | } 39 | 40 | if((errmsg=bsdiff(argv[1],argv[2],argv[3])) != NULL) 41 | { 42 | printf("%s\n",errmsg); 43 | return 1; 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /include/bsdifflib/bsdifflib.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2010, Peter Vaskovic, (petervaskovic@yahoo.de) 3 | * Copyright 2007 Andreas John 4 | * Copyright 2003-2005 Colin Percival 5 | * All rights reserved 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted providing that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "bsdifflib.h" 34 | 35 | typedef unsigned char u_char; 36 | 37 | #define MIN(x,y) (((x)<(y)) ? (x) : (y)) 38 | 39 | static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h) 40 | { 41 | off_t i,j,k,x,tmp,jj,kk; 42 | 43 | if(len<16) 44 | { 45 | for(k=start; kstart) 148 | { 149 | split(I,V,start,jj-start,h); 150 | } 151 | 152 | for(i=0; ikk) 163 | { 164 | split(I,V,kk,start+len-kk,h); 165 | } 166 | } 167 | 168 | static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize) 169 | { 170 | off_t buckets[256]; 171 | off_t i,h,len; 172 | 173 | for(i=0; i<256; i++) 174 | { 175 | buckets[i]=0; 176 | } 177 | 178 | for(i=0; i0; i--) 189 | { 190 | buckets[i]=buckets[i-1]; 191 | } 192 | 193 | buckets[0]=0; 194 | 195 | for(i=0; iy) 277 | { 278 | *pos=I[st]; 279 | return x; 280 | } 281 | else 282 | { 283 | *pos=I[en]; 284 | return y; 285 | } 286 | }; 287 | 288 | x=st+(en-st)/2; 289 | 290 | if(memcmp(old+I[x],_new,MIN(oldsize-I[x],newsize))<0) 291 | { 292 | return search(I,old,oldsize,_new,newsize,x,en,pos); 293 | } 294 | else 295 | { 296 | return search(I,old,oldsize,_new,newsize,st,x,pos); 297 | }; 298 | } 299 | 300 | static void offtout(off_t x,u_char *buf) 301 | { 302 | off_t y; 303 | 304 | if(x<0) 305 | { 306 | y=-x; 307 | } 308 | else 309 | { 310 | y=x; 311 | } 312 | 313 | buf[0]=y%256; 314 | y-=buf[0]; 315 | y=y/256; 316 | buf[1]=y%256; 317 | y-=buf[1]; 318 | y=y/256; 319 | buf[2]=y%256; 320 | y-=buf[2]; 321 | y=y/256; 322 | buf[3]=y%256; 323 | y-=buf[3]; 324 | y=y/256; 325 | buf[4]=y%256; 326 | y-=buf[4]; 327 | y=y/256; 328 | buf[5]=y%256; 329 | y-=buf[5]; 330 | y=y/256; 331 | buf[6]=y%256; 332 | y-=buf[6]; 333 | y=y/256; 334 | buf[7]=y%256; 335 | 336 | if(x<0) 337 | { 338 | buf[7]|=0x80; 339 | } 340 | } 341 | 342 | char *bsdiff(const char *oldfile, const char *newfile, 343 | const char *patchfile) 344 | { 345 | u_char *old = NULL; 346 | u_char *_new = NULL; 347 | off_t oldsize,newsize; 348 | off_t *I = NULL; 349 | off_t *V = NULL; 350 | off_t scan, len; 351 | off_t pos = 0; 352 | off_t lastscan,lastpos,lastoffset; 353 | off_t oldscore,scsc; 354 | off_t s,Sf,lenf,Sb,lenb; 355 | off_t overlap,Ss,lens; 356 | off_t i; 357 | off_t dblen,eblen; 358 | u_char *db = NULL; 359 | u_char *eb = NULL; 360 | u_char buf[8]; 361 | u_char header[32]; 362 | FILE * pf, * fp; 363 | BZFILE * pfbz2; 364 | int bz2err; 365 | static char errstr[1024]; 366 | 367 | /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure 368 | that we never try to malloc(0) and get a NULL pointer */ 369 | if(((fp=fopen(oldfile,"rb")) == NULL) || 370 | (fseek(fp,0,SEEK_END)!=0) || 371 | ((oldsize=ftell(fp))==-1) || 372 | ((old=(u_char*)malloc(oldsize+1))==NULL) || 373 | (fseek(fp,0,SEEK_SET)!=0) || 374 | ((off_t)fread(old,1,oldsize,fp)!=oldsize)) 375 | { 376 | sprintf(errstr,"Cannot process file \"%s\".",oldfile); 377 | free(old); 378 | 379 | if(fp) 380 | { 381 | fclose(fp); 382 | } 383 | 384 | return errstr; 385 | } 386 | 387 | if(fclose(fp)!=0) 388 | { 389 | sprintf(errstr,"Cannot close file \"%s\".",oldfile); 390 | free(old); 391 | return errstr; 392 | } 393 | 394 | if(((I=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL) || 395 | ((V=(off_t*)malloc((oldsize+1)*sizeof(off_t)))==NULL)) 396 | { 397 | sprintf(errstr,"Cannot allocate memory."); 398 | free(I); 399 | free(V); 400 | free(old); 401 | return errstr; 402 | } 403 | 404 | qsufsort(I,V,old,oldsize); 405 | free(V); 406 | 407 | /* Allocate newsize+1 bytes instead of newsize bytes to ensure 408 | that we never try to malloc(0) and get a NULL pointer */ 409 | if(((fp=fopen(newfile,"rb")) == NULL) || 410 | (fseek(fp,0,SEEK_END)!=0) || 411 | ((newsize=ftell(fp))==-1) || 412 | ((_new=(u_char*)malloc(newsize+1))==NULL) || 413 | (fseek(fp,0,SEEK_SET)!=0) || 414 | ((off_t)fread(_new,1,newsize,fp)!=newsize)) 415 | { 416 | sprintf(errstr,"Cannot process file \"%s\".",newfile); 417 | free(I); 418 | free(_new); 419 | free(old); 420 | 421 | if(fp) 422 | { 423 | fclose(fp); 424 | } 425 | 426 | return errstr; 427 | } 428 | 429 | if(fclose(fp)!=0) 430 | { 431 | sprintf(errstr,"Cannot process file \"%s\".",newfile); 432 | free(I); 433 | free(_new); 434 | free(old); 435 | return errstr; 436 | } 437 | 438 | if(((db=(u_char*)malloc(newsize+1))==NULL) || 439 | ((eb=(u_char*)malloc(newsize+1))==NULL)) 440 | { 441 | sprintf(errstr,"Cannot allocate memory."); 442 | free(I); 443 | free(_new); 444 | free(old); 445 | free(db); 446 | free(eb); 447 | return errstr; 448 | } 449 | 450 | dblen=0; 451 | eblen=0; 452 | 453 | /* Create the patch file */ 454 | if ((pf = fopen(patchfile, "wb")) == NULL) 455 | { 456 | sprintf(errstr,"Cannot open file \"%s\".",patchfile); 457 | free(I); 458 | free(_new); 459 | free(old); 460 | free(db); 461 | free(eb); 462 | return errstr; 463 | } 464 | 465 | /* Header is 466 | 0 8 "BSDIFF40" 467 | 8 8 length of bzip2ed ctrl block 468 | 16 8 length of bzip2ed diff block 469 | 24 8 length of new file */ 470 | /* File is 471 | 0 32 Header 472 | 32 ?? Bzip2ed ctrl block 473 | ?? ?? Bzip2ed diff block 474 | ?? ?? Bzip2ed extra block */ 475 | memcpy(header,"BSDIFF40",8); 476 | offtout(0, header + 8); 477 | offtout(0, header + 16); 478 | offtout(newsize, header + 24); 479 | 480 | if (fwrite(header, 32, 1, pf) != 1) 481 | { 482 | sprintf(errstr,"Cannot write file \"%s\".",patchfile); 483 | free(I); 484 | free(_new); 485 | free(old); 486 | free(db); 487 | free(eb); 488 | fclose(pf); 489 | return errstr; 490 | } 491 | 492 | /* Compute the differences, writing ctrl as we go */ 493 | if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL) 494 | { 495 | sprintf(errstr,"BZ2_bzWriteOpen, bz2err = %d", bz2err); 496 | free(I); 497 | free(_new); 498 | free(old); 499 | free(db); 500 | free(eb); 501 | fclose(pf); 502 | return errstr; 503 | } 504 | 505 | scan=0; 506 | len=0; 507 | lastscan=0; 508 | lastpos=0; 509 | lastoffset=0; 510 | 511 | while(scanoldscore+8)) 529 | { 530 | break; 531 | } 532 | 533 | if((scan+lastoffsetSf*2-lenf) 556 | { 557 | Sf=s; 558 | lenf=i; 559 | }; 560 | }; 561 | 562 | lenb=0; 563 | 564 | if(scan=lastscan+i)&&(pos>=i); i++) 570 | { 571 | if(old[pos-i]==_new[scan-i]) 572 | { 573 | s++; 574 | } 575 | 576 | if(s*2-i>Sb*2-lenb) 577 | { 578 | Sb=s; 579 | lenb=i; 580 | }; 581 | }; 582 | }; 583 | 584 | if(lastscan+lenf>scan-lenb) 585 | { 586 | overlap=(lastscan+lenf)-(scan-lenb); 587 | s=0; 588 | Ss=0; 589 | lens=0; 590 | 591 | for(i=0; iSs) 606 | { 607 | Ss=s; 608 | lens=i+1; 609 | }; 610 | }; 611 | 612 | lenf+=lens-overlap; 613 | 614 | lenb-=lens; 615 | }; 616 | 617 | for(i=0; i 28 | #include "bspatchlib.h" 29 | 30 | int main(int argc,char * argv[]) 31 | { 32 | char *errmsg; 33 | 34 | if(argc!=4) 35 | { 36 | printf("usage: %s oldfile newfile patchfile\n",argv[0]); 37 | return 1; 38 | } 39 | 40 | if((errmsg=bspatch(argv[1],argv[2],argv[3])) != NULL) 41 | { 42 | printf("%s\n",errmsg); 43 | return 1; 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /include/bsdifflib/bspatchlib.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2010, Peter Vaskovic, (petervaskovic@yahoo.de) 3 | * Copyright 2007 Andreas John 4 | * Copyright 2003-2005 Colin Percival 5 | * All rights reserved 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted providing that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include "bspatchlib.h" 34 | 35 | typedef unsigned char u_char; 36 | 37 | /***************************************************************************/ 38 | 39 | char *file_to_mem(const char *fname, unsigned char **buf, int *buf_sz) 40 | { 41 | FILE *f; 42 | int l_sz; 43 | unsigned char *l_buf; 44 | static char errstr[384]; 45 | 46 | *buf = NULL; 47 | *buf_sz = 0; 48 | 49 | if ( (f=fopen(fname,"rb")) == NULL ) 50 | { 51 | sprintf(errstr,"Cannot open file \"%s\" for reading.",fname); 52 | return errstr; 53 | } 54 | if ( fseek(f,0,SEEK_END) || (l_sz=ftell(f))<=0 ) 55 | { 56 | fclose(f); 57 | sprintf(errstr,"Seek failure on file \"%s\".",fname); 58 | return errstr; 59 | } 60 | if ( (l_buf = (unsigned char *) malloc(l_sz+1)) == NULL) 61 | { 62 | fclose(f); 63 | sprintf(errstr,"Cannot allocate %d bytes to read file \"%s\" into memory.",l_sz+1, fname); 64 | return errstr; 65 | } 66 | 67 | fseek(f,0,SEEK_SET); 68 | 69 | if ( (int)fread(l_buf, 1, l_sz, f) != l_sz) 70 | { 71 | free(l_buf); 72 | fclose(f); 73 | sprintf(errstr,"Cannot read from file \"%s\".",fname); 74 | return errstr; 75 | } 76 | fclose(f); 77 | *buf = l_buf; 78 | *buf_sz = l_sz; 79 | return NULL; 80 | } 81 | 82 | /***************************************************************************/ 83 | 84 | char *mem_to_file(const unsigned char *buf, int buf_sz, const char *fname) 85 | { 86 | FILE *f; 87 | static char errstr[384]; 88 | 89 | if ( (f=fopen(fname,"wb")) == NULL ) 90 | { 91 | sprintf(errstr,"Cannot open file \"%s\" for writing.",fname); 92 | return errstr; 93 | } 94 | if ( (int)fwrite(buf, 1, buf_sz, f) != buf_sz ) 95 | { 96 | fclose(f); 97 | sprintf(errstr,"Cannot write to file \"%s\".",fname); 98 | return errstr; 99 | } 100 | fclose(f); 101 | return NULL; 102 | } 103 | 104 | /***************************************************************************/ 105 | 106 | static off_t offtin(const u_char *buf) 107 | { 108 | off_t y; 109 | y=buf[7]&0x7F; 110 | y=y*256; 111 | y+=buf[6]; 112 | y=y*256; 113 | y+=buf[5]; 114 | y=y*256; 115 | y+=buf[4]; 116 | y=y*256; 117 | y+=buf[3]; 118 | y=y*256; 119 | y+=buf[2]; 120 | y=y*256; 121 | y+=buf[1]; 122 | y=y*256; 123 | y+=buf[0]; 124 | 125 | if(buf[7]&0x80) 126 | { 127 | y=-y; 128 | } 129 | 130 | return y; 131 | } 132 | 133 | /***************************************************************************/ 134 | 135 | static char *decompress_block(const unsigned char *in_buf, int in_sz, unsigned char **out_buf, int *out_sz) 136 | { 137 | int rc, known_size; 138 | unsigned sz; 139 | unsigned char *buf; 140 | static char err_str[1024]; 141 | 142 | known_size = *out_sz; 143 | *out_buf = NULL; 144 | *out_sz = 0; 145 | 146 | sz = (known_size>=0) ? (known_size+16) : 1024 + 8*in_sz; 147 | for (;;) 148 | { 149 | if ( (buf = (unsigned char *) malloc(sz)) == NULL ) 150 | { 151 | sprintf(err_str,"decompress_block: cannot allocate %u bytes for patch",sz); 152 | return err_str; 153 | } 154 | rc = BZ2_bzBuffToBuffDecompress( (char *) buf, &sz, (char *) in_buf, in_sz, 0, 0); 155 | if (rc == BZ_OK) 156 | { 157 | *out_buf = buf; 158 | *out_sz = (int) sz; 159 | return NULL; 160 | } 161 | if (rc != BZ_OUTBUFF_FULL) 162 | { 163 | sprintf(err_str,"decompress_block: BZ2_bzBuffToBuffDecompress() returned %d",rc); 164 | return err_str; 165 | } 166 | 167 | /* 168 | * We come to this point if the decompression failed because 169 | * we have not allocated enough memory 170 | */ 171 | if (known_size>=0) /* This should not happen, but don't break if it does */ 172 | sz = 1024 + 8*in_sz; 173 | 174 | if (sz >= 32*1024*1024) /* Seems to me that 32M should be more than enough for a patch */ 175 | break; 176 | sz *= 2; 177 | } 178 | sprintf(err_str,"decompress_block: even %u bytes are not enough for the patch",sz); 179 | return err_str; 180 | } 181 | 182 | /***************************************************************************/ 183 | 184 | char *bspatch_mem(const unsigned char *old_buf, int old_size, 185 | unsigned char **new_buf, int *new_size, 186 | const unsigned char *compr_patch_buf, int compr_patch_buf_sz, 187 | int uncompr_ctrl_sz, int uncompr_diff_sz, int uncompr_xtra_sz) 188 | { 189 | int l_new_size, dec_ctrl_sz, dec_diff_sz, dec_xtra_sz; 190 | ssize_t bzctrllen, bzdifflen, bzextralen; 191 | u_char *l_new_buf, *dec_ctrl_buf, *dec_diff_buf, *dec_xtra_buf, 192 | *pctrl, *pdiff, *pxtra, *pctrl_end, *pdiff_end, *pxtra_end; 193 | off_t oldpos, newpos, i, ctrl[3]; 194 | char *errmsg; 195 | static char err_buf[1024]; 196 | 197 | *new_buf = NULL; 198 | *new_size = 0; 199 | 200 | /* 201 | * File format: 202 | * 0 8 "BSDIFF40" 203 | * 8 8 X 204 | * 16 8 Y 205 | * 24 8 sizeof(newfile) 206 | * 32 X bzip2(control block) 207 | * 32+X Y bzip2(diff block) 208 | * 32+X+Y ??? bzip2(extra block) 209 | * with control block a set of triples (x,y,z) meaning "add x bytes 210 | * from oldfile to x bytes from the diff block; copy y bytes from the 211 | * extra block; seek forwards in oldfile by z bytes". 212 | */ 213 | if (compr_patch_buf_sz < 32) 214 | { 215 | sprintf(err_buf,"Corrupt patch. Too short patch size"); 216 | return err_buf; 217 | } 218 | 219 | /* Check for appropriate magic */ 220 | if ( memcmp(compr_patch_buf, "BSDIFF40", 8) != 0 ) 221 | { 222 | sprintf(err_buf,"Corrupt patch. Bad header signature"); 223 | return err_buf; 224 | } 225 | 226 | /* Read lengths from header */ 227 | bzctrllen = offtin(compr_patch_buf+8); 228 | bzdifflen = offtin(compr_patch_buf+16); 229 | l_new_size = offtin(compr_patch_buf+24); 230 | 231 | if (bzctrllen<=0 || bzdifflen<=0 || l_new_size<=0 || compr_patch_buf_sz<=32+bzctrllen+bzdifflen) 232 | { 233 | sprintf(err_buf,"Corrupt patch. Bad header lengths"); 234 | return err_buf; 235 | } 236 | bzextralen = compr_patch_buf_sz - 32 - bzctrllen - bzdifflen; 237 | 238 | dec_ctrl_sz = uncompr_ctrl_sz; 239 | if ( (errmsg = decompress_block(compr_patch_buf+32, bzctrllen, 240 | &dec_ctrl_buf, &dec_ctrl_sz)) != NULL ) 241 | return errmsg; 242 | 243 | dec_diff_sz = uncompr_diff_sz; 244 | if ( (errmsg = decompress_block(compr_patch_buf + 32 + bzctrllen, bzdifflen, 245 | &dec_diff_buf, &dec_diff_sz)) != NULL ) 246 | { 247 | free(dec_ctrl_buf); 248 | return errmsg; 249 | } 250 | 251 | dec_xtra_sz = uncompr_xtra_sz; 252 | if ( (errmsg = decompress_block(compr_patch_buf + 32 + bzctrllen + bzdifflen, bzextralen, 253 | &dec_xtra_buf, &dec_xtra_sz)) != NULL ) 254 | { 255 | free(dec_diff_buf); 256 | free(dec_ctrl_buf); 257 | return errmsg; 258 | } 259 | 260 | if ( (l_new_buf=(u_char*)malloc(l_new_size+1)) == NULL ) 261 | { 262 | free(dec_xtra_buf); 263 | free(dec_diff_buf); 264 | free(dec_ctrl_buf); 265 | sprintf(err_buf,"Cannot allocate %d bytes to create the patch.", l_new_size+1); 266 | return err_buf; 267 | } 268 | 269 | pctrl_end = (pctrl = dec_ctrl_buf) + dec_ctrl_sz; 270 | pdiff_end = (pdiff = dec_diff_buf) + dec_diff_sz; 271 | pxtra_end = (pxtra = dec_xtra_buf) + dec_xtra_sz; 272 | 273 | oldpos = newpos = 0; 274 | 275 | while (newpos pctrl_end - 2*8) 279 | { 280 | sprintf(err_buf,"Corrupt patch 1."); 281 | GETOUT: 282 | free(dec_xtra_buf); 283 | free(dec_diff_buf); 284 | free(dec_ctrl_buf); 285 | free(l_new_buf); 286 | return err_buf; 287 | } 288 | for (i=0; i<=2; i++) 289 | { 290 | ctrl[i] = offtin(pctrl); 291 | pctrl += 8; 292 | } 293 | 294 | /* Sanity-check */ 295 | if (newpos+ctrl[0]>l_new_size) 296 | { 297 | sprintf(err_buf,"Corrupt patch 2."); 298 | goto GETOUT; 299 | } 300 | 301 | /* Read diff string */ 302 | if (pdiff > pdiff_end - ctrl[0]) 303 | { 304 | sprintf(err_buf,"Corrupt patch 3."); 305 | goto GETOUT; 306 | } 307 | memcpy(l_new_buf+newpos, pdiff, ctrl[0]); 308 | pdiff += ctrl[0]; 309 | 310 | /* Add old data to diff string */ 311 | for (i=0; i=0) && (oldpos+il_new_size) 323 | { 324 | sprintf(err_buf,"Corrupt patch 4."); 325 | goto GETOUT; 326 | } 327 | 328 | 329 | /* Read extra string */ 330 | if (pxtra > pxtra_end - ctrl[1]) 331 | { 332 | sprintf(err_buf,"Corrupt patch 5."); 333 | goto GETOUT; 334 | } 335 | memcpy(l_new_buf + newpos, pxtra, ctrl[1]); 336 | pxtra += ctrl[1]; 337 | 338 | /* Adjust pointers */ 339 | newpos += ctrl[1]; 340 | oldpos += ctrl[2]; 341 | } 342 | 343 | /* Clean up the bzip2 reads */ 344 | free(dec_xtra_buf); 345 | free(dec_diff_buf); 346 | free(dec_ctrl_buf); 347 | 348 | *new_buf = l_new_buf; 349 | *new_size = l_new_size; 350 | return NULL; 351 | } 352 | 353 | /***************************************************************************/ 354 | 355 | char *bspatch(const char *oldfile, const char *newfile, const char *patchfile) 356 | { 357 | unsigned char *in_buf, *out_buf, *patch_buf; 358 | int in_sz, out_sz, patch_sz; 359 | char *errs; 360 | 361 | errs = file_to_mem(oldfile, &in_buf, &in_sz); 362 | if (errs) 363 | return errs; 364 | 365 | errs = file_to_mem(patchfile, &patch_buf, &patch_sz); 366 | if (errs) 367 | { 368 | free(in_buf); 369 | return errs; 370 | } 371 | 372 | errs = bspatch_mem(in_buf,in_sz, &out_buf, &out_sz, patch_buf, patch_sz, -1, -1, -1); 373 | free(in_buf); 374 | if (errs) 375 | return errs; 376 | 377 | errs = mem_to_file(out_buf, out_sz, newfile); 378 | free(out_buf); 379 | return (errs) ? errs : NULL; 380 | } 381 | 382 | /***************************************************************************/ 383 | -------------------------------------------------------------------------------- /include/bsdifflib/bspatchlib.h: -------------------------------------------------------------------------------- 1 | #ifndef BSPATCHLIBH__ 2 | #define BSPATCHLIBH__ 3 | /*- 4 | * Copyright 2010, Peter Vaskovic, (petervaskovic@yahoo.de) 5 | * All rights reserved 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted providing that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* Returns NULL on success, and an error message otherwise. */ 34 | char *file_to_mem(const char *fname, unsigned char **buf, int *buf_sz); 35 | 36 | /* Same */ 37 | char *mem_to_file(const unsigned char *buf, int buf_sz, const char *fname); 38 | 39 | /* Same */ 40 | char *bspatch_mem(const unsigned char *old_buf, int old_size, 41 | unsigned char **new_buf, int *new_size, 42 | const unsigned char *compr_patch_buf, int compr_patch_buf_sz, 43 | int uncompr_ctrl_sz, int uncompr_diff_sz, int uncompr_xtra_sz); 44 | 45 | /* Same */ 46 | char *bspatch(const char *oldfile, const char *newfile, 47 | const char *patchfile); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* BSPATCHLIBH__ */ 54 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------- 3 | 4 | This program, "bzip2", the associated library "libbzip2", and all 5 | documentation, are copyright (C) 1996-2010 Julian R Seward. All 6 | rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions 10 | are met: 11 | 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | 2. The origin of this software must not be misrepresented; you must 16 | not claim that you wrote the original software. If you use this 17 | software in a product, an acknowledgment in the product 18 | documentation would be appreciated but is not required. 19 | 20 | 3. Altered source versions must be plainly marked as such, and must 21 | not be misrepresented as being the original software. 22 | 23 | 4. The name of the author may not be used to endorse or promote 24 | products derived from this software without specific prior written 25 | permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 28 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 31 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 33 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | 39 | Julian Seward, jseward@bzip.org 40 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 41 | 42 | -------------------------------------------------------------------------- 43 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/blocksort.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Block sorting machinery ---*/ 4 | /*--- blocksort.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #include "bzlib_private.h" 23 | 24 | /*---------------------------------------------*/ 25 | /*--- Fallback O(N log(N)^2) sorting ---*/ 26 | /*--- algorithm, for repetitive blocks ---*/ 27 | /*---------------------------------------------*/ 28 | 29 | /*---------------------------------------------*/ 30 | static 31 | __inline__ 32 | void fallbackSimpleSort ( UInt32* fmap, 33 | UInt32* eclass, 34 | Int32 lo, 35 | Int32 hi ) 36 | { 37 | Int32 i, j, tmp; 38 | UInt32 ec_tmp; 39 | 40 | if (lo == hi) return; 41 | 42 | if (hi - lo > 3) { 43 | for ( i = hi-4; i >= lo; i-- ) { 44 | tmp = fmap[i]; 45 | ec_tmp = eclass[tmp]; 46 | for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) 47 | fmap[j-4] = fmap[j]; 48 | fmap[j-4] = tmp; 49 | } 50 | } 51 | 52 | for ( i = hi-1; i >= lo; i-- ) { 53 | tmp = fmap[i]; 54 | ec_tmp = eclass[tmp]; 55 | for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) 56 | fmap[j-1] = fmap[j]; 57 | fmap[j-1] = tmp; 58 | } 59 | } 60 | 61 | 62 | /*---------------------------------------------*/ 63 | #define fswap(zz1, zz2) \ 64 | { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } 65 | 66 | #define fvswap(zzp1, zzp2, zzn) \ 67 | { \ 68 | Int32 yyp1 = (zzp1); \ 69 | Int32 yyp2 = (zzp2); \ 70 | Int32 yyn = (zzn); \ 71 | while (yyn > 0) { \ 72 | fswap(fmap[yyp1], fmap[yyp2]); \ 73 | yyp1++; yyp2++; yyn--; \ 74 | } \ 75 | } 76 | 77 | 78 | #define fmin(a,b) ((a) < (b)) ? (a) : (b) 79 | 80 | #define fpush(lz,hz) { stackLo[sp] = lz; \ 81 | stackHi[sp] = hz; \ 82 | sp++; } 83 | 84 | #define fpop(lz,hz) { sp--; \ 85 | lz = stackLo[sp]; \ 86 | hz = stackHi[sp]; } 87 | 88 | #define FALLBACK_QSORT_SMALL_THRESH 10 89 | #define FALLBACK_QSORT_STACK_SIZE 100 90 | 91 | 92 | static 93 | void fallbackQSort3 ( UInt32* fmap, 94 | UInt32* eclass, 95 | Int32 loSt, 96 | Int32 hiSt ) 97 | { 98 | Int32 unLo, unHi, ltLo, gtHi, n, m; 99 | Int32 sp, lo, hi; 100 | UInt32 med, r, r3; 101 | Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; 102 | Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; 103 | 104 | r = 0; 105 | 106 | sp = 0; 107 | fpush ( loSt, hiSt ); 108 | 109 | while (sp > 0) { 110 | 111 | AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); 112 | 113 | fpop ( lo, hi ); 114 | if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { 115 | fallbackSimpleSort ( fmap, eclass, lo, hi ); 116 | continue; 117 | } 118 | 119 | /* Random partitioning. Median of 3 sometimes fails to 120 | avoid bad cases. Median of 9 seems to help but 121 | looks rather expensive. This too seems to work but 122 | is cheaper. Guidance for the magic constants 123 | 7621 and 32768 is taken from Sedgewick's algorithms 124 | book, chapter 35. 125 | */ 126 | r = ((r * 7621) + 1) % 32768; 127 | r3 = r % 3; 128 | if (r3 == 0) med = eclass[fmap[lo]]; else 129 | if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else 130 | med = eclass[fmap[hi]]; 131 | 132 | unLo = ltLo = lo; 133 | unHi = gtHi = hi; 134 | 135 | while (1) { 136 | while (1) { 137 | if (unLo > unHi) break; 138 | n = (Int32)eclass[fmap[unLo]] - (Int32)med; 139 | if (n == 0) { 140 | fswap(fmap[unLo], fmap[ltLo]); 141 | ltLo++; unLo++; 142 | continue; 143 | }; 144 | if (n > 0) break; 145 | unLo++; 146 | } 147 | while (1) { 148 | if (unLo > unHi) break; 149 | n = (Int32)eclass[fmap[unHi]] - (Int32)med; 150 | if (n == 0) { 151 | fswap(fmap[unHi], fmap[gtHi]); 152 | gtHi--; unHi--; 153 | continue; 154 | }; 155 | if (n < 0) break; 156 | unHi--; 157 | } 158 | if (unLo > unHi) break; 159 | fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; 160 | } 161 | 162 | AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); 163 | 164 | if (gtHi < ltLo) continue; 165 | 166 | n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); 167 | m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); 168 | 169 | n = lo + unLo - ltLo - 1; 170 | m = hi - (gtHi - unHi) + 1; 171 | 172 | if (n - lo > hi - m) { 173 | fpush ( lo, n ); 174 | fpush ( m, hi ); 175 | } else { 176 | fpush ( m, hi ); 177 | fpush ( lo, n ); 178 | } 179 | } 180 | } 181 | 182 | #undef fmin 183 | #undef fpush 184 | #undef fpop 185 | #undef fswap 186 | #undef fvswap 187 | #undef FALLBACK_QSORT_SMALL_THRESH 188 | #undef FALLBACK_QSORT_STACK_SIZE 189 | 190 | 191 | /*---------------------------------------------*/ 192 | /* Pre: 193 | nblock > 0 194 | eclass exists for [0 .. nblock-1] 195 | ((UChar*)eclass) [0 .. nblock-1] holds block 196 | ptr exists for [0 .. nblock-1] 197 | 198 | Post: 199 | ((UChar*)eclass) [0 .. nblock-1] holds block 200 | All other areas of eclass destroyed 201 | fmap [0 .. nblock-1] holds sorted order 202 | bhtab [ 0 .. 2+(nblock/32) ] destroyed 203 | */ 204 | 205 | #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) 206 | #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) 207 | #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) 208 | #define WORD_BH(zz) bhtab[(zz) >> 5] 209 | #define UNALIGNED_BH(zz) ((zz) & 0x01f) 210 | 211 | static 212 | void fallbackSort ( UInt32* fmap, 213 | UInt32* eclass, 214 | UInt32* bhtab, 215 | Int32 nblock, 216 | Int32 verb ) 217 | { 218 | Int32 ftab[257]; 219 | Int32 ftabCopy[256]; 220 | Int32 H, i, j, k, l, r, cc, cc1; 221 | Int32 nNotDone; 222 | Int32 nBhtab; 223 | UChar* eclass8 = (UChar*)eclass; 224 | 225 | /*-- 226 | Initial 1-char radix sort to generate 227 | initial fmap and initial BH bits. 228 | --*/ 229 | if (verb >= 4) 230 | VPrintf0 ( " bucket sorting ...\n" ); 231 | for (i = 0; i < 257; i++) ftab[i] = 0; 232 | for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; 233 | for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; 234 | for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; 235 | 236 | for (i = 0; i < nblock; i++) { 237 | j = eclass8[i]; 238 | k = ftab[j] - 1; 239 | ftab[j] = k; 240 | fmap[k] = i; 241 | } 242 | 243 | nBhtab = 2 + (nblock / 32); 244 | for (i = 0; i < nBhtab; i++) bhtab[i] = 0; 245 | for (i = 0; i < 256; i++) SET_BH(ftab[i]); 246 | 247 | /*-- 248 | Inductively refine the buckets. Kind-of an 249 | "exponential radix sort" (!), inspired by the 250 | Manber-Myers suffix array construction algorithm. 251 | --*/ 252 | 253 | /*-- set sentinel bits for block-end detection --*/ 254 | for (i = 0; i < 32; i++) { 255 | SET_BH(nblock + 2*i); 256 | CLEAR_BH(nblock + 2*i + 1); 257 | } 258 | 259 | /*-- the log(N) loop --*/ 260 | H = 1; 261 | while (1) { 262 | 263 | if (verb >= 4) 264 | VPrintf1 ( " depth %6d has ", H ); 265 | 266 | j = 0; 267 | for (i = 0; i < nblock; i++) { 268 | if (ISSET_BH(i)) j = i; 269 | k = fmap[i] - H; if (k < 0) k += nblock; 270 | eclass[k] = j; 271 | } 272 | 273 | nNotDone = 0; 274 | r = -1; 275 | while (1) { 276 | 277 | /*-- find the next non-singleton bucket --*/ 278 | k = r + 1; 279 | while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; 280 | if (ISSET_BH(k)) { 281 | while (WORD_BH(k) == 0xffffffff) k += 32; 282 | while (ISSET_BH(k)) k++; 283 | } 284 | l = k - 1; 285 | if (l >= nblock) break; 286 | while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; 287 | if (!ISSET_BH(k)) { 288 | while (WORD_BH(k) == 0x00000000) k += 32; 289 | while (!ISSET_BH(k)) k++; 290 | } 291 | r = k - 1; 292 | if (r >= nblock) break; 293 | 294 | /*-- now [l, r] bracket current bucket --*/ 295 | if (r > l) { 296 | nNotDone += (r - l + 1); 297 | fallbackQSort3 ( fmap, eclass, l, r ); 298 | 299 | /*-- scan bucket and generate header bits-- */ 300 | cc = -1; 301 | for (i = l; i <= r; i++) { 302 | cc1 = eclass[fmap[i]]; 303 | if (cc != cc1) { SET_BH(i); cc = cc1; }; 304 | } 305 | } 306 | } 307 | 308 | if (verb >= 4) 309 | VPrintf1 ( "%6d unresolved strings\n", nNotDone ); 310 | 311 | H *= 2; 312 | if (H > nblock || nNotDone == 0) break; 313 | } 314 | 315 | /*-- 316 | Reconstruct the original block in 317 | eclass8 [0 .. nblock-1], since the 318 | previous phase destroyed it. 319 | --*/ 320 | if (verb >= 4) 321 | VPrintf0 ( " reconstructing block ...\n" ); 322 | j = 0; 323 | for (i = 0; i < nblock; i++) { 324 | while (ftabCopy[j] == 0) j++; 325 | ftabCopy[j]--; 326 | eclass8[fmap[i]] = (UChar)j; 327 | } 328 | AssertH ( j < 256, 1005 ); 329 | } 330 | 331 | #undef SET_BH 332 | #undef CLEAR_BH 333 | #undef ISSET_BH 334 | #undef WORD_BH 335 | #undef UNALIGNED_BH 336 | 337 | 338 | /*---------------------------------------------*/ 339 | /*--- The main, O(N^2 log(N)) sorting ---*/ 340 | /*--- algorithm. Faster for "normal" ---*/ 341 | /*--- non-repetitive blocks. ---*/ 342 | /*---------------------------------------------*/ 343 | 344 | /*---------------------------------------------*/ 345 | static 346 | __inline__ 347 | Bool mainGtU ( UInt32 i1, 348 | UInt32 i2, 349 | UChar* block, 350 | UInt16* quadrant, 351 | UInt32 nblock, 352 | Int32* budget ) 353 | { 354 | Int32 k; 355 | UChar c1, c2; 356 | UInt16 s1, s2; 357 | 358 | AssertD ( i1 != i2, "mainGtU" ); 359 | /* 1 */ 360 | c1 = block[i1]; c2 = block[i2]; 361 | if (c1 != c2) return (c1 > c2); 362 | i1++; i2++; 363 | /* 2 */ 364 | c1 = block[i1]; c2 = block[i2]; 365 | if (c1 != c2) return (c1 > c2); 366 | i1++; i2++; 367 | /* 3 */ 368 | c1 = block[i1]; c2 = block[i2]; 369 | if (c1 != c2) return (c1 > c2); 370 | i1++; i2++; 371 | /* 4 */ 372 | c1 = block[i1]; c2 = block[i2]; 373 | if (c1 != c2) return (c1 > c2); 374 | i1++; i2++; 375 | /* 5 */ 376 | c1 = block[i1]; c2 = block[i2]; 377 | if (c1 != c2) return (c1 > c2); 378 | i1++; i2++; 379 | /* 6 */ 380 | c1 = block[i1]; c2 = block[i2]; 381 | if (c1 != c2) return (c1 > c2); 382 | i1++; i2++; 383 | /* 7 */ 384 | c1 = block[i1]; c2 = block[i2]; 385 | if (c1 != c2) return (c1 > c2); 386 | i1++; i2++; 387 | /* 8 */ 388 | c1 = block[i1]; c2 = block[i2]; 389 | if (c1 != c2) return (c1 > c2); 390 | i1++; i2++; 391 | /* 9 */ 392 | c1 = block[i1]; c2 = block[i2]; 393 | if (c1 != c2) return (c1 > c2); 394 | i1++; i2++; 395 | /* 10 */ 396 | c1 = block[i1]; c2 = block[i2]; 397 | if (c1 != c2) return (c1 > c2); 398 | i1++; i2++; 399 | /* 11 */ 400 | c1 = block[i1]; c2 = block[i2]; 401 | if (c1 != c2) return (c1 > c2); 402 | i1++; i2++; 403 | /* 12 */ 404 | c1 = block[i1]; c2 = block[i2]; 405 | if (c1 != c2) return (c1 > c2); 406 | i1++; i2++; 407 | 408 | k = nblock + 8; 409 | 410 | do { 411 | /* 1 */ 412 | c1 = block[i1]; c2 = block[i2]; 413 | if (c1 != c2) return (c1 > c2); 414 | s1 = quadrant[i1]; s2 = quadrant[i2]; 415 | if (s1 != s2) return (s1 > s2); 416 | i1++; i2++; 417 | /* 2 */ 418 | c1 = block[i1]; c2 = block[i2]; 419 | if (c1 != c2) return (c1 > c2); 420 | s1 = quadrant[i1]; s2 = quadrant[i2]; 421 | if (s1 != s2) return (s1 > s2); 422 | i1++; i2++; 423 | /* 3 */ 424 | c1 = block[i1]; c2 = block[i2]; 425 | if (c1 != c2) return (c1 > c2); 426 | s1 = quadrant[i1]; s2 = quadrant[i2]; 427 | if (s1 != s2) return (s1 > s2); 428 | i1++; i2++; 429 | /* 4 */ 430 | c1 = block[i1]; c2 = block[i2]; 431 | if (c1 != c2) return (c1 > c2); 432 | s1 = quadrant[i1]; s2 = quadrant[i2]; 433 | if (s1 != s2) return (s1 > s2); 434 | i1++; i2++; 435 | /* 5 */ 436 | c1 = block[i1]; c2 = block[i2]; 437 | if (c1 != c2) return (c1 > c2); 438 | s1 = quadrant[i1]; s2 = quadrant[i2]; 439 | if (s1 != s2) return (s1 > s2); 440 | i1++; i2++; 441 | /* 6 */ 442 | c1 = block[i1]; c2 = block[i2]; 443 | if (c1 != c2) return (c1 > c2); 444 | s1 = quadrant[i1]; s2 = quadrant[i2]; 445 | if (s1 != s2) return (s1 > s2); 446 | i1++; i2++; 447 | /* 7 */ 448 | c1 = block[i1]; c2 = block[i2]; 449 | if (c1 != c2) return (c1 > c2); 450 | s1 = quadrant[i1]; s2 = quadrant[i2]; 451 | if (s1 != s2) return (s1 > s2); 452 | i1++; i2++; 453 | /* 8 */ 454 | c1 = block[i1]; c2 = block[i2]; 455 | if (c1 != c2) return (c1 > c2); 456 | s1 = quadrant[i1]; s2 = quadrant[i2]; 457 | if (s1 != s2) return (s1 > s2); 458 | i1++; i2++; 459 | 460 | if (i1 >= nblock) i1 -= nblock; 461 | if (i2 >= nblock) i2 -= nblock; 462 | 463 | k -= 8; 464 | (*budget)--; 465 | } 466 | while (k >= 0); 467 | 468 | return False; 469 | } 470 | 471 | 472 | /*---------------------------------------------*/ 473 | /*-- 474 | Knuth's increments seem to work better 475 | than Incerpi-Sedgewick here. Possibly 476 | because the number of elems to sort is 477 | usually small, typically <= 20. 478 | --*/ 479 | static 480 | Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, 481 | 9841, 29524, 88573, 265720, 482 | 797161, 2391484 }; 483 | 484 | static 485 | void mainSimpleSort ( UInt32* ptr, 486 | UChar* block, 487 | UInt16* quadrant, 488 | Int32 nblock, 489 | Int32 lo, 490 | Int32 hi, 491 | Int32 d, 492 | Int32* budget ) 493 | { 494 | Int32 i, j, h, bigN, hp; 495 | UInt32 v; 496 | 497 | bigN = hi - lo + 1; 498 | if (bigN < 2) return; 499 | 500 | hp = 0; 501 | while (incs[hp] < bigN) hp++; 502 | hp--; 503 | 504 | for (; hp >= 0; hp--) { 505 | h = incs[hp]; 506 | 507 | i = lo + h; 508 | while (True) { 509 | 510 | /*-- copy 1 --*/ 511 | if (i > hi) break; 512 | v = ptr[i]; 513 | j = i; 514 | while ( mainGtU ( 515 | ptr[j-h]+d, v+d, block, quadrant, nblock, budget 516 | ) ) { 517 | ptr[j] = ptr[j-h]; 518 | j = j - h; 519 | if (j <= (lo + h - 1)) break; 520 | } 521 | ptr[j] = v; 522 | i++; 523 | 524 | /*-- copy 2 --*/ 525 | if (i > hi) break; 526 | v = ptr[i]; 527 | j = i; 528 | while ( mainGtU ( 529 | ptr[j-h]+d, v+d, block, quadrant, nblock, budget 530 | ) ) { 531 | ptr[j] = ptr[j-h]; 532 | j = j - h; 533 | if (j <= (lo + h - 1)) break; 534 | } 535 | ptr[j] = v; 536 | i++; 537 | 538 | /*-- copy 3 --*/ 539 | if (i > hi) break; 540 | v = ptr[i]; 541 | j = i; 542 | while ( mainGtU ( 543 | ptr[j-h]+d, v+d, block, quadrant, nblock, budget 544 | ) ) { 545 | ptr[j] = ptr[j-h]; 546 | j = j - h; 547 | if (j <= (lo + h - 1)) break; 548 | } 549 | ptr[j] = v; 550 | i++; 551 | 552 | if (*budget < 0) return; 553 | } 554 | } 555 | } 556 | 557 | 558 | /*---------------------------------------------*/ 559 | /*-- 560 | The following is an implementation of 561 | an elegant 3-way quicksort for strings, 562 | described in a paper "Fast Algorithms for 563 | Sorting and Searching Strings", by Robert 564 | Sedgewick and Jon L. Bentley. 565 | --*/ 566 | 567 | #define mswap(zz1, zz2) \ 568 | { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } 569 | 570 | #define mvswap(zzp1, zzp2, zzn) \ 571 | { \ 572 | Int32 yyp1 = (zzp1); \ 573 | Int32 yyp2 = (zzp2); \ 574 | Int32 yyn = (zzn); \ 575 | while (yyn > 0) { \ 576 | mswap(ptr[yyp1], ptr[yyp2]); \ 577 | yyp1++; yyp2++; yyn--; \ 578 | } \ 579 | } 580 | 581 | static 582 | __inline__ 583 | UChar mmed3 ( UChar a, UChar b, UChar c ) 584 | { 585 | UChar t; 586 | if (a > b) { t = a; a = b; b = t; }; 587 | if (b > c) { 588 | b = c; 589 | if (a > b) b = a; 590 | } 591 | return b; 592 | } 593 | 594 | #define mmin(a,b) ((a) < (b)) ? (a) : (b) 595 | 596 | #define mpush(lz,hz,dz) { stackLo[sp] = lz; \ 597 | stackHi[sp] = hz; \ 598 | stackD [sp] = dz; \ 599 | sp++; } 600 | 601 | #define mpop(lz,hz,dz) { sp--; \ 602 | lz = stackLo[sp]; \ 603 | hz = stackHi[sp]; \ 604 | dz = stackD [sp]; } 605 | 606 | 607 | #define mnextsize(az) (nextHi[az]-nextLo[az]) 608 | 609 | #define mnextswap(az,bz) \ 610 | { Int32 tz; \ 611 | tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ 612 | tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ 613 | tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } 614 | 615 | 616 | #define MAIN_QSORT_SMALL_THRESH 20 617 | #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) 618 | #define MAIN_QSORT_STACK_SIZE 100 619 | 620 | static 621 | void mainQSort3 ( UInt32* ptr, 622 | UChar* block, 623 | UInt16* quadrant, 624 | Int32 nblock, 625 | Int32 loSt, 626 | Int32 hiSt, 627 | Int32 dSt, 628 | Int32* budget ) 629 | { 630 | Int32 unLo, unHi, ltLo, gtHi, n, m, med; 631 | Int32 sp, lo, hi, d; 632 | 633 | Int32 stackLo[MAIN_QSORT_STACK_SIZE]; 634 | Int32 stackHi[MAIN_QSORT_STACK_SIZE]; 635 | Int32 stackD [MAIN_QSORT_STACK_SIZE]; 636 | 637 | Int32 nextLo[3]; 638 | Int32 nextHi[3]; 639 | Int32 nextD [3]; 640 | 641 | sp = 0; 642 | mpush ( loSt, hiSt, dSt ); 643 | 644 | while (sp > 0) { 645 | 646 | AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); 647 | 648 | mpop ( lo, hi, d ); 649 | if (hi - lo < MAIN_QSORT_SMALL_THRESH || 650 | d > MAIN_QSORT_DEPTH_THRESH) { 651 | mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); 652 | if (*budget < 0) return; 653 | continue; 654 | } 655 | 656 | med = (Int32) 657 | mmed3 ( block[ptr[ lo ]+d], 658 | block[ptr[ hi ]+d], 659 | block[ptr[ (lo+hi)>>1 ]+d] ); 660 | 661 | unLo = ltLo = lo; 662 | unHi = gtHi = hi; 663 | 664 | while (True) { 665 | while (True) { 666 | if (unLo > unHi) break; 667 | n = ((Int32)block[ptr[unLo]+d]) - med; 668 | if (n == 0) { 669 | mswap(ptr[unLo], ptr[ltLo]); 670 | ltLo++; unLo++; continue; 671 | }; 672 | if (n > 0) break; 673 | unLo++; 674 | } 675 | while (True) { 676 | if (unLo > unHi) break; 677 | n = ((Int32)block[ptr[unHi]+d]) - med; 678 | if (n == 0) { 679 | mswap(ptr[unHi], ptr[gtHi]); 680 | gtHi--; unHi--; continue; 681 | }; 682 | if (n < 0) break; 683 | unHi--; 684 | } 685 | if (unLo > unHi) break; 686 | mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; 687 | } 688 | 689 | AssertD ( unHi == unLo-1, "mainQSort3(2)" ); 690 | 691 | if (gtHi < ltLo) { 692 | mpush(lo, hi, d+1 ); 693 | continue; 694 | } 695 | 696 | n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); 697 | m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); 698 | 699 | n = lo + unLo - ltLo - 1; 700 | m = hi - (gtHi - unHi) + 1; 701 | 702 | nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; 703 | nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; 704 | nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; 705 | 706 | if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); 707 | if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); 708 | if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); 709 | 710 | AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); 711 | AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); 712 | 713 | mpush (nextLo[0], nextHi[0], nextD[0]); 714 | mpush (nextLo[1], nextHi[1], nextD[1]); 715 | mpush (nextLo[2], nextHi[2], nextD[2]); 716 | } 717 | } 718 | 719 | #undef mswap 720 | #undef mvswap 721 | #undef mpush 722 | #undef mpop 723 | #undef mmin 724 | #undef mnextsize 725 | #undef mnextswap 726 | #undef MAIN_QSORT_SMALL_THRESH 727 | #undef MAIN_QSORT_DEPTH_THRESH 728 | #undef MAIN_QSORT_STACK_SIZE 729 | 730 | 731 | /*---------------------------------------------*/ 732 | /* Pre: 733 | nblock > N_OVERSHOOT 734 | block32 exists for [0 .. nblock-1 +N_OVERSHOOT] 735 | ((UChar*)block32) [0 .. nblock-1] holds block 736 | ptr exists for [0 .. nblock-1] 737 | 738 | Post: 739 | ((UChar*)block32) [0 .. nblock-1] holds block 740 | All other areas of block32 destroyed 741 | ftab [0 .. 65536 ] destroyed 742 | ptr [0 .. nblock-1] holds sorted order 743 | if (*budget < 0), sorting was abandoned 744 | */ 745 | 746 | #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) 747 | #define SETMASK (1 << 21) 748 | #define CLEARMASK (~(SETMASK)) 749 | 750 | static 751 | void mainSort ( UInt32* ptr, 752 | UChar* block, 753 | UInt16* quadrant, 754 | UInt32* ftab, 755 | Int32 nblock, 756 | Int32 verb, 757 | Int32* budget ) 758 | { 759 | Int32 i, j, k, ss, sb; 760 | Int32 runningOrder[256]; 761 | Bool bigDone[256]; 762 | Int32 copyStart[256]; 763 | Int32 copyEnd [256]; 764 | UChar c1; 765 | Int32 numQSorted; 766 | UInt16 s; 767 | if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); 768 | 769 | /*-- set up the 2-byte frequency table --*/ 770 | for (i = 65536; i >= 0; i--) ftab[i] = 0; 771 | 772 | j = block[0] << 8; 773 | i = nblock-1; 774 | for (; i >= 3; i -= 4) { 775 | quadrant[i] = 0; 776 | j = (j >> 8) | ( ((UInt16)block[i]) << 8); 777 | ftab[j]++; 778 | quadrant[i-1] = 0; 779 | j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); 780 | ftab[j]++; 781 | quadrant[i-2] = 0; 782 | j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); 783 | ftab[j]++; 784 | quadrant[i-3] = 0; 785 | j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); 786 | ftab[j]++; 787 | } 788 | for (; i >= 0; i--) { 789 | quadrant[i] = 0; 790 | j = (j >> 8) | ( ((UInt16)block[i]) << 8); 791 | ftab[j]++; 792 | } 793 | 794 | /*-- (emphasises close relationship of block & quadrant) --*/ 795 | for (i = 0; i < BZ_N_OVERSHOOT; i++) { 796 | block [nblock+i] = block[i]; 797 | quadrant[nblock+i] = 0; 798 | } 799 | 800 | if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); 801 | 802 | /*-- Complete the initial radix sort --*/ 803 | for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; 804 | 805 | s = block[0] << 8; 806 | i = nblock-1; 807 | for (; i >= 3; i -= 4) { 808 | s = (s >> 8) | (block[i] << 8); 809 | j = ftab[s] -1; 810 | ftab[s] = j; 811 | ptr[j] = i; 812 | s = (s >> 8) | (block[i-1] << 8); 813 | j = ftab[s] -1; 814 | ftab[s] = j; 815 | ptr[j] = i-1; 816 | s = (s >> 8) | (block[i-2] << 8); 817 | j = ftab[s] -1; 818 | ftab[s] = j; 819 | ptr[j] = i-2; 820 | s = (s >> 8) | (block[i-3] << 8); 821 | j = ftab[s] -1; 822 | ftab[s] = j; 823 | ptr[j] = i-3; 824 | } 825 | for (; i >= 0; i--) { 826 | s = (s >> 8) | (block[i] << 8); 827 | j = ftab[s] -1; 828 | ftab[s] = j; 829 | ptr[j] = i; 830 | } 831 | 832 | /*-- 833 | Now ftab contains the first loc of every small bucket. 834 | Calculate the running order, from smallest to largest 835 | big bucket. 836 | --*/ 837 | for (i = 0; i <= 255; i++) { 838 | bigDone [i] = False; 839 | runningOrder[i] = i; 840 | } 841 | 842 | { 843 | Int32 vv; 844 | Int32 h = 1; 845 | do h = 3 * h + 1; while (h <= 256); 846 | do { 847 | h = h / 3; 848 | for (i = h; i <= 255; i++) { 849 | vv = runningOrder[i]; 850 | j = i; 851 | while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { 852 | runningOrder[j] = runningOrder[j-h]; 853 | j = j - h; 854 | if (j <= (h - 1)) goto zero; 855 | } 856 | zero: 857 | runningOrder[j] = vv; 858 | } 859 | } while (h != 1); 860 | } 861 | 862 | /*-- 863 | The main sorting loop. 864 | --*/ 865 | 866 | numQSorted = 0; 867 | 868 | for (i = 0; i <= 255; i++) { 869 | 870 | /*-- 871 | Process big buckets, starting with the least full. 872 | Basically this is a 3-step process in which we call 873 | mainQSort3 to sort the small buckets [ss, j], but 874 | also make a big effort to avoid the calls if we can. 875 | --*/ 876 | ss = runningOrder[i]; 877 | 878 | /*-- 879 | Step 1: 880 | Complete the big bucket [ss] by quicksorting 881 | any unsorted small buckets [ss, j], for j != ss. 882 | Hopefully previous pointer-scanning phases have already 883 | completed many of the small buckets [ss, j], so 884 | we don't have to sort them at all. 885 | --*/ 886 | for (j = 0; j <= 255; j++) { 887 | if (j != ss) { 888 | sb = (ss << 8) + j; 889 | if ( ! (ftab[sb] & SETMASK) ) { 890 | Int32 lo = ftab[sb] & CLEARMASK; 891 | Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; 892 | if (hi > lo) { 893 | if (verb >= 4) 894 | VPrintf4 ( " qsort [0x%x, 0x%x] " 895 | "done %d this %d\n", 896 | ss, j, numQSorted, hi - lo + 1 ); 897 | mainQSort3 ( 898 | ptr, block, quadrant, nblock, 899 | lo, hi, BZ_N_RADIX, budget 900 | ); 901 | numQSorted += (hi - lo + 1); 902 | if (*budget < 0) return; 903 | } 904 | } 905 | ftab[sb] |= SETMASK; 906 | } 907 | } 908 | 909 | AssertH ( !bigDone[ss], 1006 ); 910 | 911 | /*-- 912 | Step 2: 913 | Now scan this big bucket [ss] so as to synthesise the 914 | sorted order for small buckets [t, ss] for all t, 915 | including, magically, the bucket [ss,ss] too. 916 | This will avoid doing Real Work in subsequent Step 1's. 917 | --*/ 918 | { 919 | for (j = 0; j <= 255; j++) { 920 | copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; 921 | copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; 922 | } 923 | for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { 924 | k = ptr[j]-1; if (k < 0) k += nblock; 925 | c1 = block[k]; 926 | if (!bigDone[c1]) 927 | ptr[ copyStart[c1]++ ] = k; 928 | } 929 | for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { 930 | k = ptr[j]-1; if (k < 0) k += nblock; 931 | c1 = block[k]; 932 | if (!bigDone[c1]) 933 | ptr[ copyEnd[c1]-- ] = k; 934 | } 935 | } 936 | 937 | AssertH ( (copyStart[ss]-1 == copyEnd[ss]) 938 | || 939 | /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. 940 | Necessity for this case is demonstrated by compressing 941 | a sequence of approximately 48.5 million of character 942 | 251; 1.0.0/1.0.1 will then die here. */ 943 | (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), 944 | 1007 ) 945 | 946 | for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; 947 | 948 | /*-- 949 | Step 3: 950 | The [ss] big bucket is now done. Record this fact, 951 | and update the quadrant descriptors. Remember to 952 | update quadrants in the overshoot area too, if 953 | necessary. The "if (i < 255)" test merely skips 954 | this updating for the last bucket processed, since 955 | updating for the last bucket is pointless. 956 | 957 | The quadrant array provides a way to incrementally 958 | cache sort orderings, as they appear, so as to 959 | make subsequent comparisons in fullGtU() complete 960 | faster. For repetitive blocks this makes a big 961 | difference (but not big enough to be able to avoid 962 | the fallback sorting mechanism, exponential radix sort). 963 | 964 | The precise meaning is: at all times: 965 | 966 | for 0 <= i < nblock and 0 <= j <= nblock 967 | 968 | if block[i] != block[j], 969 | 970 | then the relative values of quadrant[i] and 971 | quadrant[j] are meaningless. 972 | 973 | else { 974 | if quadrant[i] < quadrant[j] 975 | then the string starting at i lexicographically 976 | precedes the string starting at j 977 | 978 | else if quadrant[i] > quadrant[j] 979 | then the string starting at j lexicographically 980 | precedes the string starting at i 981 | 982 | else 983 | the relative ordering of the strings starting 984 | at i and j has not yet been determined. 985 | } 986 | --*/ 987 | bigDone[ss] = True; 988 | 989 | if (i < 255) { 990 | Int32 bbStart = ftab[ss << 8] & CLEARMASK; 991 | Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; 992 | Int32 shifts = 0; 993 | 994 | while ((bbSize >> shifts) > 65534) shifts++; 995 | 996 | for (j = bbSize-1; j >= 0; j--) { 997 | Int32 a2update = ptr[bbStart + j]; 998 | UInt16 qVal = (UInt16)(j >> shifts); 999 | quadrant[a2update] = qVal; 1000 | if (a2update < BZ_N_OVERSHOOT) 1001 | quadrant[a2update + nblock] = qVal; 1002 | } 1003 | AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); 1004 | } 1005 | 1006 | } 1007 | 1008 | if (verb >= 4) 1009 | VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", 1010 | nblock, numQSorted, nblock - numQSorted ); 1011 | } 1012 | 1013 | #undef BIGFREQ 1014 | #undef SETMASK 1015 | #undef CLEARMASK 1016 | 1017 | 1018 | /*---------------------------------------------*/ 1019 | /* Pre: 1020 | nblock > 0 1021 | arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] 1022 | ((UChar*)arr2) [0 .. nblock-1] holds block 1023 | arr1 exists for [0 .. nblock-1] 1024 | 1025 | Post: 1026 | ((UChar*)arr2) [0 .. nblock-1] holds block 1027 | All other areas of block destroyed 1028 | ftab [ 0 .. 65536 ] destroyed 1029 | arr1 [0 .. nblock-1] holds sorted order 1030 | */ 1031 | void BZ2_blockSort ( EState* s ) 1032 | { 1033 | UInt32* ptr = s->ptr; 1034 | UChar* block = s->block; 1035 | UInt32* ftab = s->ftab; 1036 | Int32 nblock = s->nblock; 1037 | Int32 verb = s->verbosity; 1038 | Int32 wfact = s->workFactor; 1039 | UInt16* quadrant; 1040 | Int32 budget; 1041 | Int32 budgetInit; 1042 | Int32 i; 1043 | 1044 | if (nblock < 10000) { 1045 | fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); 1046 | } else { 1047 | /* Calculate the location for quadrant, remembering to get 1048 | the alignment right. Assumes that &(block[0]) is at least 1049 | 2-byte aligned -- this should be ok since block is really 1050 | the first section of arr2. 1051 | */ 1052 | i = nblock+BZ_N_OVERSHOOT; 1053 | if (i & 1) i++; 1054 | quadrant = (UInt16*)(&(block[i])); 1055 | 1056 | /* (wfact-1) / 3 puts the default-factor-30 1057 | transition point at very roughly the same place as 1058 | with v0.1 and v0.9.0. 1059 | Not that it particularly matters any more, since the 1060 | resulting compressed stream is now the same regardless 1061 | of whether or not we use the main sort or fallback sort. 1062 | */ 1063 | if (wfact < 1 ) wfact = 1; 1064 | if (wfact > 100) wfact = 100; 1065 | budgetInit = nblock * ((wfact-1) / 3); 1066 | budget = budgetInit; 1067 | 1068 | mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); 1069 | if (verb >= 3) 1070 | VPrintf3 ( " %d work, %d block, ratio %5.2f\n", 1071 | budgetInit - budget, 1072 | nblock, 1073 | (float)(budgetInit - budget) / 1074 | (float)(nblock==0 ? 1 : nblock) ); 1075 | if (budget < 0) { 1076 | if (verb >= 2) 1077 | VPrintf0 ( " too repetitive; using fallback" 1078 | " sorting algorithm\n" ); 1079 | fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); 1080 | } 1081 | } 1082 | 1083 | s->origPtr = -1; 1084 | for (i = 0; i < s->nblock; i++) 1085 | if (ptr[i] == 0) 1086 | { s->origPtr = i; break; }; 1087 | 1088 | AssertH( s->origPtr != -1, 1003 ); 1089 | } 1090 | 1091 | 1092 | /*-------------------------------------------------------------*/ 1093 | /*--- end blocksort.c ---*/ 1094 | /*-------------------------------------------------------------*/ 1095 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/bzlib.h: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Public header file for the library. ---*/ 4 | /*--- bzlib.h ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #ifndef _BZLIB_H 23 | #define _BZLIB_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #define BZ_RUN 0 30 | #define BZ_FLUSH 1 31 | #define BZ_FINISH 2 32 | 33 | #define BZ_OK 0 34 | #define BZ_RUN_OK 1 35 | #define BZ_FLUSH_OK 2 36 | #define BZ_FINISH_OK 3 37 | #define BZ_STREAM_END 4 38 | #define BZ_SEQUENCE_ERROR (-1) 39 | #define BZ_PARAM_ERROR (-2) 40 | #define BZ_MEM_ERROR (-3) 41 | #define BZ_DATA_ERROR (-4) 42 | #define BZ_DATA_ERROR_MAGIC (-5) 43 | #define BZ_IO_ERROR (-6) 44 | #define BZ_UNEXPECTED_EOF (-7) 45 | #define BZ_OUTBUFF_FULL (-8) 46 | #define BZ_CONFIG_ERROR (-9) 47 | 48 | typedef 49 | struct { 50 | char *next_in; 51 | unsigned int avail_in; 52 | unsigned int total_in_lo32; 53 | unsigned int total_in_hi32; 54 | 55 | char *next_out; 56 | unsigned int avail_out; 57 | unsigned int total_out_lo32; 58 | unsigned int total_out_hi32; 59 | 60 | void *state; 61 | 62 | void *(*bzalloc)(void *,int,int); 63 | void (*bzfree)(void *,void *); 64 | void *opaque; 65 | } 66 | bz_stream; 67 | 68 | 69 | #ifndef BZ_IMPORT 70 | #define BZ_EXPORT 71 | #endif 72 | 73 | #ifndef BZ_NO_STDIO 74 | /* Need a definitition for FILE */ 75 | #include 76 | #endif 77 | 78 | #ifdef _WIN32 79 | # include 80 | # ifdef small 81 | /* windows.h define small to char */ 82 | # undef small 83 | # endif 84 | # ifdef BZ_EXPORT 85 | # define BZ_API(func) WINAPI func 86 | # define BZ_EXTERN extern 87 | # else 88 | /* import windows dll dynamically */ 89 | # define BZ_API(func) (WINAPI * func) 90 | # define BZ_EXTERN 91 | # endif 92 | #else 93 | # define BZ_API(func) func 94 | # define BZ_EXTERN extern 95 | #endif 96 | 97 | 98 | /*-- Core (low-level) library functions --*/ 99 | 100 | BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 101 | bz_stream* strm, 102 | int blockSize100k, 103 | int verbosity, 104 | int workFactor 105 | ); 106 | 107 | BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 108 | bz_stream* strm, 109 | int action 110 | ); 111 | 112 | BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 113 | bz_stream* strm 114 | ); 115 | 116 | BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 117 | bz_stream *strm, 118 | int verbosity, 119 | int small 120 | ); 121 | 122 | BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 123 | bz_stream* strm 124 | ); 125 | 126 | BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 127 | bz_stream *strm 128 | ); 129 | 130 | 131 | 132 | /*-- High(er) level library functions --*/ 133 | 134 | #ifndef BZ_NO_STDIO 135 | #define BZ_MAX_UNUSED 5000 136 | 137 | typedef void BZFILE; 138 | 139 | BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 140 | int* bzerror, 141 | FILE* f, 142 | int verbosity, 143 | int small, 144 | void* unused, 145 | int nUnused 146 | ); 147 | 148 | BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 149 | int* bzerror, 150 | BZFILE* b 151 | ); 152 | 153 | BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 154 | int* bzerror, 155 | BZFILE* b, 156 | void** unused, 157 | int* nUnused 158 | ); 159 | 160 | BZ_EXTERN int BZ_API(BZ2_bzRead) ( 161 | int* bzerror, 162 | BZFILE* b, 163 | void* buf, 164 | int len 165 | ); 166 | 167 | BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 168 | int* bzerror, 169 | FILE* f, 170 | int blockSize100k, 171 | int verbosity, 172 | int workFactor 173 | ); 174 | 175 | BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 176 | int* bzerror, 177 | BZFILE* b, 178 | void* buf, 179 | int len 180 | ); 181 | 182 | BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 183 | int* bzerror, 184 | BZFILE* b, 185 | int abandon, 186 | unsigned int* nbytes_in, 187 | unsigned int* nbytes_out 188 | ); 189 | 190 | BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 191 | int* bzerror, 192 | BZFILE* b, 193 | int abandon, 194 | unsigned int* nbytes_in_lo32, 195 | unsigned int* nbytes_in_hi32, 196 | unsigned int* nbytes_out_lo32, 197 | unsigned int* nbytes_out_hi32 198 | ); 199 | #endif 200 | 201 | 202 | /*-- Utility functions --*/ 203 | 204 | BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 205 | char* dest, 206 | unsigned int* destLen, 207 | char* source, 208 | unsigned int sourceLen, 209 | int blockSize100k, 210 | int verbosity, 211 | int workFactor 212 | ); 213 | 214 | BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 215 | char* dest, 216 | unsigned int* destLen, 217 | char* source, 218 | unsigned int sourceLen, 219 | int small, 220 | int verbosity 221 | ); 222 | 223 | 224 | /*-- 225 | Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) 226 | to support better zlib compatibility. 227 | This code is not _officially_ part of libbzip2 (yet); 228 | I haven't tested it, documented it, or considered the 229 | threading-safeness of it. 230 | If this code breaks, please contact both Yoshioka and me. 231 | --*/ 232 | 233 | BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( 234 | void 235 | ); 236 | 237 | #ifndef BZ_NO_STDIO 238 | BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( 239 | const char *path, 240 | const char *mode 241 | ); 242 | 243 | BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( 244 | int fd, 245 | const char *mode 246 | ); 247 | 248 | BZ_EXTERN int BZ_API(BZ2_bzread) ( 249 | BZFILE* b, 250 | void* buf, 251 | int len 252 | ); 253 | 254 | BZ_EXTERN int BZ_API(BZ2_bzwrite) ( 255 | BZFILE* b, 256 | void* buf, 257 | int len 258 | ); 259 | 260 | BZ_EXTERN int BZ_API(BZ2_bzflush) ( 261 | BZFILE* b 262 | ); 263 | 264 | BZ_EXTERN void BZ_API(BZ2_bzclose) ( 265 | BZFILE* b 266 | ); 267 | 268 | BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( 269 | BZFILE *b, 270 | int *errnum 271 | ); 272 | #endif 273 | 274 | #ifdef __cplusplus 275 | } 276 | #endif 277 | 278 | #endif 279 | 280 | /*-------------------------------------------------------------*/ 281 | /*--- end bzlib.h ---*/ 282 | /*-------------------------------------------------------------*/ 283 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/bzlib_private.h: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Private header file for the library. ---*/ 4 | /*--- bzlib_private.h ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #ifndef _BZLIB_PRIVATE_H 23 | #define _BZLIB_PRIVATE_H 24 | 25 | #include 26 | 27 | #ifndef BZ_NO_STDIO 28 | #include 29 | #include 30 | #include 31 | #endif 32 | 33 | #include "bzlib.h" 34 | 35 | 36 | 37 | /*-- General stuff. --*/ 38 | 39 | #define BZ_VERSION "1.0.6, 6-Sept-2010" 40 | 41 | typedef char Char; 42 | typedef unsigned char Bool; 43 | typedef unsigned char UChar; 44 | typedef int Int32; 45 | typedef unsigned int UInt32; 46 | typedef short Int16; 47 | typedef unsigned short UInt16; 48 | 49 | #define True ((Bool)1) 50 | #define False ((Bool)0) 51 | 52 | #ifndef __GNUC__ 53 | #define __inline__ /* */ 54 | #endif 55 | 56 | #ifndef BZ_NO_STDIO 57 | 58 | extern void BZ2_bz__AssertH__fail ( int errcode ); 59 | #define AssertH(cond,errcode) \ 60 | { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } 61 | 62 | #if BZ_DEBUG 63 | #define AssertD(cond,msg) \ 64 | { if (!(cond)) { \ 65 | fprintf ( stderr, \ 66 | "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ 67 | exit(1); \ 68 | }} 69 | #else 70 | #define AssertD(cond,msg) /* */ 71 | #endif 72 | 73 | #define VPrintf0(zf) \ 74 | fprintf(stderr,zf) 75 | #define VPrintf1(zf,za1) \ 76 | fprintf(stderr,zf,za1) 77 | #define VPrintf2(zf,za1,za2) \ 78 | fprintf(stderr,zf,za1,za2) 79 | #define VPrintf3(zf,za1,za2,za3) \ 80 | fprintf(stderr,zf,za1,za2,za3) 81 | #define VPrintf4(zf,za1,za2,za3,za4) \ 82 | fprintf(stderr,zf,za1,za2,za3,za4) 83 | #define VPrintf5(zf,za1,za2,za3,za4,za5) \ 84 | fprintf(stderr,zf,za1,za2,za3,za4,za5) 85 | 86 | #else 87 | 88 | extern void bz_internal_error ( int errcode ); 89 | #define AssertH(cond,errcode) \ 90 | { if (!(cond)) bz_internal_error ( errcode ); } 91 | #define AssertD(cond,msg) do { } while (0) 92 | #define VPrintf0(zf) do { } while (0) 93 | #define VPrintf1(zf,za1) do { } while (0) 94 | #define VPrintf2(zf,za1,za2) do { } while (0) 95 | #define VPrintf3(zf,za1,za2,za3) do { } while (0) 96 | #define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) 97 | #define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) 98 | 99 | #endif 100 | 101 | 102 | #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) 103 | #define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) 104 | 105 | 106 | /*-- Header bytes. --*/ 107 | 108 | #define BZ_HDR_B 0x42 /* 'B' */ 109 | #define BZ_HDR_Z 0x5a /* 'Z' */ 110 | #define BZ_HDR_h 0x68 /* 'h' */ 111 | #define BZ_HDR_0 0x30 /* '0' */ 112 | 113 | /*-- Constants for the back end. --*/ 114 | 115 | #define BZ_MAX_ALPHA_SIZE 258 116 | #define BZ_MAX_CODE_LEN 23 117 | 118 | #define BZ_RUNA 0 119 | #define BZ_RUNB 1 120 | 121 | #define BZ_N_GROUPS 6 122 | #define BZ_G_SIZE 50 123 | #define BZ_N_ITERS 4 124 | 125 | #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) 126 | 127 | 128 | 129 | /*-- Stuff for randomising repetitive blocks. --*/ 130 | 131 | extern Int32 BZ2_rNums[512]; 132 | 133 | #define BZ_RAND_DECLS \ 134 | Int32 rNToGo; \ 135 | Int32 rTPos \ 136 | 137 | #define BZ_RAND_INIT_MASK \ 138 | s->rNToGo = 0; \ 139 | s->rTPos = 0 \ 140 | 141 | #define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) 142 | 143 | #define BZ_RAND_UPD_MASK \ 144 | if (s->rNToGo == 0) { \ 145 | s->rNToGo = BZ2_rNums[s->rTPos]; \ 146 | s->rTPos++; \ 147 | if (s->rTPos == 512) s->rTPos = 0; \ 148 | } \ 149 | s->rNToGo--; 150 | 151 | 152 | 153 | /*-- Stuff for doing CRCs. --*/ 154 | 155 | extern UInt32 BZ2_crc32Table[256]; 156 | 157 | #define BZ_INITIALISE_CRC(crcVar) \ 158 | { \ 159 | crcVar = 0xffffffffL; \ 160 | } 161 | 162 | #define BZ_FINALISE_CRC(crcVar) \ 163 | { \ 164 | crcVar = ~(crcVar); \ 165 | } 166 | 167 | #define BZ_UPDATE_CRC(crcVar,cha) \ 168 | { \ 169 | crcVar = (crcVar << 8) ^ \ 170 | BZ2_crc32Table[(crcVar >> 24) ^ \ 171 | ((UChar)cha)]; \ 172 | } 173 | 174 | 175 | 176 | /*-- States and modes for compression. --*/ 177 | 178 | #define BZ_M_IDLE 1 179 | #define BZ_M_RUNNING 2 180 | #define BZ_M_FLUSHING 3 181 | #define BZ_M_FINISHING 4 182 | 183 | #define BZ_S_OUTPUT 1 184 | #define BZ_S_INPUT 2 185 | 186 | #define BZ_N_RADIX 2 187 | #define BZ_N_QSORT 12 188 | #define BZ_N_SHELL 18 189 | #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) 190 | 191 | 192 | 193 | 194 | /*-- Structure holding all the compression-side stuff. --*/ 195 | 196 | typedef 197 | struct { 198 | /* pointer back to the struct bz_stream */ 199 | bz_stream* strm; 200 | 201 | /* mode this stream is in, and whether inputting */ 202 | /* or outputting data */ 203 | Int32 mode; 204 | Int32 state; 205 | 206 | /* remembers avail_in when flush/finish requested */ 207 | UInt32 avail_in_expect; 208 | 209 | /* for doing the block sorting */ 210 | UInt32* arr1; 211 | UInt32* arr2; 212 | UInt32* ftab; 213 | Int32 origPtr; 214 | 215 | /* aliases for arr1 and arr2 */ 216 | UInt32* ptr; 217 | UChar* block; 218 | UInt16* mtfv; 219 | UChar* zbits; 220 | 221 | /* for deciding when to use the fallback sorting algorithm */ 222 | Int32 workFactor; 223 | 224 | /* run-length-encoding of the input */ 225 | UInt32 state_in_ch; 226 | Int32 state_in_len; 227 | BZ_RAND_DECLS; 228 | 229 | /* input and output limits and current posns */ 230 | Int32 nblock; 231 | Int32 nblockMAX; 232 | Int32 numZ; 233 | Int32 state_out_pos; 234 | 235 | /* map of bytes used in block */ 236 | Int32 nInUse; 237 | Bool inUse[256]; 238 | UChar unseqToSeq[256]; 239 | 240 | /* the buffer for bit stream creation */ 241 | UInt32 bsBuff; 242 | Int32 bsLive; 243 | 244 | /* block and combined CRCs */ 245 | UInt32 blockCRC; 246 | UInt32 combinedCRC; 247 | 248 | /* misc administratium */ 249 | Int32 verbosity; 250 | Int32 blockNo; 251 | Int32 blockSize100k; 252 | 253 | /* stuff for coding the MTF values */ 254 | Int32 nMTF; 255 | Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; 256 | UChar selector [BZ_MAX_SELECTORS]; 257 | UChar selectorMtf[BZ_MAX_SELECTORS]; 258 | 259 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 260 | Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 261 | Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 262 | /* second dimension: only 3 needed; 4 makes index calculations faster */ 263 | UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; 264 | 265 | } 266 | EState; 267 | 268 | 269 | 270 | /*-- externs for compression. --*/ 271 | 272 | extern void 273 | BZ2_blockSort ( EState* ); 274 | 275 | extern void 276 | BZ2_compressBlock ( EState*, Bool ); 277 | 278 | extern void 279 | BZ2_bsInitWrite ( EState* ); 280 | 281 | extern void 282 | BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); 283 | 284 | extern void 285 | BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); 286 | 287 | 288 | 289 | /*-- states for decompression. --*/ 290 | 291 | #define BZ_X_IDLE 1 292 | #define BZ_X_OUTPUT 2 293 | 294 | #define BZ_X_MAGIC_1 10 295 | #define BZ_X_MAGIC_2 11 296 | #define BZ_X_MAGIC_3 12 297 | #define BZ_X_MAGIC_4 13 298 | #define BZ_X_BLKHDR_1 14 299 | #define BZ_X_BLKHDR_2 15 300 | #define BZ_X_BLKHDR_3 16 301 | #define BZ_X_BLKHDR_4 17 302 | #define BZ_X_BLKHDR_5 18 303 | #define BZ_X_BLKHDR_6 19 304 | #define BZ_X_BCRC_1 20 305 | #define BZ_X_BCRC_2 21 306 | #define BZ_X_BCRC_3 22 307 | #define BZ_X_BCRC_4 23 308 | #define BZ_X_RANDBIT 24 309 | #define BZ_X_ORIGPTR_1 25 310 | #define BZ_X_ORIGPTR_2 26 311 | #define BZ_X_ORIGPTR_3 27 312 | #define BZ_X_MAPPING_1 28 313 | #define BZ_X_MAPPING_2 29 314 | #define BZ_X_SELECTOR_1 30 315 | #define BZ_X_SELECTOR_2 31 316 | #define BZ_X_SELECTOR_3 32 317 | #define BZ_X_CODING_1 33 318 | #define BZ_X_CODING_2 34 319 | #define BZ_X_CODING_3 35 320 | #define BZ_X_MTF_1 36 321 | #define BZ_X_MTF_2 37 322 | #define BZ_X_MTF_3 38 323 | #define BZ_X_MTF_4 39 324 | #define BZ_X_MTF_5 40 325 | #define BZ_X_MTF_6 41 326 | #define BZ_X_ENDHDR_2 42 327 | #define BZ_X_ENDHDR_3 43 328 | #define BZ_X_ENDHDR_4 44 329 | #define BZ_X_ENDHDR_5 45 330 | #define BZ_X_ENDHDR_6 46 331 | #define BZ_X_CCRC_1 47 332 | #define BZ_X_CCRC_2 48 333 | #define BZ_X_CCRC_3 49 334 | #define BZ_X_CCRC_4 50 335 | 336 | 337 | 338 | /*-- Constants for the fast MTF decoder. --*/ 339 | 340 | #define MTFA_SIZE 4096 341 | #define MTFL_SIZE 16 342 | 343 | 344 | 345 | /*-- Structure holding all the decompression-side stuff. --*/ 346 | 347 | typedef 348 | struct { 349 | /* pointer back to the struct bz_stream */ 350 | bz_stream* strm; 351 | 352 | /* state indicator for this stream */ 353 | Int32 state; 354 | 355 | /* for doing the final run-length decoding */ 356 | UChar state_out_ch; 357 | Int32 state_out_len; 358 | Bool blockRandomised; 359 | BZ_RAND_DECLS; 360 | 361 | /* the buffer for bit stream reading */ 362 | UInt32 bsBuff; 363 | Int32 bsLive; 364 | 365 | /* misc administratium */ 366 | Int32 blockSize100k; 367 | Bool smallDecompress; 368 | Int32 currBlockNo; 369 | Int32 verbosity; 370 | 371 | /* for undoing the Burrows-Wheeler transform */ 372 | Int32 origPtr; 373 | UInt32 tPos; 374 | Int32 k0; 375 | Int32 unzftab[256]; 376 | Int32 nblock_used; 377 | Int32 cftab[257]; 378 | Int32 cftabCopy[257]; 379 | 380 | /* for undoing the Burrows-Wheeler transform (FAST) */ 381 | UInt32 *tt; 382 | 383 | /* for undoing the Burrows-Wheeler transform (SMALL) */ 384 | UInt16 *ll16; 385 | UChar *ll4; 386 | 387 | /* stored and calculated CRCs */ 388 | UInt32 storedBlockCRC; 389 | UInt32 storedCombinedCRC; 390 | UInt32 calculatedBlockCRC; 391 | UInt32 calculatedCombinedCRC; 392 | 393 | /* map of bytes used in block */ 394 | Int32 nInUse; 395 | Bool inUse[256]; 396 | Bool inUse16[16]; 397 | UChar seqToUnseq[256]; 398 | 399 | /* for decoding the MTF values */ 400 | UChar mtfa [MTFA_SIZE]; 401 | Int32 mtfbase[256 / MTFL_SIZE]; 402 | UChar selector [BZ_MAX_SELECTORS]; 403 | UChar selectorMtf[BZ_MAX_SELECTORS]; 404 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 405 | 406 | Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 407 | Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 408 | Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 409 | Int32 minLens[BZ_N_GROUPS]; 410 | 411 | /* save area for scalars in the main decompress code */ 412 | Int32 save_i; 413 | Int32 save_j; 414 | Int32 save_t; 415 | Int32 save_alphaSize; 416 | Int32 save_nGroups; 417 | Int32 save_nSelectors; 418 | Int32 save_EOB; 419 | Int32 save_groupNo; 420 | Int32 save_groupPos; 421 | Int32 save_nextSym; 422 | Int32 save_nblockMAX; 423 | Int32 save_nblock; 424 | Int32 save_es; 425 | Int32 save_N; 426 | Int32 save_curr; 427 | Int32 save_zt; 428 | Int32 save_zn; 429 | Int32 save_zvec; 430 | Int32 save_zj; 431 | Int32 save_gSel; 432 | Int32 save_gMinlen; 433 | Int32* save_gLimit; 434 | Int32* save_gBase; 435 | Int32* save_gPerm; 436 | 437 | } 438 | DState; 439 | 440 | 441 | 442 | /*-- Macros for decompression. --*/ 443 | 444 | #define BZ_GET_FAST(cccc) \ 445 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \ 446 | if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ 447 | s->tPos = s->tt[s->tPos]; \ 448 | cccc = (UChar)(s->tPos & 0xff); \ 449 | s->tPos >>= 8; 450 | 451 | #define BZ_GET_FAST_C(cccc) \ 452 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \ 453 | if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ 454 | c_tPos = c_tt[c_tPos]; \ 455 | cccc = (UChar)(c_tPos & 0xff); \ 456 | c_tPos >>= 8; 457 | 458 | #define SET_LL4(i,n) \ 459 | { if (((i) & 0x1) == 0) \ 460 | s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ 461 | s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ 462 | } 463 | 464 | #define GET_LL4(i) \ 465 | ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) 466 | 467 | #define SET_LL(i,n) \ 468 | { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ 469 | SET_LL4(i, n >> 16); \ 470 | } 471 | 472 | #define GET_LL(i) \ 473 | (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) 474 | 475 | #define BZ_GET_SMALL(cccc) \ 476 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \ 477 | if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ 478 | cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ 479 | s->tPos = GET_LL(s->tPos); 480 | 481 | 482 | /*-- externs for decompression. --*/ 483 | 484 | extern Int32 485 | BZ2_indexIntoF ( Int32, Int32* ); 486 | 487 | extern Int32 488 | BZ2_decompress ( DState* ); 489 | 490 | extern void 491 | BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, 492 | Int32, Int32, Int32 ); 493 | 494 | 495 | #endif 496 | 497 | 498 | /*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ 499 | 500 | #ifdef BZ_NO_STDIO 501 | #ifndef NULL 502 | #define NULL 0 503 | #endif 504 | #endif 505 | 506 | 507 | /*-------------------------------------------------------------*/ 508 | /*--- end bzlib_private.h ---*/ 509 | /*-------------------------------------------------------------*/ 510 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/compress.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Compression machinery (not incl block sorting) ---*/ 4 | /*--- compress.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | /* CHANGES 23 | 0.9.0 -- original version. 24 | 0.9.0a/b -- no changes in this file. 25 | 0.9.0c -- changed setting of nGroups in sendMTFValues() 26 | so as to do a bit better on small files 27 | */ 28 | 29 | #include "bzlib_private.h" 30 | 31 | 32 | /*---------------------------------------------------*/ 33 | /*--- Bit stream I/O ---*/ 34 | /*---------------------------------------------------*/ 35 | 36 | /*---------------------------------------------------*/ 37 | void BZ2_bsInitWrite ( EState* s ) 38 | { 39 | s->bsLive = 0; 40 | s->bsBuff = 0; 41 | } 42 | 43 | 44 | /*---------------------------------------------------*/ 45 | static 46 | void bsFinishWrite ( EState* s ) 47 | { 48 | while (s->bsLive > 0) { 49 | s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); 50 | s->numZ++; 51 | s->bsBuff <<= 8; 52 | s->bsLive -= 8; 53 | } 54 | } 55 | 56 | 57 | /*---------------------------------------------------*/ 58 | #define bsNEEDW(nz) \ 59 | { \ 60 | while (s->bsLive >= 8) { \ 61 | s->zbits[s->numZ] \ 62 | = (UChar)(s->bsBuff >> 24); \ 63 | s->numZ++; \ 64 | s->bsBuff <<= 8; \ 65 | s->bsLive -= 8; \ 66 | } \ 67 | } 68 | 69 | 70 | /*---------------------------------------------------*/ 71 | static 72 | __inline__ 73 | void bsW ( EState* s, Int32 n, UInt32 v ) 74 | { 75 | bsNEEDW ( n ); 76 | s->bsBuff |= (v << (32 - s->bsLive - n)); 77 | s->bsLive += n; 78 | } 79 | 80 | 81 | /*---------------------------------------------------*/ 82 | static 83 | void bsPutUInt32 ( EState* s, UInt32 u ) 84 | { 85 | bsW ( s, 8, (u >> 24) & 0xffL ); 86 | bsW ( s, 8, (u >> 16) & 0xffL ); 87 | bsW ( s, 8, (u >> 8) & 0xffL ); 88 | bsW ( s, 8, u & 0xffL ); 89 | } 90 | 91 | 92 | /*---------------------------------------------------*/ 93 | static 94 | void bsPutUChar ( EState* s, UChar c ) 95 | { 96 | bsW( s, 8, (UInt32)c ); 97 | } 98 | 99 | 100 | /*---------------------------------------------------*/ 101 | /*--- The back end proper ---*/ 102 | /*---------------------------------------------------*/ 103 | 104 | /*---------------------------------------------------*/ 105 | static 106 | void makeMaps_e ( EState* s ) 107 | { 108 | Int32 i; 109 | s->nInUse = 0; 110 | for (i = 0; i < 256; i++) 111 | if (s->inUse[i]) { 112 | s->unseqToSeq[i] = s->nInUse; 113 | s->nInUse++; 114 | } 115 | } 116 | 117 | 118 | /*---------------------------------------------------*/ 119 | static 120 | void generateMTFValues ( EState* s ) 121 | { 122 | UChar yy[256]; 123 | Int32 i, j; 124 | Int32 zPend; 125 | Int32 wr; 126 | Int32 EOB; 127 | 128 | /* 129 | After sorting (eg, here), 130 | s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, 131 | and 132 | ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 133 | holds the original block data. 134 | 135 | The first thing to do is generate the MTF values, 136 | and put them in 137 | ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. 138 | Because there are strictly fewer or equal MTF values 139 | than block values, ptr values in this area are overwritten 140 | with MTF values only when they are no longer needed. 141 | 142 | The final compressed bitstream is generated into the 143 | area starting at 144 | (UChar*) (&((UChar*)s->arr2)[s->nblock]) 145 | 146 | These storage aliases are set up in bzCompressInit(), 147 | except for the last one, which is arranged in 148 | compressBlock(). 149 | */ 150 | UInt32* ptr = s->ptr; 151 | UChar* block = s->block; 152 | UInt16* mtfv = s->mtfv; 153 | 154 | makeMaps_e ( s ); 155 | EOB = s->nInUse+1; 156 | 157 | for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; 158 | 159 | wr = 0; 160 | zPend = 0; 161 | for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; 162 | 163 | for (i = 0; i < s->nblock; i++) { 164 | UChar ll_i; 165 | AssertD ( wr <= i, "generateMTFValues(1)" ); 166 | j = ptr[i]-1; if (j < 0) j += s->nblock; 167 | ll_i = s->unseqToSeq[block[j]]; 168 | AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); 169 | 170 | if (yy[0] == ll_i) { 171 | zPend++; 172 | } else { 173 | 174 | if (zPend > 0) { 175 | zPend--; 176 | while (True) { 177 | if (zPend & 1) { 178 | mtfv[wr] = BZ_RUNB; wr++; 179 | s->mtfFreq[BZ_RUNB]++; 180 | } else { 181 | mtfv[wr] = BZ_RUNA; wr++; 182 | s->mtfFreq[BZ_RUNA]++; 183 | } 184 | if (zPend < 2) break; 185 | zPend = (zPend - 2) / 2; 186 | }; 187 | zPend = 0; 188 | } 189 | { 190 | register UChar rtmp; 191 | register UChar* ryy_j; 192 | register UChar rll_i; 193 | rtmp = yy[1]; 194 | yy[1] = yy[0]; 195 | ryy_j = &(yy[1]); 196 | rll_i = ll_i; 197 | while ( rll_i != rtmp ) { 198 | register UChar rtmp2; 199 | ryy_j++; 200 | rtmp2 = rtmp; 201 | rtmp = *ryy_j; 202 | *ryy_j = rtmp2; 203 | }; 204 | yy[0] = rtmp; 205 | j = ryy_j - &(yy[0]); 206 | mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; 207 | } 208 | 209 | } 210 | } 211 | 212 | if (zPend > 0) { 213 | zPend--; 214 | while (True) { 215 | if (zPend & 1) { 216 | mtfv[wr] = BZ_RUNB; wr++; 217 | s->mtfFreq[BZ_RUNB]++; 218 | } else { 219 | mtfv[wr] = BZ_RUNA; wr++; 220 | s->mtfFreq[BZ_RUNA]++; 221 | } 222 | if (zPend < 2) break; 223 | zPend = (zPend - 2) / 2; 224 | }; 225 | zPend = 0; 226 | } 227 | 228 | mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; 229 | 230 | s->nMTF = wr; 231 | } 232 | 233 | 234 | /*---------------------------------------------------*/ 235 | #define BZ_LESSER_ICOST 0 236 | #define BZ_GREATER_ICOST 15 237 | 238 | static 239 | void sendMTFValues ( EState* s ) 240 | { 241 | Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; 242 | Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; 243 | Int32 nGroups, nBytes; 244 | 245 | /*-- 246 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 247 | is a global since the decoder also needs it. 248 | 249 | Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 250 | Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 251 | are also globals only used in this proc. 252 | Made global to keep stack frame size small. 253 | --*/ 254 | 255 | 256 | UInt16 cost[BZ_N_GROUPS]; 257 | Int32 fave[BZ_N_GROUPS]; 258 | 259 | UInt16* mtfv = s->mtfv; 260 | 261 | if (s->verbosity >= 3) 262 | VPrintf3( " %d in block, %d after MTF & 1-2 coding, " 263 | "%d+2 syms in use\n", 264 | s->nblock, s->nMTF, s->nInUse ); 265 | 266 | alphaSize = s->nInUse+2; 267 | for (t = 0; t < BZ_N_GROUPS; t++) 268 | for (v = 0; v < alphaSize; v++) 269 | s->len[t][v] = BZ_GREATER_ICOST; 270 | 271 | /*--- Decide how many coding tables to use ---*/ 272 | AssertH ( s->nMTF > 0, 3001 ); 273 | if (s->nMTF < 200) nGroups = 2; else 274 | if (s->nMTF < 600) nGroups = 3; else 275 | if (s->nMTF < 1200) nGroups = 4; else 276 | if (s->nMTF < 2400) nGroups = 5; else 277 | nGroups = 6; 278 | 279 | /*--- Generate an initial set of coding tables ---*/ 280 | { 281 | Int32 nPart, remF, tFreq, aFreq; 282 | 283 | nPart = nGroups; 284 | remF = s->nMTF; 285 | gs = 0; 286 | while (nPart > 0) { 287 | tFreq = remF / nPart; 288 | ge = gs-1; 289 | aFreq = 0; 290 | while (aFreq < tFreq && ge < alphaSize-1) { 291 | ge++; 292 | aFreq += s->mtfFreq[ge]; 293 | } 294 | 295 | if (ge > gs 296 | && nPart != nGroups && nPart != 1 297 | && ((nGroups-nPart) % 2 == 1)) { 298 | aFreq -= s->mtfFreq[ge]; 299 | ge--; 300 | } 301 | 302 | if (s->verbosity >= 3) 303 | VPrintf5( " initial group %d, [%d .. %d], " 304 | "has %d syms (%4.1f%%)\n", 305 | nPart, gs, ge, aFreq, 306 | (100.0 * (float)aFreq) / (float)(s->nMTF) ); 307 | 308 | for (v = 0; v < alphaSize; v++) 309 | if (v >= gs && v <= ge) 310 | s->len[nPart-1][v] = BZ_LESSER_ICOST; else 311 | s->len[nPart-1][v] = BZ_GREATER_ICOST; 312 | 313 | nPart--; 314 | gs = ge+1; 315 | remF -= aFreq; 316 | } 317 | } 318 | 319 | /*--- 320 | Iterate up to BZ_N_ITERS times to improve the tables. 321 | ---*/ 322 | for (iter = 0; iter < BZ_N_ITERS; iter++) { 323 | 324 | for (t = 0; t < nGroups; t++) fave[t] = 0; 325 | 326 | for (t = 0; t < nGroups; t++) 327 | for (v = 0; v < alphaSize; v++) 328 | s->rfreq[t][v] = 0; 329 | 330 | /*--- 331 | Set up an auxiliary length table which is used to fast-track 332 | the common case (nGroups == 6). 333 | ---*/ 334 | if (nGroups == 6) { 335 | for (v = 0; v < alphaSize; v++) { 336 | s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; 337 | s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; 338 | s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; 339 | } 340 | } 341 | 342 | nSelectors = 0; 343 | totc = 0; 344 | gs = 0; 345 | while (True) { 346 | 347 | /*--- Set group start & end marks. --*/ 348 | if (gs >= s->nMTF) break; 349 | ge = gs + BZ_G_SIZE - 1; 350 | if (ge >= s->nMTF) ge = s->nMTF-1; 351 | 352 | /*-- 353 | Calculate the cost of this group as coded 354 | by each of the coding tables. 355 | --*/ 356 | for (t = 0; t < nGroups; t++) cost[t] = 0; 357 | 358 | if (nGroups == 6 && 50 == ge-gs+1) { 359 | /*--- fast track the common case ---*/ 360 | register UInt32 cost01, cost23, cost45; 361 | register UInt16 icv; 362 | cost01 = cost23 = cost45 = 0; 363 | 364 | # define BZ_ITER(nn) \ 365 | icv = mtfv[gs+(nn)]; \ 366 | cost01 += s->len_pack[icv][0]; \ 367 | cost23 += s->len_pack[icv][1]; \ 368 | cost45 += s->len_pack[icv][2]; \ 369 | 370 | BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); 371 | BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); 372 | BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); 373 | BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); 374 | BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); 375 | BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); 376 | BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); 377 | BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); 378 | BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); 379 | BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); 380 | 381 | # undef BZ_ITER 382 | 383 | cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; 384 | cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; 385 | cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; 386 | 387 | } else { 388 | /*--- slow version which correctly handles all situations ---*/ 389 | for (i = gs; i <= ge; i++) { 390 | UInt16 icv = mtfv[i]; 391 | for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; 392 | } 393 | } 394 | 395 | /*-- 396 | Find the coding table which is best for this group, 397 | and record its identity in the selector table. 398 | --*/ 399 | bc = 999999999; bt = -1; 400 | for (t = 0; t < nGroups; t++) 401 | if (cost[t] < bc) { bc = cost[t]; bt = t; }; 402 | totc += bc; 403 | fave[bt]++; 404 | s->selector[nSelectors] = bt; 405 | nSelectors++; 406 | 407 | /*-- 408 | Increment the symbol frequencies for the selected table. 409 | --*/ 410 | if (nGroups == 6 && 50 == ge-gs+1) { 411 | /*--- fast track the common case ---*/ 412 | 413 | # define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ 414 | 415 | BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); 416 | BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); 417 | BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); 418 | BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); 419 | BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); 420 | BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); 421 | BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); 422 | BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); 423 | BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); 424 | BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); 425 | 426 | # undef BZ_ITUR 427 | 428 | } else { 429 | /*--- slow version which correctly handles all situations ---*/ 430 | for (i = gs; i <= ge; i++) 431 | s->rfreq[bt][ mtfv[i] ]++; 432 | } 433 | 434 | gs = ge+1; 435 | } 436 | if (s->verbosity >= 3) { 437 | VPrintf2 ( " pass %d: size is %d, grp uses are ", 438 | iter+1, totc/8 ); 439 | for (t = 0; t < nGroups; t++) 440 | VPrintf1 ( "%d ", fave[t] ); 441 | VPrintf0 ( "\n" ); 442 | } 443 | 444 | /*-- 445 | Recompute the tables based on the accumulated frequencies. 446 | --*/ 447 | /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See 448 | comment in huffman.c for details. */ 449 | for (t = 0; t < nGroups; t++) 450 | BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 451 | alphaSize, 17 /*20*/ ); 452 | } 453 | 454 | 455 | AssertH( nGroups < 8, 3002 ); 456 | AssertH( nSelectors < 32768 && 457 | nSelectors <= (2 + (900000 / BZ_G_SIZE)), 458 | 3003 ); 459 | 460 | 461 | /*--- Compute MTF values for the selectors. ---*/ 462 | { 463 | UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; 464 | for (i = 0; i < nGroups; i++) pos[i] = i; 465 | for (i = 0; i < nSelectors; i++) { 466 | ll_i = s->selector[i]; 467 | j = 0; 468 | tmp = pos[j]; 469 | while ( ll_i != tmp ) { 470 | j++; 471 | tmp2 = tmp; 472 | tmp = pos[j]; 473 | pos[j] = tmp2; 474 | }; 475 | pos[0] = tmp; 476 | s->selectorMtf[i] = j; 477 | } 478 | }; 479 | 480 | /*--- Assign actual codes for the tables. --*/ 481 | for (t = 0; t < nGroups; t++) { 482 | minLen = 32; 483 | maxLen = 0; 484 | for (i = 0; i < alphaSize; i++) { 485 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; 486 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; 487 | } 488 | AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); 489 | AssertH ( !(minLen < 1), 3005 ); 490 | BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 491 | minLen, maxLen, alphaSize ); 492 | } 493 | 494 | /*--- Transmit the mapping table. ---*/ 495 | { 496 | Bool inUse16[16]; 497 | for (i = 0; i < 16; i++) { 498 | inUse16[i] = False; 499 | for (j = 0; j < 16; j++) 500 | if (s->inUse[i * 16 + j]) inUse16[i] = True; 501 | } 502 | 503 | nBytes = s->numZ; 504 | for (i = 0; i < 16; i++) 505 | if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); 506 | 507 | for (i = 0; i < 16; i++) 508 | if (inUse16[i]) 509 | for (j = 0; j < 16; j++) { 510 | if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); 511 | } 512 | 513 | if (s->verbosity >= 3) 514 | VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); 515 | } 516 | 517 | /*--- Now the selectors. ---*/ 518 | nBytes = s->numZ; 519 | bsW ( s, 3, nGroups ); 520 | bsW ( s, 15, nSelectors ); 521 | for (i = 0; i < nSelectors; i++) { 522 | for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); 523 | bsW(s,1,0); 524 | } 525 | if (s->verbosity >= 3) 526 | VPrintf1( "selectors %d, ", s->numZ-nBytes ); 527 | 528 | /*--- Now the coding tables. ---*/ 529 | nBytes = s->numZ; 530 | 531 | for (t = 0; t < nGroups; t++) { 532 | Int32 curr = s->len[t][0]; 533 | bsW ( s, 5, curr ); 534 | for (i = 0; i < alphaSize; i++) { 535 | while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; 536 | while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; 537 | bsW ( s, 1, 0 ); 538 | } 539 | } 540 | 541 | if (s->verbosity >= 3) 542 | VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); 543 | 544 | /*--- And finally, the block data proper ---*/ 545 | nBytes = s->numZ; 546 | selCtr = 0; 547 | gs = 0; 548 | while (True) { 549 | if (gs >= s->nMTF) break; 550 | ge = gs + BZ_G_SIZE - 1; 551 | if (ge >= s->nMTF) ge = s->nMTF-1; 552 | AssertH ( s->selector[selCtr] < nGroups, 3006 ); 553 | 554 | if (nGroups == 6 && 50 == ge-gs+1) { 555 | /*--- fast track the common case ---*/ 556 | UInt16 mtfv_i; 557 | UChar* s_len_sel_selCtr 558 | = &(s->len[s->selector[selCtr]][0]); 559 | Int32* s_code_sel_selCtr 560 | = &(s->code[s->selector[selCtr]][0]); 561 | 562 | # define BZ_ITAH(nn) \ 563 | mtfv_i = mtfv[gs+(nn)]; \ 564 | bsW ( s, \ 565 | s_len_sel_selCtr[mtfv_i], \ 566 | s_code_sel_selCtr[mtfv_i] ) 567 | 568 | BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); 569 | BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); 570 | BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); 571 | BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); 572 | BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); 573 | BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); 574 | BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); 575 | BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); 576 | BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); 577 | BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); 578 | 579 | # undef BZ_ITAH 580 | 581 | } else { 582 | /*--- slow version which correctly handles all situations ---*/ 583 | for (i = gs; i <= ge; i++) { 584 | bsW ( s, 585 | s->len [s->selector[selCtr]] [mtfv[i]], 586 | s->code [s->selector[selCtr]] [mtfv[i]] ); 587 | } 588 | } 589 | 590 | 591 | gs = ge+1; 592 | selCtr++; 593 | } 594 | AssertH( selCtr == nSelectors, 3007 ); 595 | 596 | if (s->verbosity >= 3) 597 | VPrintf1( "codes %d\n", s->numZ-nBytes ); 598 | } 599 | 600 | 601 | /*---------------------------------------------------*/ 602 | void BZ2_compressBlock ( EState* s, Bool is_last_block ) 603 | { 604 | if (s->nblock > 0) { 605 | 606 | BZ_FINALISE_CRC ( s->blockCRC ); 607 | s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); 608 | s->combinedCRC ^= s->blockCRC; 609 | if (s->blockNo > 1) s->numZ = 0; 610 | 611 | if (s->verbosity >= 2) 612 | VPrintf4( " block %d: crc = 0x%08x, " 613 | "combined CRC = 0x%08x, size = %d\n", 614 | s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); 615 | 616 | BZ2_blockSort ( s ); 617 | } 618 | 619 | s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); 620 | 621 | /*-- If this is the first block, create the stream header. --*/ 622 | if (s->blockNo == 1) { 623 | BZ2_bsInitWrite ( s ); 624 | bsPutUChar ( s, BZ_HDR_B ); 625 | bsPutUChar ( s, BZ_HDR_Z ); 626 | bsPutUChar ( s, BZ_HDR_h ); 627 | bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); 628 | } 629 | 630 | if (s->nblock > 0) { 631 | 632 | bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); 633 | bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); 634 | bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); 635 | 636 | /*-- Now the block's CRC, so it is in a known place. --*/ 637 | bsPutUInt32 ( s, s->blockCRC ); 638 | 639 | /*-- 640 | Now a single bit indicating (non-)randomisation. 641 | As of version 0.9.5, we use a better sorting algorithm 642 | which makes randomisation unnecessary. So always set 643 | the randomised bit to 'no'. Of course, the decoder 644 | still needs to be able to handle randomised blocks 645 | so as to maintain backwards compatibility with 646 | older versions of bzip2. 647 | --*/ 648 | bsW(s,1,0); 649 | 650 | bsW ( s, 24, s->origPtr ); 651 | generateMTFValues ( s ); 652 | sendMTFValues ( s ); 653 | } 654 | 655 | 656 | /*-- If this is the last block, add the stream trailer. --*/ 657 | if (is_last_block) { 658 | 659 | bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); 660 | bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); 661 | bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); 662 | bsPutUInt32 ( s, s->combinedCRC ); 663 | if (s->verbosity >= 2) 664 | VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); 665 | bsFinishWrite ( s ); 666 | } 667 | } 668 | 669 | 670 | /*-------------------------------------------------------------*/ 671 | /*--- end compress.c ---*/ 672 | /*-------------------------------------------------------------*/ 673 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/crctable.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Table for doing CRCs ---*/ 4 | /*--- crctable.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #include "bzlib_private.h" 23 | 24 | /*-- 25 | I think this is an implementation of the AUTODIN-II, 26 | Ethernet & FDDI 32-bit CRC standard. Vaguely derived 27 | from code by Rob Warnock, in Section 51 of the 28 | comp.compression FAQ. 29 | --*/ 30 | 31 | UInt32 BZ2_crc32Table[256] = { 32 | 33 | /*-- Ugly, innit? --*/ 34 | 35 | 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, 36 | 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, 37 | 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, 38 | 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, 39 | 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, 40 | 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, 41 | 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, 42 | 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, 43 | 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, 44 | 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, 45 | 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, 46 | 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, 47 | 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, 48 | 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, 49 | 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, 50 | 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, 51 | 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, 52 | 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, 53 | 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, 54 | 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, 55 | 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, 56 | 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, 57 | 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, 58 | 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, 59 | 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, 60 | 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, 61 | 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, 62 | 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, 63 | 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, 64 | 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, 65 | 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, 66 | 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, 67 | 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, 68 | 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, 69 | 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, 70 | 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, 71 | 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, 72 | 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, 73 | 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, 74 | 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, 75 | 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, 76 | 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, 77 | 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, 78 | 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, 79 | 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, 80 | 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, 81 | 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, 82 | 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, 83 | 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, 84 | 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, 85 | 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, 86 | 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, 87 | 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, 88 | 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, 89 | 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, 90 | 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, 91 | 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, 92 | 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, 93 | 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, 94 | 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, 95 | 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, 96 | 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, 97 | 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, 98 | 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L 99 | }; 100 | 101 | 102 | /*-------------------------------------------------------------*/ 103 | /*--- end crctable.c ---*/ 104 | /*-------------------------------------------------------------*/ 105 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/decompress.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Decompression machinery ---*/ 4 | /*--- decompress.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #include "bzlib_private.h" 23 | 24 | 25 | /*---------------------------------------------------*/ 26 | static 27 | void makeMaps_d ( DState* s ) 28 | { 29 | Int32 i; 30 | s->nInUse = 0; 31 | for (i = 0; i < 256; i++) 32 | if (s->inUse[i]) { 33 | s->seqToUnseq[s->nInUse] = i; 34 | s->nInUse++; 35 | } 36 | } 37 | 38 | 39 | /*---------------------------------------------------*/ 40 | #define RETURN(rrr) \ 41 | { retVal = rrr; goto save_state_and_return; }; 42 | 43 | #define GET_BITS(lll,vvv,nnn) \ 44 | case lll: s->state = lll; \ 45 | while (True) { \ 46 | if (s->bsLive >= nnn) { \ 47 | UInt32 v; \ 48 | v = (s->bsBuff >> \ 49 | (s->bsLive-nnn)) & ((1 << nnn)-1); \ 50 | s->bsLive -= nnn; \ 51 | vvv = v; \ 52 | break; \ 53 | } \ 54 | if (s->strm->avail_in == 0) RETURN(BZ_OK); \ 55 | s->bsBuff \ 56 | = (s->bsBuff << 8) | \ 57 | ((UInt32) \ 58 | (*((UChar*)(s->strm->next_in)))); \ 59 | s->bsLive += 8; \ 60 | s->strm->next_in++; \ 61 | s->strm->avail_in--; \ 62 | s->strm->total_in_lo32++; \ 63 | if (s->strm->total_in_lo32 == 0) \ 64 | s->strm->total_in_hi32++; \ 65 | } 66 | 67 | #define GET_UCHAR(lll,uuu) \ 68 | GET_BITS(lll,uuu,8) 69 | 70 | #define GET_BIT(lll,uuu) \ 71 | GET_BITS(lll,uuu,1) 72 | 73 | /*---------------------------------------------------*/ 74 | #define GET_MTF_VAL(label1,label2,lval) \ 75 | { \ 76 | if (groupPos == 0) { \ 77 | groupNo++; \ 78 | if (groupNo >= nSelectors) \ 79 | RETURN(BZ_DATA_ERROR); \ 80 | groupPos = BZ_G_SIZE; \ 81 | gSel = s->selector[groupNo]; \ 82 | gMinlen = s->minLens[gSel]; \ 83 | gLimit = &(s->limit[gSel][0]); \ 84 | gPerm = &(s->perm[gSel][0]); \ 85 | gBase = &(s->base[gSel][0]); \ 86 | } \ 87 | groupPos--; \ 88 | zn = gMinlen; \ 89 | GET_BITS(label1, zvec, zn); \ 90 | while (1) { \ 91 | if (zn > 20 /* the longest code */) \ 92 | RETURN(BZ_DATA_ERROR); \ 93 | if (zvec <= gLimit[zn]) break; \ 94 | zn++; \ 95 | GET_BIT(label2, zj); \ 96 | zvec = (zvec << 1) | zj; \ 97 | }; \ 98 | if (zvec - gBase[zn] < 0 \ 99 | || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ 100 | RETURN(BZ_DATA_ERROR); \ 101 | lval = gPerm[zvec - gBase[zn]]; \ 102 | } 103 | 104 | 105 | /*---------------------------------------------------*/ 106 | Int32 BZ2_decompress ( DState* s ) 107 | { 108 | UChar uc; 109 | Int32 retVal; 110 | Int32 minLen, maxLen; 111 | bz_stream* strm = s->strm; 112 | 113 | /* stuff that needs to be saved/restored */ 114 | Int32 i; 115 | Int32 j; 116 | Int32 t; 117 | Int32 alphaSize; 118 | Int32 nGroups; 119 | Int32 nSelectors; 120 | Int32 EOB; 121 | Int32 groupNo; 122 | Int32 groupPos; 123 | Int32 nextSym; 124 | Int32 nblockMAX; 125 | Int32 nblock; 126 | Int32 es; 127 | Int32 N; 128 | Int32 curr; 129 | Int32 zt; 130 | Int32 zn; 131 | Int32 zvec; 132 | Int32 zj; 133 | Int32 gSel; 134 | Int32 gMinlen; 135 | Int32* gLimit; 136 | Int32* gBase; 137 | Int32* gPerm; 138 | 139 | if (s->state == BZ_X_MAGIC_1) { 140 | /*initialise the save area*/ 141 | s->save_i = 0; 142 | s->save_j = 0; 143 | s->save_t = 0; 144 | s->save_alphaSize = 0; 145 | s->save_nGroups = 0; 146 | s->save_nSelectors = 0; 147 | s->save_EOB = 0; 148 | s->save_groupNo = 0; 149 | s->save_groupPos = 0; 150 | s->save_nextSym = 0; 151 | s->save_nblockMAX = 0; 152 | s->save_nblock = 0; 153 | s->save_es = 0; 154 | s->save_N = 0; 155 | s->save_curr = 0; 156 | s->save_zt = 0; 157 | s->save_zn = 0; 158 | s->save_zvec = 0; 159 | s->save_zj = 0; 160 | s->save_gSel = 0; 161 | s->save_gMinlen = 0; 162 | s->save_gLimit = NULL; 163 | s->save_gBase = NULL; 164 | s->save_gPerm = NULL; 165 | } 166 | 167 | /*restore from the save area*/ 168 | i = s->save_i; 169 | j = s->save_j; 170 | t = s->save_t; 171 | alphaSize = s->save_alphaSize; 172 | nGroups = s->save_nGroups; 173 | nSelectors = s->save_nSelectors; 174 | EOB = s->save_EOB; 175 | groupNo = s->save_groupNo; 176 | groupPos = s->save_groupPos; 177 | nextSym = s->save_nextSym; 178 | nblockMAX = s->save_nblockMAX; 179 | nblock = s->save_nblock; 180 | es = s->save_es; 181 | N = s->save_N; 182 | curr = s->save_curr; 183 | zt = s->save_zt; 184 | zn = s->save_zn; 185 | zvec = s->save_zvec; 186 | zj = s->save_zj; 187 | gSel = s->save_gSel; 188 | gMinlen = s->save_gMinlen; 189 | gLimit = s->save_gLimit; 190 | gBase = s->save_gBase; 191 | gPerm = s->save_gPerm; 192 | 193 | retVal = BZ_OK; 194 | 195 | switch (s->state) { 196 | 197 | GET_UCHAR(BZ_X_MAGIC_1, uc); 198 | if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); 199 | 200 | GET_UCHAR(BZ_X_MAGIC_2, uc); 201 | if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); 202 | 203 | GET_UCHAR(BZ_X_MAGIC_3, uc) 204 | if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); 205 | 206 | GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) 207 | if (s->blockSize100k < (BZ_HDR_0 + 1) || 208 | s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); 209 | s->blockSize100k -= BZ_HDR_0; 210 | 211 | if (s->smallDecompress) { 212 | s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); 213 | s->ll4 = BZALLOC( 214 | ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 215 | ); 216 | if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); 217 | } else { 218 | s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); 219 | if (s->tt == NULL) RETURN(BZ_MEM_ERROR); 220 | } 221 | 222 | GET_UCHAR(BZ_X_BLKHDR_1, uc); 223 | 224 | if (uc == 0x17) goto endhdr_2; 225 | if (uc != 0x31) RETURN(BZ_DATA_ERROR); 226 | GET_UCHAR(BZ_X_BLKHDR_2, uc); 227 | if (uc != 0x41) RETURN(BZ_DATA_ERROR); 228 | GET_UCHAR(BZ_X_BLKHDR_3, uc); 229 | if (uc != 0x59) RETURN(BZ_DATA_ERROR); 230 | GET_UCHAR(BZ_X_BLKHDR_4, uc); 231 | if (uc != 0x26) RETURN(BZ_DATA_ERROR); 232 | GET_UCHAR(BZ_X_BLKHDR_5, uc); 233 | if (uc != 0x53) RETURN(BZ_DATA_ERROR); 234 | GET_UCHAR(BZ_X_BLKHDR_6, uc); 235 | if (uc != 0x59) RETURN(BZ_DATA_ERROR); 236 | 237 | s->currBlockNo++; 238 | if (s->verbosity >= 2) 239 | VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); 240 | 241 | s->storedBlockCRC = 0; 242 | GET_UCHAR(BZ_X_BCRC_1, uc); 243 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); 244 | GET_UCHAR(BZ_X_BCRC_2, uc); 245 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); 246 | GET_UCHAR(BZ_X_BCRC_3, uc); 247 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); 248 | GET_UCHAR(BZ_X_BCRC_4, uc); 249 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); 250 | 251 | GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); 252 | 253 | s->origPtr = 0; 254 | GET_UCHAR(BZ_X_ORIGPTR_1, uc); 255 | s->origPtr = (s->origPtr << 8) | ((Int32)uc); 256 | GET_UCHAR(BZ_X_ORIGPTR_2, uc); 257 | s->origPtr = (s->origPtr << 8) | ((Int32)uc); 258 | GET_UCHAR(BZ_X_ORIGPTR_3, uc); 259 | s->origPtr = (s->origPtr << 8) | ((Int32)uc); 260 | 261 | if (s->origPtr < 0) 262 | RETURN(BZ_DATA_ERROR); 263 | if (s->origPtr > 10 + 100000*s->blockSize100k) 264 | RETURN(BZ_DATA_ERROR); 265 | 266 | /*--- Receive the mapping table ---*/ 267 | for (i = 0; i < 16; i++) { 268 | GET_BIT(BZ_X_MAPPING_1, uc); 269 | if (uc == 1) 270 | s->inUse16[i] = True; else 271 | s->inUse16[i] = False; 272 | } 273 | 274 | for (i = 0; i < 256; i++) s->inUse[i] = False; 275 | 276 | for (i = 0; i < 16; i++) 277 | if (s->inUse16[i]) 278 | for (j = 0; j < 16; j++) { 279 | GET_BIT(BZ_X_MAPPING_2, uc); 280 | if (uc == 1) s->inUse[i * 16 + j] = True; 281 | } 282 | makeMaps_d ( s ); 283 | if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); 284 | alphaSize = s->nInUse+2; 285 | 286 | /*--- Now the selectors ---*/ 287 | GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); 288 | if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); 289 | GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); 290 | if (nSelectors < 1) RETURN(BZ_DATA_ERROR); 291 | for (i = 0; i < nSelectors; i++) { 292 | j = 0; 293 | while (True) { 294 | GET_BIT(BZ_X_SELECTOR_3, uc); 295 | if (uc == 0) break; 296 | j++; 297 | if (j >= nGroups) RETURN(BZ_DATA_ERROR); 298 | } 299 | s->selectorMtf[i] = j; 300 | } 301 | 302 | /*--- Undo the MTF values for the selectors. ---*/ 303 | { 304 | UChar pos[BZ_N_GROUPS], tmp, v; 305 | for (v = 0; v < nGroups; v++) pos[v] = v; 306 | 307 | for (i = 0; i < nSelectors; i++) { 308 | v = s->selectorMtf[i]; 309 | tmp = pos[v]; 310 | while (v > 0) { pos[v] = pos[v-1]; v--; } 311 | pos[0] = tmp; 312 | s->selector[i] = tmp; 313 | } 314 | } 315 | 316 | /*--- Now the coding tables ---*/ 317 | for (t = 0; t < nGroups; t++) { 318 | GET_BITS(BZ_X_CODING_1, curr, 5); 319 | for (i = 0; i < alphaSize; i++) { 320 | while (True) { 321 | if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); 322 | GET_BIT(BZ_X_CODING_2, uc); 323 | if (uc == 0) break; 324 | GET_BIT(BZ_X_CODING_3, uc); 325 | if (uc == 0) curr++; else curr--; 326 | } 327 | s->len[t][i] = curr; 328 | } 329 | } 330 | 331 | /*--- Create the Huffman decoding tables ---*/ 332 | for (t = 0; t < nGroups; t++) { 333 | minLen = 32; 334 | maxLen = 0; 335 | for (i = 0; i < alphaSize; i++) { 336 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; 337 | if (s->len[t][i] < minLen) minLen = s->len[t][i]; 338 | } 339 | BZ2_hbCreateDecodeTables ( 340 | &(s->limit[t][0]), 341 | &(s->base[t][0]), 342 | &(s->perm[t][0]), 343 | &(s->len[t][0]), 344 | minLen, maxLen, alphaSize 345 | ); 346 | s->minLens[t] = minLen; 347 | } 348 | 349 | /*--- Now the MTF values ---*/ 350 | 351 | EOB = s->nInUse+1; 352 | nblockMAX = 100000 * s->blockSize100k; 353 | groupNo = -1; 354 | groupPos = 0; 355 | 356 | for (i = 0; i <= 255; i++) s->unzftab[i] = 0; 357 | 358 | /*-- MTF init --*/ 359 | { 360 | Int32 ii, jj, kk; 361 | kk = MTFA_SIZE-1; 362 | for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { 363 | for (jj = MTFL_SIZE-1; jj >= 0; jj--) { 364 | s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); 365 | kk--; 366 | } 367 | s->mtfbase[ii] = kk + 1; 368 | } 369 | } 370 | /*-- end MTF init --*/ 371 | 372 | nblock = 0; 373 | GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); 374 | 375 | while (True) { 376 | 377 | if (nextSym == EOB) break; 378 | 379 | if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { 380 | 381 | es = -1; 382 | N = 1; 383 | do { 384 | /* Check that N doesn't get too big, so that es doesn't 385 | go negative. The maximum value that can be 386 | RUNA/RUNB encoded is equal to the block size (post 387 | the initial RLE), viz, 900k, so bounding N at 2 388 | million should guard against overflow without 389 | rejecting any legitimate inputs. */ 390 | if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR); 391 | if (nextSym == BZ_RUNA) es = es + (0+1) * N; else 392 | if (nextSym == BZ_RUNB) es = es + (1+1) * N; 393 | N = N * 2; 394 | GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); 395 | } 396 | while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); 397 | 398 | es++; 399 | uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; 400 | s->unzftab[uc] += es; 401 | 402 | if (s->smallDecompress) 403 | while (es > 0) { 404 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); 405 | s->ll16[nblock] = (UInt16)uc; 406 | nblock++; 407 | es--; 408 | } 409 | else 410 | while (es > 0) { 411 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); 412 | s->tt[nblock] = (UInt32)uc; 413 | nblock++; 414 | es--; 415 | }; 416 | 417 | continue; 418 | 419 | } else { 420 | 421 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); 422 | 423 | /*-- uc = MTF ( nextSym-1 ) --*/ 424 | { 425 | Int32 ii, jj, kk, pp, lno, off; 426 | UInt32 nn; 427 | nn = (UInt32)(nextSym - 1); 428 | 429 | if (nn < MTFL_SIZE) { 430 | /* avoid general-case expense */ 431 | pp = s->mtfbase[0]; 432 | uc = s->mtfa[pp+nn]; 433 | while (nn > 3) { 434 | Int32 z = pp+nn; 435 | s->mtfa[(z) ] = s->mtfa[(z)-1]; 436 | s->mtfa[(z)-1] = s->mtfa[(z)-2]; 437 | s->mtfa[(z)-2] = s->mtfa[(z)-3]; 438 | s->mtfa[(z)-3] = s->mtfa[(z)-4]; 439 | nn -= 4; 440 | } 441 | while (nn > 0) { 442 | s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 443 | }; 444 | s->mtfa[pp] = uc; 445 | } else { 446 | /* general case */ 447 | lno = nn / MTFL_SIZE; 448 | off = nn % MTFL_SIZE; 449 | pp = s->mtfbase[lno] + off; 450 | uc = s->mtfa[pp]; 451 | while (pp > s->mtfbase[lno]) { 452 | s->mtfa[pp] = s->mtfa[pp-1]; pp--; 453 | }; 454 | s->mtfbase[lno]++; 455 | while (lno > 0) { 456 | s->mtfbase[lno]--; 457 | s->mtfa[s->mtfbase[lno]] 458 | = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; 459 | lno--; 460 | } 461 | s->mtfbase[0]--; 462 | s->mtfa[s->mtfbase[0]] = uc; 463 | if (s->mtfbase[0] == 0) { 464 | kk = MTFA_SIZE-1; 465 | for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { 466 | for (jj = MTFL_SIZE-1; jj >= 0; jj--) { 467 | s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; 468 | kk--; 469 | } 470 | s->mtfbase[ii] = kk + 1; 471 | } 472 | } 473 | } 474 | } 475 | /*-- end uc = MTF ( nextSym-1 ) --*/ 476 | 477 | s->unzftab[s->seqToUnseq[uc]]++; 478 | if (s->smallDecompress) 479 | s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else 480 | s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); 481 | nblock++; 482 | 483 | GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); 484 | continue; 485 | } 486 | } 487 | 488 | /* Now we know what nblock is, we can do a better sanity 489 | check on s->origPtr. 490 | */ 491 | if (s->origPtr < 0 || s->origPtr >= nblock) 492 | RETURN(BZ_DATA_ERROR); 493 | 494 | /*-- Set up cftab to facilitate generation of T^(-1) --*/ 495 | /* Check: unzftab entries in range. */ 496 | for (i = 0; i <= 255; i++) { 497 | if (s->unzftab[i] < 0 || s->unzftab[i] > nblock) 498 | RETURN(BZ_DATA_ERROR); 499 | } 500 | /* Actually generate cftab. */ 501 | s->cftab[0] = 0; 502 | for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; 503 | for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; 504 | /* Check: cftab entries in range. */ 505 | for (i = 0; i <= 256; i++) { 506 | if (s->cftab[i] < 0 || s->cftab[i] > nblock) { 507 | /* s->cftab[i] can legitimately be == nblock */ 508 | RETURN(BZ_DATA_ERROR); 509 | } 510 | } 511 | /* Check: cftab entries non-descending. */ 512 | for (i = 1; i <= 256; i++) { 513 | if (s->cftab[i-1] > s->cftab[i]) { 514 | RETURN(BZ_DATA_ERROR); 515 | } 516 | } 517 | 518 | s->state_out_len = 0; 519 | s->state_out_ch = 0; 520 | BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); 521 | s->state = BZ_X_OUTPUT; 522 | if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); 523 | 524 | if (s->smallDecompress) { 525 | 526 | /*-- Make a copy of cftab, used in generation of T --*/ 527 | for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; 528 | 529 | /*-- compute the T vector --*/ 530 | for (i = 0; i < nblock; i++) { 531 | uc = (UChar)(s->ll16[i]); 532 | SET_LL(i, s->cftabCopy[uc]); 533 | s->cftabCopy[uc]++; 534 | } 535 | 536 | /*-- Compute T^(-1) by pointer reversal on T --*/ 537 | i = s->origPtr; 538 | j = GET_LL(i); 539 | do { 540 | Int32 tmp = GET_LL(j); 541 | SET_LL(j, i); 542 | i = j; 543 | j = tmp; 544 | } 545 | while (i != s->origPtr); 546 | 547 | s->tPos = s->origPtr; 548 | s->nblock_used = 0; 549 | if (s->blockRandomised) { 550 | BZ_RAND_INIT_MASK; 551 | BZ_GET_SMALL(s->k0); s->nblock_used++; 552 | BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 553 | } else { 554 | BZ_GET_SMALL(s->k0); s->nblock_used++; 555 | } 556 | 557 | } else { 558 | 559 | /*-- compute the T^(-1) vector --*/ 560 | for (i = 0; i < nblock; i++) { 561 | uc = (UChar)(s->tt[i] & 0xff); 562 | s->tt[s->cftab[uc]] |= (i << 8); 563 | s->cftab[uc]++; 564 | } 565 | 566 | s->tPos = s->tt[s->origPtr] >> 8; 567 | s->nblock_used = 0; 568 | if (s->blockRandomised) { 569 | BZ_RAND_INIT_MASK; 570 | BZ_GET_FAST(s->k0); s->nblock_used++; 571 | BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 572 | } else { 573 | BZ_GET_FAST(s->k0); s->nblock_used++; 574 | } 575 | 576 | } 577 | 578 | RETURN(BZ_OK); 579 | 580 | 581 | 582 | endhdr_2: 583 | 584 | GET_UCHAR(BZ_X_ENDHDR_2, uc); 585 | if (uc != 0x72) RETURN(BZ_DATA_ERROR); 586 | GET_UCHAR(BZ_X_ENDHDR_3, uc); 587 | if (uc != 0x45) RETURN(BZ_DATA_ERROR); 588 | GET_UCHAR(BZ_X_ENDHDR_4, uc); 589 | if (uc != 0x38) RETURN(BZ_DATA_ERROR); 590 | GET_UCHAR(BZ_X_ENDHDR_5, uc); 591 | if (uc != 0x50) RETURN(BZ_DATA_ERROR); 592 | GET_UCHAR(BZ_X_ENDHDR_6, uc); 593 | if (uc != 0x90) RETURN(BZ_DATA_ERROR); 594 | 595 | s->storedCombinedCRC = 0; 596 | GET_UCHAR(BZ_X_CCRC_1, uc); 597 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); 598 | GET_UCHAR(BZ_X_CCRC_2, uc); 599 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); 600 | GET_UCHAR(BZ_X_CCRC_3, uc); 601 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); 602 | GET_UCHAR(BZ_X_CCRC_4, uc); 603 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); 604 | 605 | s->state = BZ_X_IDLE; 606 | RETURN(BZ_STREAM_END); 607 | 608 | default: AssertH ( False, 4001 ); 609 | } 610 | 611 | AssertH ( False, 4002 ); 612 | 613 | save_state_and_return: 614 | 615 | s->save_i = i; 616 | s->save_j = j; 617 | s->save_t = t; 618 | s->save_alphaSize = alphaSize; 619 | s->save_nGroups = nGroups; 620 | s->save_nSelectors = nSelectors; 621 | s->save_EOB = EOB; 622 | s->save_groupNo = groupNo; 623 | s->save_groupPos = groupPos; 624 | s->save_nextSym = nextSym; 625 | s->save_nblockMAX = nblockMAX; 626 | s->save_nblock = nblock; 627 | s->save_es = es; 628 | s->save_N = N; 629 | s->save_curr = curr; 630 | s->save_zt = zt; 631 | s->save_zn = zn; 632 | s->save_zvec = zvec; 633 | s->save_zj = zj; 634 | s->save_gSel = gSel; 635 | s->save_gMinlen = gMinlen; 636 | s->save_gLimit = gLimit; 637 | s->save_gBase = gBase; 638 | s->save_gPerm = gPerm; 639 | 640 | return retVal; 641 | } 642 | 643 | 644 | /*-------------------------------------------------------------*/ 645 | /*--- end decompress.c ---*/ 646 | /*-------------------------------------------------------------*/ 647 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/huffman.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Huffman coding low-level stuff ---*/ 4 | /*--- huffman.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #include "bzlib_private.h" 23 | 24 | /*---------------------------------------------------*/ 25 | #define WEIGHTOF(zz0) ((zz0) & 0xffffff00) 26 | #define DEPTHOF(zz1) ((zz1) & 0x000000ff) 27 | #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) 28 | 29 | #define ADDWEIGHTS(zw1,zw2) \ 30 | (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ 31 | (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) 32 | 33 | #define UPHEAP(z) \ 34 | { \ 35 | Int32 zz, tmp; \ 36 | zz = z; tmp = heap[zz]; \ 37 | while (weight[tmp] < weight[heap[zz >> 1]]) { \ 38 | heap[zz] = heap[zz >> 1]; \ 39 | zz >>= 1; \ 40 | } \ 41 | heap[zz] = tmp; \ 42 | } 43 | 44 | #define DOWNHEAP(z) \ 45 | { \ 46 | Int32 zz, yy, tmp; \ 47 | zz = z; tmp = heap[zz]; \ 48 | while (True) { \ 49 | yy = zz << 1; \ 50 | if (yy > nHeap) break; \ 51 | if (yy < nHeap && \ 52 | weight[heap[yy+1]] < weight[heap[yy]]) \ 53 | yy++; \ 54 | if (weight[tmp] < weight[heap[yy]]) break; \ 55 | heap[zz] = heap[yy]; \ 56 | zz = yy; \ 57 | } \ 58 | heap[zz] = tmp; \ 59 | } 60 | 61 | 62 | /*---------------------------------------------------*/ 63 | void BZ2_hbMakeCodeLengths ( UChar *len, 64 | Int32 *freq, 65 | Int32 alphaSize, 66 | Int32 maxLen ) 67 | { 68 | /*-- 69 | Nodes and heap entries run from 1. Entry 0 70 | for both the heap and nodes is a sentinel. 71 | --*/ 72 | Int32 nNodes, nHeap, n1, n2, i, j, k; 73 | Bool tooLong; 74 | 75 | Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; 76 | Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; 77 | Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 78 | 79 | for (i = 0; i < alphaSize; i++) 80 | weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; 81 | 82 | while (True) { 83 | 84 | nNodes = alphaSize; 85 | nHeap = 0; 86 | 87 | heap[0] = 0; 88 | weight[0] = 0; 89 | parent[0] = -2; 90 | 91 | for (i = 1; i <= alphaSize; i++) { 92 | parent[i] = -1; 93 | nHeap++; 94 | heap[nHeap] = i; 95 | UPHEAP(nHeap); 96 | } 97 | 98 | AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); 99 | 100 | while (nHeap > 1) { 101 | n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); 102 | n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); 103 | nNodes++; 104 | parent[n1] = parent[n2] = nNodes; 105 | weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); 106 | parent[nNodes] = -1; 107 | nHeap++; 108 | heap[nHeap] = nNodes; 109 | UPHEAP(nHeap); 110 | } 111 | 112 | AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); 113 | 114 | tooLong = False; 115 | for (i = 1; i <= alphaSize; i++) { 116 | j = 0; 117 | k = i; 118 | while (parent[k] >= 0) { k = parent[k]; j++; } 119 | len[i-1] = j; 120 | if (j > maxLen) tooLong = True; 121 | } 122 | 123 | if (! tooLong) break; 124 | 125 | /* 17 Oct 04: keep-going condition for the following loop used 126 | to be 'i < alphaSize', which missed the last element, 127 | theoretically leading to the possibility of the compressor 128 | looping. However, this count-scaling step is only needed if 129 | one of the generated Huffman code words is longer than 130 | maxLen, which up to and including version 1.0.2 was 20 bits, 131 | which is extremely unlikely. In version 1.0.3 maxLen was 132 | changed to 17 bits, which has minimal effect on compression 133 | ratio, but does mean this scaling step is used from time to 134 | time, enough to verify that it works. 135 | 136 | This means that bzip2-1.0.3 and later will only produce 137 | Huffman codes with a maximum length of 17 bits. However, in 138 | order to preserve backwards compatibility with bitstreams 139 | produced by versions pre-1.0.3, the decompressor must still 140 | handle lengths of up to 20. */ 141 | 142 | for (i = 1; i <= alphaSize; i++) { 143 | j = weight[i] >> 8; 144 | j = 1 + (j / 2); 145 | weight[i] = j << 8; 146 | } 147 | } 148 | } 149 | 150 | 151 | /*---------------------------------------------------*/ 152 | void BZ2_hbAssignCodes ( Int32 *code, 153 | UChar *length, 154 | Int32 minLen, 155 | Int32 maxLen, 156 | Int32 alphaSize ) 157 | { 158 | Int32 n, vec, i; 159 | 160 | vec = 0; 161 | for (n = minLen; n <= maxLen; n++) { 162 | for (i = 0; i < alphaSize; i++) 163 | if (length[i] == n) { code[i] = vec; vec++; }; 164 | vec <<= 1; 165 | } 166 | } 167 | 168 | 169 | /*---------------------------------------------------*/ 170 | void BZ2_hbCreateDecodeTables ( Int32 *limit, 171 | Int32 *base, 172 | Int32 *perm, 173 | UChar *length, 174 | Int32 minLen, 175 | Int32 maxLen, 176 | Int32 alphaSize ) 177 | { 178 | Int32 pp, i, j, vec; 179 | 180 | pp = 0; 181 | for (i = minLen; i <= maxLen; i++) 182 | for (j = 0; j < alphaSize; j++) 183 | if (length[j] == i) { perm[pp] = j; pp++; }; 184 | 185 | for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; 186 | for (i = 0; i < alphaSize; i++) base[length[i]+1]++; 187 | 188 | for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; 189 | 190 | for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; 191 | vec = 0; 192 | 193 | for (i = minLen; i <= maxLen; i++) { 194 | vec += (base[i+1] - base[i]); 195 | limit[i] = vec-1; 196 | vec <<= 1; 197 | } 198 | for (i = minLen + 1; i <= maxLen; i++) 199 | base[i] = ((limit[i-1] + 1) << 1) - base[i]; 200 | } 201 | 202 | 203 | /*-------------------------------------------------------------*/ 204 | /*--- end huffman.c ---*/ 205 | /*-------------------------------------------------------------*/ 206 | -------------------------------------------------------------------------------- /include/bsdifflib/bzip2/randtable.c: -------------------------------------------------------------------------------- 1 | 2 | /*-------------------------------------------------------------*/ 3 | /*--- Table for randomising repetitive blocks ---*/ 4 | /*--- randtable.c ---*/ 5 | /*-------------------------------------------------------------*/ 6 | 7 | /* ------------------------------------------------------------------ 8 | This file is part of bzip2/libbzip2, a program and library for 9 | lossless, block-sorting data compression. 10 | 11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010 12 | Copyright (C) 1996-2010 Julian Seward 13 | 14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the 15 | README file. 16 | 17 | This program is released under the terms of the license contained 18 | in the file LICENSE. 19 | ------------------------------------------------------------------ */ 20 | 21 | 22 | #include "bzlib_private.h" 23 | 24 | 25 | /*---------------------------------------------*/ 26 | Int32 BZ2_rNums[512] = { 27 | 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 28 | 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 29 | 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 30 | 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 31 | 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 32 | 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 33 | 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 34 | 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 35 | 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 36 | 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 37 | 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 38 | 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 39 | 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 40 | 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 41 | 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 42 | 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 43 | 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 44 | 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 45 | 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 46 | 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 47 | 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 48 | 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 49 | 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 50 | 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 51 | 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 52 | 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 53 | 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 54 | 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 55 | 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 56 | 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 57 | 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 58 | 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 59 | 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 60 | 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 61 | 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 62 | 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 63 | 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 64 | 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 65 | 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 66 | 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 67 | 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 68 | 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 69 | 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 70 | 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 71 | 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 72 | 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 73 | 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 74 | 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 75 | 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 76 | 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 77 | 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 78 | 936, 638 79 | }; 80 | 81 | 82 | /*-------------------------------------------------------------*/ 83 | /*--- end randtable.c ---*/ 84 | /*-------------------------------------------------------------*/ 85 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) { 6 | QApplication a(argc, argv); 7 | MainWindow w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "include/bsdifflib/bsdifflib.h" 3 | #include "include/bsdifflib/bspatchlib.h" 4 | #include "ui_mainwindow.h" 5 | #include 6 | #include 7 | 8 | static QString *create_sourceFilePath = new QString(); 9 | static QString *create_newFilePath = new QString(); 10 | static QString *create_patchFilePath = new QString(); 11 | 12 | static QString *apply_oldFilePath = new QString(); 13 | static QString *apply_patchFilePath = new QString(); 14 | static QString *apply_newFilePath = new QString(); 15 | 16 | static Page_Elements *createElements = new Page_Elements(); 17 | static Page_Elements *applyElements = new Page_Elements(); 18 | 19 | void clickFileDialogButton(MainWindow *w, bool existingFile, QLabel *label, 20 | QString *path) { 21 | QFileDialog dialog(w); 22 | if (existingFile) 23 | dialog.setFileMode(QFileDialog::ExistingFile); 24 | else 25 | dialog.setFileMode(QFileDialog::AnyFile); 26 | if (dialog.exec()) 27 | *path = dialog.selectedFiles()[0]; 28 | 29 | label->setText(*path); 30 | } 31 | 32 | void initCreatePatch(QString *oldPath, QString *newPath, QString *patchPath) { 33 | QMessageBox res; 34 | char *errs = 35 | bsdiff(oldPath->toUtf8(), newPath->toUtf8(), patchPath->toUtf8()); 36 | if (errs) 37 | res.setText(errs); 38 | else 39 | res.setText(patchPath->toUtf8() + " created successfully!"); 40 | res.exec(); 41 | } 42 | 43 | void initApplyPatch(QString *oldPath, QString *newPath, QString *patchPath) { 44 | QMessageBox res; 45 | char *errs = 46 | bspatch(oldPath->toUtf8(), newPath->toUtf8(), patchPath->toUtf8()); 47 | if (errs) 48 | res.setText(errs); 49 | else 50 | res.setText(newPath->toUtf8() + " created successfully!"); 51 | res.exec(); 52 | } 53 | 54 | MainWindow::MainWindow(QWidget *parent) 55 | : QMainWindow(parent), ui(new Ui::MainWindow) { 56 | ui->setupUi(this); 57 | 58 | // set about page label 59 | QLabel *aboutLabel = this->findChild("aboutLabel"); 60 | aboutLabel->setOpenExternalLinks(true); 61 | aboutLabel->setText( 62 | "PatchGUI Utility"); 63 | 64 | // assign pointer elements (create) 65 | createElements->oldFileButton = 66 | findChild("create_sourceFileButton"); 67 | createElements->newFileButton = 68 | findChild("create_newFileButton"); 69 | createElements->patchFileButton = 70 | findChild("create_patchFileButton"); 71 | createElements->initButton = findChild("create_initButton"); 72 | createElements->oldFileLabel = findChild("create_sourceFileLabel"); 73 | createElements->newFileLabel = findChild("create_newFileLabel"); 74 | createElements->patchFileLabel = findChild("create_patchFileLabel"); 75 | 76 | // assign pointer elements (apply) 77 | applyElements->oldFileButton = 78 | findChild("apply_oldFileButton"); 79 | applyElements->patchFileButton = 80 | findChild("apply_patchFileButton"); 81 | applyElements->newFileButton = 82 | findChild("apply_newFileButton"); 83 | applyElements->initButton = findChild("apply_initButton"); 84 | applyElements->oldFileLabel = findChild("apply_oldFileLabel"); 85 | applyElements->patchFileLabel = findChild("apply_patchFileLabel"); 86 | applyElements->newFileLabel = findChild("apply_newFileLabel"); 87 | 88 | // connect functions to buttons (create) 89 | connect(createElements->oldFileButton, &QPushButton::clicked, [&] { 90 | clickFileDialogButton(this, true, createElements->oldFileLabel, 91 | create_sourceFilePath); 92 | }); 93 | connect(createElements->newFileButton, &QPushButton::clicked, [&] { 94 | clickFileDialogButton(this, true, createElements->newFileLabel, 95 | create_newFilePath); 96 | }); 97 | connect(createElements->patchFileButton, &QPushButton::clicked, [&] { 98 | clickFileDialogButton(this, false, createElements->patchFileLabel, 99 | create_patchFilePath); 100 | }); 101 | connect(createElements->initButton, &QPushButton::clicked, [&] { 102 | initCreatePatch(create_sourceFilePath, create_newFilePath, 103 | create_patchFilePath); 104 | }); 105 | 106 | // connect functions to buttons (apply) 107 | connect(applyElements->oldFileButton, &QPushButton::clicked, [&] { 108 | clickFileDialogButton(this, true, applyElements->oldFileLabel, 109 | apply_oldFilePath); 110 | }); 111 | connect(applyElements->patchFileButton, &QPushButton::clicked, [&] { 112 | clickFileDialogButton(this, true, applyElements->patchFileLabel, 113 | apply_patchFilePath); 114 | }); 115 | connect(applyElements->newFileButton, &QPushButton::clicked, [&] { 116 | clickFileDialogButton(this, false, applyElements->newFileLabel, 117 | apply_newFilePath); 118 | }); 119 | connect(applyElements->initButton, &QPushButton::clicked, [&] { 120 | initApplyPatch(apply_oldFilePath, apply_newFilePath, apply_patchFilePath); 121 | }); 122 | } 123 | 124 | MainWindow::~MainWindow() { 125 | delete ui; 126 | delete create_newFilePath; 127 | delete create_sourceFilePath; 128 | delete create_patchFilePath; 129 | delete apply_newFilePath; 130 | delete apply_oldFilePath; 131 | delete apply_patchFilePath; 132 | delete createElements; 133 | delete applyElements; 134 | } 135 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | typedef struct Page_Elements { 10 | QPushButton *oldFileButton; 11 | QPushButton *patchFileButton; 12 | QPushButton *newFileButton; 13 | QPushButton *initButton; 14 | QLabel *oldFileLabel; 15 | QLabel *patchFileLabel; 16 | QLabel *newFileLabel; 17 | } Page_Elements; 18 | 19 | namespace Ui { 20 | class MainWindow; 21 | } 22 | 23 | class MainWindow : public QMainWindow { 24 | Q_OBJECT 25 | 26 | public: 27 | explicit MainWindow(QWidget *parent = nullptr); 28 | ~MainWindow(); 29 | 30 | private: 31 | Ui::MainWindow *ui; 32 | }; 33 | 34 | #endif // MAINWINDOW_H 35 | -------------------------------------------------------------------------------- /mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | PatchGUI 15 | 16 | 17 | 18 | 19 | 2 20 | 21 | 22 | 0 23 | 24 | 25 | 2 26 | 27 | 28 | 2 29 | 30 | 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | Create Patch 38 | 39 | 40 | 41 | 42 | 43 | Browse 44 | 45 | 46 | 47 | 48 | 49 | 50 | Browse 51 | 52 | 53 | 54 | 55 | 56 | 57 | New version of Source File: 58 | 59 | 60 | 61 | 62 | 63 | 64 | Source File: 65 | 66 | 67 | 68 | 69 | 70 | 71 | Patch File to be created: 72 | 73 | 74 | 75 | 76 | 77 | 78 | Browse 79 | 80 | 81 | 82 | 83 | 84 | 85 | Create Patch 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Apply Patch 94 | 95 | 96 | 97 | 98 | 99 | Old File: 100 | 101 | 102 | 103 | 104 | 105 | 106 | Browse 107 | 108 | 109 | 110 | 111 | 112 | 113 | Patch File: 114 | 115 | 116 | 117 | 118 | 119 | 120 | Browse 121 | 122 | 123 | 124 | 125 | 126 | 127 | New File to be created: 128 | 129 | 130 | 131 | 132 | 133 | 134 | Browse 135 | 136 | 137 | 138 | 139 | 140 | 141 | Apply Patch 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | About 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | Qt::Vertical 163 | 164 | 165 | 166 | 20 167 | 40 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | --------------------------------------------------------------------------------