├── .gitattributes ├── .gitignore ├── ChangeLog.txt ├── Linux └── Linux.vcxproj ├── README.md ├── RubiChess.sln ├── copying └── src ├── Makefile ├── Makefile.clang ├── RubiChess.cbp ├── RubiChess.h ├── RubiChess.vcxproj ├── RubiChess.vcxproj.filters ├── board.cpp ├── book.cpp ├── cputest.cpp ├── engine.cpp ├── eval.cpp ├── learn.cpp ├── main.cpp ├── move.cpp ├── nnue.cpp ├── release.cmd ├── search.cpp ├── tbcore.c ├── tbcore.h ├── tbprobe.cpp ├── texel.cpp ├── transposition.cpp ├── utils.cpp └── zlib ├── README ├── adler32.c ├── compress.c ├── crc32.c ├── crc32.h ├── deflate.c ├── deflate.h ├── gzclose.c ├── gzguts.h ├── gzlib.c ├── gzread.c ├── gzwrite.c ├── infback.c ├── inffast.c ├── inffast.h ├── inffixed.h ├── inflate.c ├── inflate.h ├── inftrees.c ├── inftrees.h ├── trees.c ├── trees.h ├── uncompr.c ├── zconf.h ├── zlib.h ├── zutil.c └── zutil.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc 262 | 263 | # Linux object files 264 | *.o 265 | 266 | # Executables 267 | *.exe 268 | 269 | # Network weight files 270 | *.nnue 271 | *.z 272 | 273 | # Linux executables 274 | /src/RubiChess 275 | /src/cputest 276 | *.lib 277 | *.a 278 | -------------------------------------------------------------------------------- /Linux/Linux.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | ARM 7 | 8 | 9 | Release 10 | ARM 11 | 12 | 13 | Debug 14 | ARM64 15 | 16 | 17 | Release 18 | ARM64 19 | 20 | 21 | Debug 22 | x86 23 | 24 | 25 | Release 26 | x86 27 | 28 | 29 | Debug 30 | x64 31 | 32 | 33 | Release 34 | x64 35 | 36 | 37 | 38 | {04c5e994-b673-4e72-a9a2-c6fd9f2afb9d} 39 | Linux 40 | Linux 41 | 15.0 42 | Linux 43 | 1.0 44 | Generic 45 | {D51BCBC9-82E9-4017-911E-C93873C4EA2B} 46 | Rubi for Linux 47 | 48 | 49 | 50 | true 51 | 52 | 53 | false 54 | 55 | 56 | true 57 | 58 | 59 | false 60 | 61 | 62 | true 63 | 64 | 65 | false 66 | 67 | 68 | false 69 | 70 | 71 | true 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | RubiChess 80 | 81 | 82 | 83 | RubiChess 84 | 85 | 86 | 87 | RubiChess 88 | 89 | 90 | 91 | RubiChess 92 | 93 | 94 | 95 | RubiChess 96 | 97 | 98 | 99 | RubiChess 100 | 101 | 102 | 103 | RubiChess 104 | 105 | 106 | 107 | RubiChess 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | CppCode 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | true 147 | true 148 | true 149 | true 150 | true 151 | true 152 | true 153 | true 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | pthread;z 174 | 175 | 176 | USE_ZLIB;USE_NEON;NDEBUG;%(PreprocessorDefinitions) 177 | 178 | 179 | 180 | 181 | pthread;z 182 | 183 | 184 | USE_ZLIB;USE_NEON;;NDEBUG;%(PreprocessorDefinitions) 185 | 186 | 187 | 188 | 189 | pthread;z 190 | 191 | 192 | 193 | 194 | pthread;z 195 | 196 | 197 | 198 | 199 | pthread;z 200 | 201 | 202 | USE_ZLIB;USE_NEON 203 | 204 | 205 | 206 | 207 | pthread;z 208 | 209 | 210 | USE_ZLIB;USE_NEON 211 | 212 | 213 | 214 | 215 | pthread;z 216 | 217 | 218 | 219 | 220 | pthread;z 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RubiChess 2 | Just another UCI compliant chess engine. Have a look at the ChangeLog for a detailed feature list. 3 | 4 | 'UCI compliant' means that for best user experience you need a chess GUI like Arena, CuteChess or BanksiaGUI (just to name some free programs) and install RubiChess as an engine in this GUI. 5 | 6 | RubiChess development started in 2016 as a private hobby project to practise programming in C++ and to see the engine improving compared 7 | to earlier releases. Meanwhile some years later RubiChess got pretty competitive and is listed in most of the rankings and plays 8 | a lot of even big tournaments. 9 | 10 | I'm still not very good in C++ using a C-style code most of the time but the whole project was and is a lot of fun. 11 | 12 | Many thanks to the excellent documentation at https://chessprogramming.org. 13 | Also many thanks to Bluefever and his video tutorial https://www.youtube.com/user/BlueFeverSoft/videos 14 | A special thank you goes to open source engine Olithink. I had a look at its source code or even two. 15 | And while improving RubiChess more and more I looked at several open source engines like 16 | Ethereal, Stockfish, Pirarucu, Laser, Koivisto, Berserk, ... 17 | Thank you for the great list of engines at http://www.computerchess.org.uk/ccrl/4040/ 18 | Not mentioned all the other documentation and tools freely available. 19 | 20 | Also a big thank you goes to the guys at http://chess.grantnet.us/ especially to Andrew Grant for running and improving this testing framework and to Bojun Guo (noobpwnftw) for spending all the hardware resources for testing. 21 | ## NNUE 22 | Starting with version 1.9 RubiChess supports evaluation using NNUE weight files. With version 2.0 NNUE evaluation becomes the default. 23 | 24 | Disable the 'Use_NNUE' option for so called handcrafted evaluation. 25 | 26 | Use the 'NNUENetpath' option to switch to a different network weight file. 27 | 28 | You can download network files from my repository https://github.com/Matthies/NN and put it in the same folder as the executable. 29 | 30 | Current default net will be downloaded automatically when compiling the engine and is also included in Windows release packages. 31 | 32 | ## Binaries and hints to build some 33 | I provide release binary packages for Windows x64 only. Depending on the type of your x86-64 CPU you can choose from 34 | - __RubiChess-x86-64-avx512__: For best performance on new Intel CPUs supporting the AVX512 extensions. 35 | - __RubiChess-x86-64-bmi2__: For best performance on modern Intel CPUs and AMD Ryzen starting from Zen3/5?00X CPU 36 | - __RubiChess-x86-64-avx2__: For best performance on modern AMD Ryzen Zen/Zen2 37 | - __RubiChess-x86-64-modern__: For older CPUs that support POPCNT but no AVX2 38 | - __RubiChess-x86-64-ssse3__: For even older CPUs with SSSE3 but no POPCNT 39 | - __RubiChess-x86-64-sse3-popcount__: For old AMD CPUs supporting POPCNT and SSE3 but no SSSE3 like Phenom II 40 | - __RubiChess-x86-64-sse2__: This should run on even oldest x86-64 CPU 41 | - __RubiChess-x86-64__: Native and slowest build without SIMD support, just for debugging purposes 42 | 43 | You will get a warning at startup if the selected binary doesn't match your CPU or it will just crash. 44 | 45 | RubiChess should build successfully on any x64 Linux, on MacOS (x64 and ARM64/M1) and on Raspbian (at least up to Raspi 3 and 4 which I own and tested) using ```make``` from inside the src subfolder. 46 | 47 | For fastest binaries you should use the Intel icx compiler (based on Clang/LLVM but with Intel's optimizations) and the following build command 48 | 49 | ```make profile-build COMP=icx``` 50 | 51 | or native Clang which is a little bit slower: 52 | 53 | ```make profile-build COMP=clang``` 54 | 55 | You may need to install some additional packages like the Intel compiler (https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp) or clang, lld and llvm and add bin paths of compiler and profiler to your PATH to make this work. 56 | 57 | You can also use the (default) gcc/g++ compiler ```make profile-build``` which probably works without additional packages but the binaries will be a little bit slower. 58 | 59 | Some more notes about compiling (for me and maybe others): 60 | 61 | - For a profile-build in MacOS (Darwin) you have to include the folder containing the llvm-profdata tool in your PATH: 62 | 63 | ```export PATH=$PATH:/Library/Developer/CommandLineTools/usr/bin/``` 64 | 65 | - For a build using the Intel icx compiler (unzipped to your home folder) add two folders to your path 66 | 67 | ```export PATH=~/intel/oneapi/compiler/latest/linux/bin/:~/intel/oneapi/compiler/latest/linux/bin-llvm/:$PATH``` 68 | 69 | - By default a 'native' binary is compiled by detecting the CPU features of the computer. If you want to create a binary with a special set of CPU features, append ARCH=x86-64-... parameter to make. For a list of supported archs look above. 70 | 71 | - For profiling an arch not supported by your CPU (like x86-64-avx512 in my case), you can use Intel's SDE by giving SDE=/path/to/sde to the make process: 72 | 73 | ```make release COMP=icx SDE=~/sde-external-9.14.0-2022-10-25-lin/sde``` 74 | 75 | - The Wiki has some additional informations about compiling RubiChess for Android: https://github.com/Matthies/RubiChess/wiki/Compiling-RubiChess-for-Android 76 | -------------------------------------------------------------------------------- /RubiChess.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.6.33801.468 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RubiChess", "src\RubiChess.vcxproj", "{83509B25-2DA0-42F8-8ABE-F3DB5C736D23}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Rubi for Linux", "Linux\Linux.vcxproj", "{04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|ARM = Debug|ARM 13 | Debug|ARM64 = Debug|ARM64 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|ARM = Release|ARM 17 | Release|ARM64 = Release|ARM64 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|ARM.ActiveCfg = Debug|ARM 23 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|ARM.Build.0 = Debug|ARM 24 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|ARM64.ActiveCfg = Debug|ARM64 25 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|ARM64.Build.0 = Debug|ARM64 26 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|x64.ActiveCfg = Debug|x64 27 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|x64.Build.0 = Debug|x64 28 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|x86.ActiveCfg = Debug|Win32 29 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Debug|x86.Build.0 = Debug|Win32 30 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|ARM.ActiveCfg = Release|ARM 31 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|ARM.Build.0 = Release|ARM 32 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|ARM64.ActiveCfg = Release|ARM64 33 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|ARM64.Build.0 = Release|ARM64 34 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|x64.ActiveCfg = Release|x64 35 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|x64.Build.0 = Release|x64 36 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|x86.ActiveCfg = Release|Win32 37 | {83509B25-2DA0-42F8-8ABE-F3DB5C736D23}.Release|x86.Build.0 = Release|Win32 38 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM.ActiveCfg = Debug|ARM 39 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM.Build.0 = Debug|ARM 40 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM.Deploy.0 = Debug|ARM 41 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM64.ActiveCfg = Debug|ARM64 42 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM64.Build.0 = Debug|ARM64 43 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|ARM64.Deploy.0 = Debug|ARM64 44 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x64.ActiveCfg = Debug|x64 45 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x64.Build.0 = Debug|x64 46 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x64.Deploy.0 = Debug|x64 47 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x86.ActiveCfg = Debug|x86 48 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x86.Build.0 = Debug|x86 49 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Debug|x86.Deploy.0 = Debug|x86 50 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM.ActiveCfg = Release|ARM 51 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM.Build.0 = Release|ARM 52 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM.Deploy.0 = Release|ARM 53 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM64.ActiveCfg = Release|ARM64 54 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM64.Build.0 = Release|ARM64 55 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|ARM64.Deploy.0 = Release|ARM64 56 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x64.ActiveCfg = Release|x64 57 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x64.Build.0 = Release|x64 58 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x64.Deploy.0 = Release|x64 59 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x86.ActiveCfg = Release|x86 60 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x86.Build.0 = Release|x86 61 | {04C5E994-B673-4E72-A9A2-C6FD9F2AFB9D}.Release|x86.Deploy.0 = Release|x86 62 | EndGlobalSection 63 | GlobalSection(SolutionProperties) = preSolution 64 | HideSolutionNode = FALSE 65 | EndGlobalSection 66 | GlobalSection(ExtensibilityGlobals) = postSolution 67 | SolutionGuid = {55E6DCFB-A206-41CE-8636-7AF6221BBB83} 68 | EndGlobalSection 69 | EndGlobal 70 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile to compile RubiChess in a standard GNU/Makefile environment 3 | # 4 | 5 | MAKEFLAGS += --no-print-directory 6 | 7 | # Some variables for my private build system 8 | ANDROIDEMU = ~/Android/Sdk/emulator/emulator 9 | ANDROIDDEVICE = 192.168.1.167:5555 10 | SDE = ~/sde/sde 11 | 12 | ifeq ($(OS), Windows_NT) 13 | EXEEXT=.exe 14 | else 15 | EXEEXT= 16 | endif 17 | 18 | CPUTEST = cputest 19 | ARCH = native 20 | PROFDIR = OPT 21 | PROFEXE = RubiChess 22 | STRIP = strip 23 | 24 | sse2 = no 25 | ssse3 = no 26 | popcnt = no 27 | bmi1 = no 28 | lzcnt = no 29 | avx2 = no 30 | bmi2 = no 31 | avx512 = no 32 | neon = no 33 | arm64 = no 34 | dotprod = no 35 | zlib = no 36 | debug = no 37 | bits = 64 38 | 39 | PTHREADLIB=-pthread 40 | 41 | UNAME_S=$(shell uname -s) 42 | UNAME_M=$(shell uname -m) 43 | 44 | ifeq ($(UNAME_S),Darwin) 45 | # Use clang compiler for MacOS 46 | COMP=clang 47 | endif 48 | 49 | ifeq ($(COMP),) 50 | COMP=gcc 51 | endif 52 | 53 | ifeq ($(EXE),) 54 | EXE=RubiChess 55 | endif 56 | 57 | CXXFLAGS=-std=c++11 -Wall -pedantic -Wextra -Wshadow 58 | CFLAGS=-Wall -pedantic -Wextra -Wshadow -Wno-implicit-function-declaration 59 | 60 | 61 | ifeq ($(debug),yes) 62 | CXXFLAGS += -g -O0 63 | CFLAGS += -g -O0 64 | else 65 | CXXFLAGS += -O3 -flto 66 | CFLAGS += -O3 67 | endif 68 | 69 | ifneq (, $(findstring MINGW64,$(UNAME_S))) 70 | # Always do a static built with Mingw 71 | LDFLAGS += -static 72 | endif 73 | ifneq (, $(findstring MINGW32,$(UNAME_S))) 74 | # Always do a static built with Mingw 75 | LDFLAGS += -static 76 | bits = 32 77 | endif 78 | ifeq ($(COMP),$(filter $(COMP),gcc)) 79 | CXX=g++ 80 | # Workaround OB giving wrong CC=g++ 81 | MYCC=gcc 82 | INSTRUMENTEDEXTRACXXFLAGS='-fprofile-generate=$(PROFDIR)' 83 | INSTRUMENTEDEXTRALDFLAGS='-lgcov' 84 | PGOEXTRACXXFLAGS='-fprofile-use=$(PROFDIR) -fno-peel-loops -fno-tracer -Wno-coverage-mismatch -fprofile-correction' 85 | PGOEXTRALDFLAGS='-lgcov' 86 | PROFMERGE= 87 | endif 88 | 89 | ifeq ($(COMP),$(filter $(COMP), clang ndk icx)) 90 | CXX=clang++ 91 | MYCC=clang 92 | ifeq ($(COMP),$(filter $(COMP), icx)) 93 | CXX=icpx 94 | MYCC=icx 95 | endif 96 | LDFLAGS += $(shell type lld 1>/dev/null 2>/dev/null && echo "-fuse-ld=lld") 97 | INSTRUMENTEDEXTRACXXFLAGS='-fprofile-instr-generate=$(EXE).clangprof-raw' 98 | INSTRUMENTEDEXTRALDFLAGS= 99 | PGOEXTRACXXFLAGS='-fprofile-instr-use=$(EXE).profdata' 100 | PGOEXTRALDFLAGS= 101 | PROFMERGE=llvm-profdata merge -output=$(EXE).profdata $(EXE).clangprof-raw 102 | endif 103 | 104 | 105 | ifeq ($(UNAME_M),armv6l) 106 | # FIXME: Find better flags 107 | CXXFLAGS += -mcpu=native 108 | ARCHFAMILY=arm32 109 | bits = 32 110 | endif 111 | 112 | ifeq ($(UNAME_M),armv7l) 113 | # FIXME: Hardcoded -mfpu=neon for Neon support 114 | CXXFLAGS += -mthumb -march=armv7-a -mfpu=neon 115 | ARCHFAMILY=arm32 116 | bits = 32 117 | endif 118 | 119 | ifeq ($(UNAME_M),aarch64) 120 | # ARM64... any better flags that work with gcc and clang?? 121 | CXXFLAGS += -mcpu=native 122 | ARCHFAMILY=arm64 123 | bits = 64 124 | endif 125 | 126 | ifeq ($(UNAME_M),x86_64) 127 | ARCHFAMILY=x86 128 | endif 129 | 130 | ifeq ($(COMP),ndk) 131 | ARCHFAMILY=android 132 | STRIP=llvm-strip 133 | AR=llvm-ar 134 | EXEEXT= 135 | ifeq ($(ARCH),armv7) 136 | CXX=armv7a-linux-androideabi21-clang++ 137 | MYCC=armv7a-linux-androideabi21-clang 138 | CXXFLAGS += -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon 139 | endif 140 | ifneq (,$(findstring armv8,$(ARCH))) 141 | CXX=aarch64-linux-android21-clang++ 142 | MYCC=aarch64-linux-android21-clang 143 | ifneq (,$(findstring -dotprod,$(ARCH))) 144 | CXXFLAGS += -mcpu=cortex-a53+dotprod 145 | endif 146 | endif 147 | ifeq ($(ARCH),x86-32) 148 | CXX=i686-linux-android21-clang++ 149 | MYCC=i686-linux-android21-clang 150 | CPUFLAGS = "ssse3 sse2" 151 | bits = 32 152 | endif 153 | ifeq ($(ARCH),x86-64) 154 | CXX=x86_64-linux-android21-clang++ 155 | MYCC=x86_64-linux-android21-clang 156 | CPUFLAGS = "popcnt lzcnt ssse3 sse2" 157 | endif 158 | LDFLAGS += -static-libstdc++ 159 | endif 160 | 161 | 162 | ZLIBDIR=zlib 163 | CXXFLAGS += -Izlib 164 | LDFLAGS += -Lzlib 165 | zlib = yes 166 | 167 | ifeq (,$(CPUFLAGS)) 168 | ifeq ($(ARCH),native) 169 | ifeq ($(wildcard ./$(CPUTEST)),) 170 | $(shell $(CXX) $(CXXFLAGS) $(LDFLAGS) -DCPUTEST $(CPUTEST).cpp -o $(CPUTEST)) 171 | endif 172 | CPUFLAGS = "$(shell ./$(CPUTEST))" 173 | endif 174 | 175 | # Common supported x86 and ARM architectures 176 | ifeq ($(findstring x86-32,$(ARCH)),x86-32) 177 | bits = 32 178 | endif 179 | ifeq ($(findstring x86-64,$(ARCH)),x86-64) 180 | bits = 64 181 | endif 182 | ifneq (,$(findstring -sse2,$(ARCH))) 183 | CPUFLAGS = "sse2" 184 | endif 185 | ifneq (,$(findstring -avx512,$(ARCH))) 186 | CPUFLAGS = "avx512 bmi2 avx2 bmi1 lzcnt popcnt ssse3 sse2" 187 | endif 188 | ifneq (,$(findstring -bmi2,$(ARCH))) 189 | CPUFLAGS = "bmi2 avx2 bmi1 lzcnt popcnt ssse3 sse2" 190 | endif 191 | ifneq (,$(findstring -avx2,$(ARCH))) 192 | CPUFLAGS = "avx2 bmi1 lzcnt popcnt ssse3 sse2" 193 | endif 194 | ifneq (,$(findstring -modern,$(ARCH))) 195 | CPUFLAGS = "popcnt ssse3 sse2" 196 | endif 197 | ifneq (,$(findstring -ssse3,$(ARCH))) 198 | CPUFLAGS = "ssse3 sse2" 199 | endif 200 | ifneq (,$(findstring -sse3-popcnt,$(ARCH))) 201 | CPUFLAGS = "popcnt sse2" 202 | endif 203 | ifneq (,$(findstring armv6,$(ARCH))) 204 | CPUFLAGS = "" 205 | bits = 32 206 | endif 207 | ifneq (,$(findstring armv7,$(ARCH))) 208 | CPUFLAGS = "neon" 209 | bits = 32 210 | endif 211 | ifneq (,$(findstring armv8,$(ARCH))) 212 | CPUFLAGS = "neon arm64" 213 | bits = 64 214 | endif 215 | ifneq (,$(findstring -dotprod,$(ARCH))) 216 | CPUFLAGS += " dotprod" 217 | endif 218 | endif 219 | 220 | ifneq (,$(findstring avx512,$(CPUFLAGS))) 221 | avx512 = yes 222 | endif 223 | ifneq (,$(findstring bmi2,$(CPUFLAGS))) 224 | bmi2 = yes 225 | endif 226 | ifneq (,$(findstring avx2,$(CPUFLAGS))) 227 | avx2 = yes 228 | endif 229 | ifneq (,$(findstring bmi1,$(CPUFLAGS))) 230 | bmi1 = yes 231 | endif 232 | ifneq (,$(findstring lzcnt,$(CPUFLAGS))) 233 | lzcnt = yes 234 | endif 235 | ifneq (,$(findstring popcnt,$(CPUFLAGS))) 236 | popcnt = yes 237 | endif 238 | ifneq (,$(findstring ssse3,$(CPUFLAGS))) 239 | ssse3 = yes 240 | endif 241 | ifneq (,$(findstring sse2,$(CPUFLAGS))) 242 | sse2 = yes 243 | endif 244 | ifneq (,$(findstring neon,$(CPUFLAGS))) 245 | neon = yes 246 | endif 247 | ifneq (,$(findstring arm64,$(CPUFLAGS))) 248 | arm64 = yes 249 | endif 250 | ifneq (,$(findstring dotprod,$(CPUFLAGS))) 251 | dotprod = yes 252 | endif 253 | 254 | ifeq ($(neon),no) 255 | ifeq (,$(findstring armv,$(UNAME_M))) 256 | ARCHFLAGS = -m$(bits) 257 | endif 258 | endif 259 | ifeq ($(bits),64) 260 | CXXFLAGS += -DIS_64BIT 261 | endif 262 | 263 | ifeq ($(avx512),yes) 264 | ARCHFLAGS += -DUSE_AVX512 -mavx512f -mavx512bw 265 | endif 266 | ifeq ($(bmi2),yes) 267 | ARCHFLAGS += -DUSE_BMI2 -mbmi2 268 | endif 269 | ifeq ($(avx2),yes) 270 | ARCHFLAGS += -DUSE_AVX2 -mavx2 271 | endif 272 | ifeq ($(bmi1)$(lzcnt),yesyes) 273 | ARCHFLAGS += -DUSE_BMI1 -mbmi -mlzcnt 274 | endif 275 | ifeq ($(popcnt),yes) 276 | ARCHFLAGS += -DUSE_POPCNT -mpopcnt -msse3 277 | endif 278 | ifeq ($(ssse3),yes) 279 | ARCHFLAGS += -DUSE_SSSE3 -mssse3 280 | endif 281 | ifeq ($(sse2),yes) 282 | ARCHFLAGS += -DUSE_SSE2 -msse2 283 | endif 284 | ifeq ($(neon),yes) 285 | ARCHFLAGS += -DUSE_NEON 286 | endif 287 | ifeq ($(arm64),yes) 288 | ARCHFLAGS += -DUSE_ARM64 289 | endif 290 | ifeq ($(dotprod),yes) 291 | ARCHFLAGS += -DUSE_DOTPROD 292 | endif 293 | ifeq ($(zlib),yes) 294 | CXXFLAGS += -DUSE_ZLIB 295 | LDFLAGS += -lz 296 | endif 297 | 298 | DEPS = RubiChess.h 299 | 300 | GITVER = $(shell 2>/dev/null git show --name-only --abbrev-commit --date=format:%Y%m%d | grep -i "date:" | grep -o -E '[0-9]+') 301 | GITID = $(shell 2>/dev/null git show --name-only --abbrev-commit | grep -i -o -E "ommit[[:blank:]]+[0-9a-f]{6}" | grep -o -E '[0-9a-f]+') 302 | ifneq ($(GITVER),) 303 | GITDEFINE = -D GITVER=\"$(GITVER)\" 304 | endif 305 | ifneq ($(GITID),) 306 | GITDEFINE += -D GITID=\"$(GITID)\" 307 | endif 308 | 309 | RUBINET = $(shell grep "NNUEDEFAULT " RubiChess.h | awk '{print $$3}') 310 | RUBINETHASH = $(shell echo $(RUBINET) | awk -F'-' '{print $$2}') 311 | NETURL = https://github.com/Matthies/NN/raw/main/ 312 | $(eval WGETCMD := $(shell if hash wget 2>/dev/null; then echo "wget -qO-"; elif hash curl 2>/dev/null; then echo "curl -skL"; fi)) 313 | ifneq ($(PROXY),) 314 | WGETCMD += -e https_proxy=$(PROXY) 315 | endif 316 | 317 | NETBIN = net.nnue 318 | ifneq ($(EVALFILE),) 319 | ifeq ($(EVALFILE),default) 320 | EMBEDFILE = $(RUBINET) 321 | else 322 | EMBEDFILE = $(EVALFILE) 323 | endif 324 | NETDEF = -DNNUEINCLUDED=$(EMBEDFILE) 325 | NETOBJ = net.o 326 | endif 327 | 328 | ifeq ($(GITVER),) 329 | MAJORVERSION = $(shell grep "\#define VERNUMLEGACY " RubiChess.h | awk '{print $$3}') 330 | else 331 | MAJORVERSION = $(GITVER) 332 | endif 333 | MINORVERSION = "" 334 | VERSION=$(MAJORVERSION)$(MINORVERSION) 335 | 336 | .PHONY: clean profile-build gcc-profile-make clang-profile-make net arch compile profilebench instrumentedcompile pgo profile-build pgo-rename release_x86 release_arm32 release_arm64 release 337 | 338 | default: net 339 | @$(MAKE) -j1 pgo MESSAGE='Compiling pgo build ...' 340 | ifneq ($(debug),yes) 341 | @$(STRIP) $(EXE)$(EXEEXT) 342 | endif 343 | 344 | build: net arch 345 | @$(MAKE) compile MESSAGE='Compiling standard build ...' 346 | 347 | arch: libclean 348 | @echo 349 | @echo "Compiler: $(COMP)" 350 | @echo "Arch: $(ARCH)" 351 | @echo "Bits: $(bits)" 352 | @echo "CPU features:" 353 | @echo "=============" 354 | @echo "avx512 : $(avx512)" 355 | @echo "bmi2 : $(bmi2)" 356 | @echo "avx2 : $(avx2)" 357 | @echo "bmi1 : $(bmi1)" 358 | @echo "lzcnt : $(lzcnt)" 359 | @echo "popcnt : $(popcnt)" 360 | @echo "ssse3 : $(ssse3)" 361 | @echo "sse2 : $(sse2)" 362 | @echo "neon : $(neon)" 363 | @echo "arm64 : $(arm64)" 364 | @echo "dotprod: $(dotprod)" 365 | @echo "zlib : $(zlib)" 366 | @echo "debug : $(debug)" 367 | 368 | net: 369 | ifeq ($(EVALFILE),$(filter $(EVALFILE),default)) 370 | ifeq ($(RUBINET),) 371 | echo "Network not found in header" 372 | else 373 | @if test -f $(RUBINET); then echo "$(RUBINET) already exists."; else echo "Downloading $(RUBINET)..."; $(WGETCMD) $(NETURL)$(RUBINET) > $(RUBINET); fi; 374 | $(eval shasum_command := $(shell if hash shasum 2>/dev/null; then echo "shasum -a 256 "; elif hash sha256sum 2>/dev/null; then echo "sha256sum "; fi)) 375 | @if [ "$(RUBINETHASH)" != `$(shasum_command) $(RUBINET) | cut -c1-10` ]; then echo "Failed download or $(RUBINET) corrupted, please delete!"; exit 1; else echo "$(RUBINET) has correct hash."; fi 376 | endif 377 | endif 378 | ifneq ($(EVALFILE),) 379 | @echo Embedding networkfile $(EMBEDFILE) 380 | @cp $(EMBEDFILE) $(NETBIN) 381 | @ld -r -b binary $(NETBIN) -o $(NETOBJ) 382 | endif 383 | 384 | $(ZLIBDIR)/libz.a: 385 | @echo Compiling zlib... 386 | @cd $(ZLIBDIR); $(MYCC) $(CFLAGS) $(ARCHFLAGS) -w -c *.c; $(AR) rcs libz.a *.o; cd .. 387 | 388 | compile: $(ZLIBDIR)/libz.a 389 | @echo $(MESSAGE) 390 | $(CXX) $(CXXFLAGS) $(EXTRACXXFLAGS) $(ARCHFLAGS) *.cpp $(LDFLAGS) $(PTHREADLIB) $(EXTRALDFLAGS) $(GITDEFINE) $(NETDEF) $(NETOBJ) -o $(EXE) 391 | 392 | objclean: 393 | @$(RM) *.o $(AVX512EXE) $(BMI2EXE) $(AVX2EXE) $(DEFAULTEXE) $(SSSE3EXE) $(SSE2POPCNTEXE) $(LEGACYEXE) $(PROFEXE) $(CPUTEST) $(NETBIN) || @echo $(RM) not available. 394 | 395 | libclean: 396 | @$(RM) zlib/*.o zlib/*.a || @echo $(RM) not available. 397 | 398 | profileclean: libclean 399 | @$(RM) -rf $(PROFDIR) || @echo $(RM) not available. 400 | @$(RM) *.clangprof-raw *.profdata || @echo $(RM) not available. 401 | 402 | clean: objclean profileclean 403 | 404 | profilebench: 405 | ifneq ($(COMP),ndk) 406 | @echo "Running bench to generate profiling data..." && ./$(PROFEXE) -bench 1>/dev/null && ([ $$? -eq 0 ] && echo " Profiling successful!") \ 407 | || (echo " Profiling failed!" && [ "$(SDE)" != "" ] && echo " Trying to use SDE..." && $(SDE) -icx -- ./$(PROFEXE) -bench 1>/dev/null && [ $$? -eq 0 ] && echo " Profiling successful!") \ 408 | || (echo " SDE not available or profiling with SDE failed! Profiling with native build..." && $(MAKE) profileclean && $(MAKE) compile ARCH=native EXTRACXXFLAGS=$(INSTRUMENTEDEXTRACXXFLAGS) EXTRALDFLAGS=$(INSTRUMENTEDEXTRALDFLAGS) EXE=$(PROFEXE) MESSAGE='Compiling instrumented build ...' && ./$(PROFEXE) -bench 1>/dev/null) 409 | else 410 | @([ "$(ANDROIDDEVICE)" != "" ] && adb disconnect 1>/dev/null && adb connect $(ANDROIDDEVICE) && adb root 1>/dev/null && adb shell "rm -rf /data/RubiChess;mkdir /data/RubiChess" \ 411 | && echo "Running bench on $(ANDROIDDEVICE) to generate profiling data..." \ 412 | && adb push $(PROFEXE) $(RUBINET) /data/RubiChess 1>/dev/null \ 413 | && adb shell "cd /data/RubiChess && ./$(PROFEXE) -bench 1>/dev/null" \ 414 | && adb pull /data/RubiChess/$(PROFEXE).clangprof-raw . 1>/dev/null \ 415 | && echo " Profiling successful!") \ 416 | || ([ "$(ANDROIDEMU)" != "" ] && adb disconnect 1>/dev/null && ($(ANDROIDEMU) -avd $(ARCH) -no-snapshot-load -no-qt 1>/dev/null 2>&1 &) \ 417 | && echo "Wait 60 seconds for emulator startup..." && sleep 60 && adb root 1>/dev/null && adb shell "rm -rf /data/RubiChess;mkdir /data/RubiChess" \ 418 | && echo "Running bench on emulator $(ARCH) to generate profiling data..." \ 419 | && adb push $(PROFEXE) $(RUBINET) /data/RubiChess 1>/dev/null \ 420 | && adb shell "cd /data/RubiChess && ./$(PROFEXE) -bench 1>/dev/null" \ 421 | && adb pull /data/RubiChess/$(PROFEXE).clangprof-raw . 1>/dev/null \ 422 | && adb emu kill 1>/dev/null 2>&1 \ 423 | && echo " Profiling successful!") \ 424 | || echo " Profiling failed!" 425 | @[ "$(ANDROIDEMU)" != "" ] && (adb emu kill 1>/dev/null 2>&1 || adb disconnect) 426 | endif 427 | 428 | instrumentedcompile: 429 | @$(MAKE) compile EXTRACXXFLAGS=$(INSTRUMENTEDEXTRACXXFLAGS) EXTRALDFLAGS=$(INSTRUMENTEDEXTRALDFLAGS) EXE=$(PROFEXE) MESSAGE='Compiling instrumented build ...' 430 | 431 | pgo: arch instrumentedcompile profilebench 432 | @$(PROFMERGE) 433 | @$(RM) ./$(PROFEXE) 434 | @$(MAKE) compile EXTRACXXFLAGS=$(PGOEXTRACXXFLAGS) EXTRALDFLAGS=$(PGOEXTRALDFLAGS) MESSAGE='Compiling optimized build ...' 435 | @$(MAKE) profileclean 436 | ifneq ($(debug),yes) 437 | @$(STRIP) $(EXE)$(EXEEXT) 438 | endif 439 | @echo Binary $(EXE) created successfully. 440 | 441 | profile-build: net 442 | @$(MAKE) -j1 pgo 443 | 444 | pgo-rename: pgo 445 | @mv $(EXE) $(EXE)-$(VERSION)_$(ARCH) 446 | @echo Successfully created $(EXE)-$(VERSION)_$(ARCH) 447 | 448 | release_x86: 449 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-avx512 450 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-bmi2 451 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-avx2 452 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-modern 453 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-ssse3 454 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-sse3-popcnt 455 | @$(MAKE) pgo-rename ARCH=x86-$(bits)-sse2 456 | @$(MAKE) pgo-rename ARCH=x86-$(bits) 457 | 458 | release_arm64: 459 | @$(MAKE) pgo-rename ARCH=armv8 460 | ifeq ($(dotprod),yes) 461 | @$(MAKE) pgo-rename ARCH=armv8-dotprod 462 | endif 463 | 464 | release_arm32: 465 | @$(MAKE) pgo-rename ARCH=armv7 466 | 467 | release_android: 468 | @$(MAKE) pgo-rename ARCH=armv8-dotprod COMP=$(COMP) 469 | @$(MAKE) pgo-rename ARCH=armv8 COMP=$(COMP) 470 | @$(MAKE) pgo-rename ARCH=armv7 COMP=$(COMP) 471 | @$(MAKE) pgo-rename ARCH=x86-64 COMP=$(COMP) 472 | @$(MAKE) pgo-rename ARCH=x86-32 COMP=$(COMP) 473 | 474 | release: net 475 | @$(MAKE) release_$(ARCHFAMILY) 476 | 477 | help: 478 | @echo "" 479 | @echo "Compile RubiChess with following command:" 480 | @echo "make target [ARCH=arch] [COMP=compiler] [EVALFILE=networkfile|default]" 481 | @echo "Supported targets:" 482 | @echo "build standard build (use if profile-build fails for some reason)" 483 | @echo "profile-build profiling optimized build, the default build target" 484 | @echo "release build all pgo optimized binaries CPU family" 485 | @echo "" 486 | @echo "ARCH should only be set when building a binary for a hardware different from the host" 487 | @echo "COMP can be gcc (default) or clang (usually faster but has some more dependencies)" 488 | @echo "Setting EVALFILE will build binaries with network included" 489 | @echo "" 490 | -------------------------------------------------------------------------------- /src/Makefile.clang: -------------------------------------------------------------------------------- 1 | # 2 | # Start MSVC Command prompt for x64 native tools and 3 | # nmake /f Makefile.clang [COMP=icx|clang] [SDE="c:\..\sde.exe"] [ARCH=...] 4 | # can be 5 | # release to build all binaries for release package in subfolder Release-clang using the Intel emulator where necessary 6 | # build to build fast binary 7 | # profile-build to build even faster binary 8 | # release-arm64 to cross-compile for ARCH arm64-neon (needs shell with cross-plattform settings) 9 | # ARCH can be one of x86-64-avx512, x86-64-bmi2, x86-64-avx2, x86-64-modern, x86-64-ssse3, x86-64-sse3-popcnt, x86-64 10 | # If ARCH is omitted the CPU features are auto-detected 11 | # 12 | # General settings 13 | # For best Windows x64 builds install 14 | # a. Intel ICX compiler from https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp in default folder C:\Program Files (x86)\Intel\oneAPI or 15 | # b. LLVM version 9 from https://releases.llvm.org/9.0.0/LLVM-9.0.0-win64.exe in folder C:\Program Files\LLVM9 16 | # For profiling a not supported platform (like avx512 in my case) set SDE to the Intel Software Development Emulator https://software.intel.com/content/www/us/en/develop/articles/intel-software-development-emulator.html 17 | # and define EMU when calling pgo-rename 18 | 19 | !IF !DEFINED(COMP) || "$(COMP)" == "clang" 20 | CompilerBaseDir=C:\Program Files\LLVM$(CLANGVER) 21 | CXX="$(CompilerBaseDir)\bin\clang-cl.exe" 22 | LD="$(CompilerBaseDir)\bin\lld-link.exe" 23 | PROFDATATOOLEXE="$(CompilerBaseDir)\bin\llvm-profdata.exe" 24 | !ELSEIF "$(COMP)" == "icx" 25 | CompilerBaseDir=C:\Program Files (x86)\Intel\oneAPI\compiler\latest 26 | !IF EXIST("$(CompilerBaseDir)\windows") # Path up to Intel oneAPI 2023.1 27 | CompilerBaseDir=$(CompilerBaseDir)\windows 28 | !ENDIF 29 | CXX="$(CompilerBaseDir)\bin\icx-cl.exe" 30 | !IF EXISTS("$(CompilerBaseDir)\bin-llvm") # Path up to Intel oneAPI 2023.1 31 | CompilerClangDir=$(CompilerBaseDir)\bin-llvm 32 | !ELSEIF EXISTS("$(CompilerBaseDir)\bin\compiler") # Path of Intel oneAPI 2024.0 33 | CompilerClangDir=$(CompilerBaseDir)\bin\compiler 34 | !ELSE 35 | !ERROR Folder with Linker tools not found. 36 | !ENDIF 37 | LD="$(CompilerClangDir)\lld-link.exe" 38 | PROFDATATOOLEXE="$(CompilerClangDir)\llvm-profdata.exe" 39 | !ELSE 40 | !ERROR Not supported compiler $(COMP) 41 | !ENDIF 42 | 43 | SOURCE=*.cpp 44 | OBJ=*.obj 45 | RELDIR=Release-clang 46 | ZLIBDIR=zlib 47 | CXXFLAGS=/EHsc /O2 /Oi /Ot /c -flto -fuse-ld=lld 48 | LDFLAGS=/OPT:REF /OPT:ICF advapi32.lib 49 | PROFEXE=RubiChess-WinProf 50 | NETURL=https://github.com/Matthies/NN/raw/main/ 51 | TMPNN=_tmp.nnue 52 | CPUTEST=cputest 53 | EXE=RubiChess 54 | GIT=git 55 | NATIVEFLAGS=_nativeflags.txt 56 | SDEDEFAULT="C:\bin\SDE\sde.exe" 57 | !IF !DEFINED(SDE) 58 | SDE=$(SDEDEFAULT) 59 | !ENDIF 60 | 61 | 62 | # Release-Dir 63 | !IF !EXIST($(RELDIR)) 64 | !MESSAGE $(RELDIR): 65 | !IF [mkdir $(RELDIR)] != 0 66 | !ERROR Cannot create folder $(RELDIR)! 67 | !ELSE 68 | !MESSAGE Successfully created folder $(RELDIR)! 69 | !ENDIF 70 | !ENDIF 71 | 72 | # compilercheck 73 | !IF !DEFINED(CCHECK) 74 | !MESSAGE Compiler and Tools: 75 | !Message Compiler base directory: $(CompilerBaseDir) 76 | !IF [$(CXX) --version > nul 2>&1] != 0 77 | !ERROR Compiler $(CXX) not found or not working. Exit! 78 | !ELSE 79 | !MESSAGE Found Compiler $(CXX). 80 | !ENDIF 81 | !IF [$(LD) --version > nul 2>&1] != 0 82 | !ERROR Linker $(LD) not found or not working. Exit! 83 | !ELSE 84 | !MESSAGE Found Linker $(LD). 85 | !ENDIF 86 | !IF !EXIST($(PROFDATATOOLEXE)) 87 | !ERROR Profiling tool $(PROFDATATOOLEXE) not found. Exit! 88 | !ELSE 89 | !MESSAGE Found Profiling tool $(PROFDATATOOLEXE). 90 | !ENDIF 91 | !IF EXIST($(SDE)) 92 | !MESSAGE Found Software Development Emulator (SDE) at $(SDE). 93 | !ELSE 94 | !MESSAGE Software Development Emulator (SDE) not found. 95 | !ENDIF 96 | !MESSAGE ========================================================================== 97 | 98 | # network 99 | !MESSAGE Network: 100 | !IF [@FOR /F "tokens=3" %A IN ('find "NNUEDEFAULT " RubiChess.h') DO @(if exist %A ( @echo Net %A already exists ) else ( curl -skL $(NETURL)%A > $(TMPNN) && move $(TMPNN) %A && echo Net %A was downloaded. )) && @if not exist $(RELDIR)\%A ( @copy %A $(RELDIR)\%A ) ] != 0 101 | !ERROR Cannot get default net from header file or download failed! 102 | !ENDIF 103 | !MESSAGE ========================================================================== 104 | CCHECK=done 105 | !ENDIF 106 | 107 | !IFNDEF ARCH 108 | ARCH=native 109 | !ENDIF 110 | 111 | # nativeflags 112 | !IF "$(ARCH)"=="native" && !EXIST($(NATIVEFLAGS)) && "$(VSCMD_ARG_HOST_ARCH)"=="$(VSCMD_ARG_TGT_ARCH)" 113 | !IF [@$(CXX) /GX -DCPUTEST $(CPUTEST).cpp -o $(CPUTEST) && @$(CPUTEST) > $(NATIVEFLAGS)] != 0 114 | !ERROR Cannot compile and/or run $(CPUTEST) to determine cpu flags on this machine! 115 | !ENDIF 116 | !ENDIF 117 | !IF "$(ARCH)"!="native" 118 | !IF EXIST($(NATIVEFLAGS)) && [@del $(NATIVEFLAGS) 2>nul] != 0 119 | !ERROR Cannot delete cpu flags file $(NATIVEFLAGS) 120 | !ENDIF 121 | !ENDIF 122 | 123 | cpuflags: lib-clean 124 | !IF "$(ARCH)" == "x86-64-avx512" 125 | CPUFLAGS=avx512 bmi2 avx2 bmi1 lzcnt popcnt ssse3 sse2 126 | !ELSEIF "$(ARCH)" == "x86-64-bmi2" 127 | CPUFLAGS=bmi2 avx2 bmi1 lzcnt popcnt ssse3 sse2 128 | !ELSEIF "$(ARCH)" == "x86-64-avx2" 129 | CPUFLAGS=avx2 bmi1 lzcnt popcnt ssse3 sse2 130 | !ELSEIF "$(ARCH)" == "x86-64-modern" 131 | CPUFLAGS=popcnt ssse3 sse2 132 | !ELSEIF "$(ARCH)" == "x86-64-ssse3" 133 | CPUFLAGS=ssse3 sse2 134 | !ELSEIF "$(ARCH)" == "x86-64-sse3-popcnt" 135 | CPUFLAGS=popcnt sse2 136 | !ELSEIF "$(ARCH)" == "x86-64-sse2" 137 | CPUFLAGS=sse2 138 | !ELSEIF "$(ARCH)" == "arm64-neon" 139 | CPUFLAGS=neon 140 | !ENDIF 141 | 142 | !IF [@echo $(CPUFLAGS) | find "avx512" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "avx512" > nul] == 0 143 | AVX512=yes 144 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_AVX512 -mavx512f -mavx512bw 145 | !ELSE 146 | AVX512=no 147 | !ENDIF 148 | !IF [@echo $(CPUFLAGS) | find "bmi2" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "bmi2" > nul] == 0 149 | BMI2=yes 150 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_BMI2 -mbmi2 151 | !ELSE 152 | BMI2=no 153 | !ENDIF 154 | !IF [@echo $(CPUFLAGS) | find "avx2" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "avx2" > nul] == 0 155 | AVX2=yes 156 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_AVX2 -mavx2 157 | !ELSE 158 | AVX2=no 159 | !ENDIF 160 | !IF [@echo $(CPUFLAGS) | find "bmi" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "bmi" > nul] == 0 161 | BMI1=yes 162 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_BMI1 -mbmi -mlzcnt 163 | !ELSE 164 | BMI1=no 165 | !ENDIF 166 | !IF [@echo $(CPUFLAGS) | find "popcnt" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "popcnt" > nul] == 0 167 | POPCNT=yes 168 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_POPCNT -mpopcnt -msse3 169 | !ELSE 170 | POPCNT=no 171 | !ENDIF 172 | !IF [@echo $(CPUFLAGS) | find "ssse3" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "ssse3" > nul] == 0 173 | SSSE3=yes 174 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_SSSE3 -mssse3 175 | !ELSE 176 | SSSE3=no 177 | !ENDIF 178 | !IF [@echo $(CPUFLAGS) | find "sse2" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "sse2" > nul] == 0 179 | SSE2=yes 180 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_SSE2 -msse2 181 | !ELSE 182 | SSE2=no 183 | !ENDIF 184 | !IF [@echo $(CPUFLAGS) | find "neon" > nul] == 0 || [type $(NATIVEFLAGS) 2>nul | find "neon" > nul] == 0 185 | NEON=yes 186 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_NEON -DUSE_ARM64 --target=arm64-pc-windows-msvc 187 | !ELSE 188 | NEON=no 189 | !ENDIF 190 | 191 | ARCHFLAGS=$(ARCHFLAGS) -DUSE_ZLIB 192 | CXXFLAGS=$(CXXFLAGS) /I$(ZLIBDIR) 193 | LDFLAGS=$(LDFLAGS) /libpath:$(ZLIBDIR) zlib.lib 194 | 195 | printarch: cpuflags 196 | @echo. 197 | @echo Arch: $(ARCH) 198 | @echo CPU features: 199 | @echo ============= 200 | @echo avx512: $(AVX512) 201 | @echo bmi2__: $(BMI2) 202 | @echo avx2__: $(AVX2) 203 | @echo bmi1__: $(BMI1) 204 | @echo popcnt: $(POPCNT) 205 | @echo ssse3_: $(SSSE3) 206 | @echo sse2__: $(SSE2) 207 | @echo neon__: $(NEON) 208 | 209 | buildandarch: printarch compile 210 | 211 | $(ZLIBDIR)\zlib.lib: 212 | @cd $(ZLIBDIR) 213 | @$(CXX) $(CXXFLAGS) $(ARCHFLAGS) -w /c *.c 214 | @$(LD) /lib /OUT:zlib.lib $(OBJ) 215 | @cd .. 216 | 217 | build: cpuflags 218 | @set CCHECK=$(CCHECK) 219 | @set ARCH=$(ARCH) 220 | @echo Building binary for $(ARCH)... 221 | @nmake -c -f Makefile.clang buildandarch 222 | @nmake -c -f Makefile.clang profile-clean 223 | 224 | compile: $(ZLIBDIR)\zlib.lib 225 | !IFNDEF GITVER 226 | @FOR /F "tokens=2" %A IN ('cmd /c "($(GIT) show --name-only --abbrev-commit --date=format:%Y%m%d || echo Date: %date%) | findstr /I /r /c:"^Date: "" ') DO @(set GITVER=%A&& nmake -f Makefile.clang $* /$(MAKEFLAGS) && exit /B) 227 | !ELSE 228 | !IFNDEF GITID 229 | @FOR /F "tokens=2" %A IN ('cmd /c "($(GIT) show --name-only --abbrev-commit || echo commit unknown) | findstr /r /c:"^commit"" ') DO @(set GITID=%A&& nmake -f Makefile.clang $* /$(MAKEFLAGS) && exit /B) 230 | !ELSE 231 | @$(CXX) $(CXXFLAGS) $(ARCHFLAGS) $(SOURCE) $(PROFILEFLAGS) -D GITVER=\"$(GITVER)\" -D GITID=\"$(GITID)\" 232 | !IFDEF USEPROFLIB 233 | @$(LD) $(LDFLAGS) /OUT:$(PROFEXE).exe $(OBJ) "$(USEPROFLIB)" 234 | !ELSE 235 | @$(LD) $(LDFLAGS) /OUT:$(RELDIR)\$(EXE).exe $(OBJ) 236 | !ENDIF 237 | !ENDIF 238 | !ENDIF 239 | 240 | pgo: 241 | !IFNDEF PROFLIB 242 | @(FOR /F "tokens=*" %A IN ('dir /b /s "$(CompilerBaseDir)\*clang_rt.profile-x86_64.lib*"') DO @(set PROFLIB="%A" && nmake -f Makefile.clang $* /$(MAKEFLAGS) && exit /B)) || @(echo 'Profiling library not found. Exit!' && exit 0) 243 | !ELSE 244 | @echo Compiling instrumented binary... 245 | @nmake -c -f Makefile.clang compile PROFILEFLAGS=-fprofile-instr-generate=$(PROFEXE).clangprof-raw USEPROFLIB=$(PROFLIB) 246 | @echo Bench to generate profiling data... 247 | @($(PROFEXE) -bench >nul || (if exist $(SDE) ( @echo Using Intels Software Development Emulator... && $(SDE) -icx -- $(PROFEXE) -bench >nul) else (@echo Intels Software Development Emulator needed but not found at $(SDE). Performance will be poor.))) 248 | @$(PROFDATATOOLEXE) merge -output=$(PROFEXE).clangprof $(PROFEXE).clangprof-raw 249 | @echo. 250 | @echo Compiling optimized binary... 251 | @nmake -c -f Makefile.clang compile PROFILEFLAGS=-fprofile-instr-use=$(PROFEXE).clangprof 252 | !ENDIF 253 | 254 | profile-build: cpuflags printarch 255 | @set CCHECK=$(CCHECK) 256 | @set ARCH=$(ARCH) 257 | @nmake -c -f Makefile.clang pgo 258 | @nmake -c -f Makefile.clang profile-clean 259 | 260 | pgo-rename: printarch pgo 261 | @move $(RELDIR)\$(EXE).exe $(RELDIR)\$(EXE)-$(VERSION)_$(ARCH).exe 1>nul 262 | @echo Successfully built $(EXE)-$(VERSION)_$(ARCH) 263 | 264 | build-rename: build 265 | @move $(RELDIR)\$(EXE).exe $(RELDIR)\$(EXE)-$(VERSION)_$(ARCH).exe 1>nul 266 | @echo Successfully built $(EXE)-$(VERSION)_$(ARCH) 267 | 268 | releaseversion: 269 | @echo Version: $(VERSION) 270 | !IF "$(VSCMD_ARG_TGT_ARCH)" == "x64" 271 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-avx512 272 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-bmi2 273 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-avx2 274 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-modern 275 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-ssse3 276 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-sse3-popcnt 277 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64-sse2 278 | @nmake -c -f Makefile.clang pgo-rename ARCH=x86-64 279 | !ENDIF 280 | !IF "$(VSCMD_ARG_TGT_ARCH)" == "arm64" 281 | @nmake -c -f Makefile.clang build-rename ARCH=arm64-neon 282 | !ENDIF 283 | 284 | release: 285 | @set CCHECK=$(CCHECK) 286 | @set ARCH=special 287 | @nmake -c -f Makefile.clang profile-clean 288 | !IFNDEF VERSIONLEGACY 289 | @FOR /F "tokens=3" %A IN ('find "define VERNUMLEGACY " RubiChess.h') DO @(set VERSIONLEGACY=%A&& nmake -f Makefile.clang $* /$(MAKEFLAGS) && exit /B) 290 | !ELSE 291 | !IFNDEF VERSION 292 | @FOR /F "tokens=2" %A IN ('cmd /c "($(GIT) show --name-only --abbrev-commit --date=format:%Y%m%d || echo Date: %VERSIONLEGACY%) | findstr /I /r /c:"^Date: "" ') DO @(set VERSION=%A&& nmake -f Makefile.clang $* /$(MAKEFLAGS) && exit /B) 293 | !ELSE 294 | @nmake -c -f Makefile.clang releaseversion 295 | !ENDIF 296 | !ENDIF 297 | @nmake -c -f Makefile.clang profile-clean 298 | 299 | release-arm64: 300 | @nmake -c -f Makefile.clang build-rename ARCH=arm64-neon 301 | 302 | lib-clean: 303 | @del $(ZLIBDIR)\*.obj 2>nul 304 | @del $(ZLIBDIR)\zlib.lib 2>nul 305 | 306 | profile-clean: lib-clean 307 | @del $(PROFEXE)* 2>nul 308 | @del *.obj 2>nul 309 | @del $(NATIVEFLAGS) 2>nul 310 | 311 | clean: profile-clean lib-clean 312 | @del $(RELDIR)\$(EXE).exe 2>nul 313 | @del $(CPUTEST).exe 2>nul 314 | @set RUBINET= 315 | 316 | -------------------------------------------------------------------------------- /src/RubiChess.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 86 | 87 | -------------------------------------------------------------------------------- /src/RubiChess.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Quelldateien 20 | 21 | 22 | Quelldateien 23 | 24 | 25 | Quelldateien 26 | 27 | 28 | Quelldateien 29 | 30 | 31 | Quelldateien 32 | 33 | 34 | Quelldateien 35 | 36 | 37 | Quelldateien 38 | 39 | 40 | Quelldateien 41 | 42 | 43 | Quelldateien 44 | 45 | 46 | Quelldateien 47 | 48 | 49 | Quelldateien 50 | 51 | 52 | Quelldateien 53 | 54 | 55 | Quelldateien 56 | 57 | 58 | Quelldateien 59 | 60 | 61 | 62 | 63 | Headerdateien 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/cputest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | RubiChess is a UCI chess playing engine by Andreas Matthies. 3 | 4 | RubiChess is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | RubiChess is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include "RubiChess.h" 20 | 21 | using namespace rubichess; 22 | 23 | 24 | #if defined(_M_X64) || defined(__amd64) 25 | 26 | #if defined _MSC_VER && !defined(__clang_major__) 27 | #include 28 | #define CPUID(x,i) __cpuid(x, i) 29 | #endif 30 | 31 | #if defined(__MINGW64__) || defined(__gnu_linux__) || defined(__clang_major__) || defined(__GNUC__) 32 | #include 33 | #define CPUID(x,i) cpuid(x, i) 34 | static void cpuid(int32_t out[4], int32_t x) { 35 | __cpuid_count(x, 0, out[0], out[1], out[2], out[3]); 36 | } 37 | #endif 38 | 39 | 40 | void compilerinfo::GetSystemInfo() 41 | { 42 | machineSupports = 0ULL; 43 | 44 | // shameless copy from MSDN example explaining __cpuid 45 | char CPUBrandString[0x40]; 46 | char CPUString[0x10]; 47 | int CPUInfo[4] = { -1 }; 48 | 49 | unsigned nIds, nExIds, i; 50 | 51 | CPUID(CPUInfo, 0); 52 | 53 | memset(CPUString, 0, sizeof(CPUString)); 54 | memcpy(CPUString, &CPUInfo[1], 4); 55 | memcpy(CPUString + 4, &CPUInfo[3], 4); 56 | memcpy(CPUString + 8, &CPUInfo[2], 4); 57 | 58 | string vendor = string(CPUString); 59 | 60 | if (vendor == "GenuineIntel") 61 | cpuVendor = CPUVENDORINTEL; 62 | else if (vendor == "AuthenticAMD") 63 | cpuVendor = CPUVENDORAMD; 64 | else 65 | cpuVendor = CPUVENDORUNKNOWN; 66 | 67 | nIds = CPUInfo[0]; 68 | 69 | // Get the information associated with each valid Id 70 | // https://www.sandpile.org/x86/cpuid.htm 71 | // https://en.wikichip.org/wiki/amd/cpuid 72 | // https://en.wikichip.org/wiki/intel/cpuid 73 | for (i = 0; i <= nIds; ++i) 74 | { 75 | CPUID(CPUInfo, i); 76 | // Interpret CPU feature information. 77 | if (i == 1) 78 | { 79 | cpuFamily = ((CPUInfo[0] & (0xf << 8)) >> 8) + ((CPUInfo[0] & (0xff << 20)) >> 20); 80 | cpuModel = ((CPUInfo[0] & (0xf << 16)) >> 12) + ((CPUInfo[0] & (0xf << 4)) >> 4); 81 | if (CPUInfo[3] & (1 << 26)) machineSupports |= CPUSSE2; 82 | if (CPUInfo[2] & (1 << 23)) machineSupports |= CPUPOPCNT; 83 | if (CPUInfo[2] & (1 << 9)) machineSupports |= CPUSSSE3; 84 | } 85 | 86 | if (i == 7) 87 | { 88 | if (CPUInfo[1] & (1 << 3)) machineSupports |= CPUBMI1; 89 | if (CPUInfo[1] & (1 << 8)) machineSupports |= CPUBMI2; 90 | if (CPUInfo[1] & (1 << 5)) machineSupports |= CPUAVX2; 91 | if (CPUInfo[1] & ((1 << 16) | (1 << 30))) machineSupports |= CPUAVX512; // AVX512F + AVX512BW needed 92 | } 93 | } 94 | 95 | // Calling __cpuid with 0x80000000 as the InfoType argument 96 | // gets the number of valid extended IDs. 97 | CPUID(CPUInfo, 0x80000000); 98 | nExIds = CPUInfo[0]; 99 | memset(CPUBrandString, 0, sizeof(CPUBrandString)); 100 | 101 | // Get the information associated with each extended ID. 102 | for (i = 0x80000000; i <= nExIds; ++i) 103 | { 104 | CPUID(CPUInfo, i); 105 | // Extended CPU features 106 | if (i == 0x80000001) 107 | if (CPUInfo[2] & (1 << 5)) machineSupports |= CPULZCNT; 108 | // Interpret CPU brand string and cache information. 109 | if (i == 0x80000002) 110 | memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo)); 111 | else if (i == 0x80000003) 112 | memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo)); 113 | else if (i == 0x80000004) 114 | memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); 115 | } 116 | 117 | system = CPUBrandString; 118 | system += " Family: " + to_string(cpuFamily) + " Model: " + to_string(cpuModel); 119 | 120 | #ifndef CPUTEST 121 | U64 notSupported = binarySupports & ~machineSupports; 122 | 123 | if (notSupported) 124 | { 125 | cout << "info string Error! Binary is not compatible with this machine. Missing cpu features: " + PrintCpuFeatures(notSupported) + ". Please use correct binary.\n"; 126 | exit(-1); 127 | } 128 | #endif 129 | 130 | if (cpuVendor == CPUVENDORAMD && cpuFamily < 25 && (machineSupports & CPUBMI2)) 131 | { 132 | // No real BMI2 support on AMD cpu before Zen3 133 | machineSupports ^= CPUBMI2; 134 | if (binarySupports & CPUBMI2) 135 | cout << "info string Warning! You are running the BMI2 binary on an AMD cpu which is known for bad performance. Please use avx2 binary for best performance.\n"; 136 | } 137 | 138 | #ifndef CPUTEST 139 | U64 supportedButunused = machineSupports & ~binarySupports; 140 | if (supportedButunused) 141 | cout << "info string Warning! Binary not optimal for this machine. Unused cpu features: " + PrintCpuFeatures(supportedButunused) + ". Please use correct binary for best performance.\n"; 142 | #endif 143 | } 144 | 145 | #else 146 | void compilerinfo::GetSystemInfo() 147 | { 148 | #if defined(__ARM_ARCH) || defined(_M_ARM64) || defined(_M_ARM) 149 | #if __ARM_ARCH == 6 150 | system = "ArmV6 platform not supporting any SIMD"; 151 | machineSupports = 0; 152 | #elif __ARM_ARCH == 7 || defined(_M_ARM) 153 | system = "ArmV7 platform supporting NEON"; 154 | machineSupports = CPUNEON; 155 | #elif defined(__aarch64__) || defined(_M_ARM64) 156 | #ifdef __ARM_FEATURE_DOTPROD 157 | system = "ArmV8.2+DotProd (AArch64) platform supporting NEON"; 158 | machineSupports = CPUNEON | CPUARM64 | CPUDOTPROD; 159 | #else 160 | system = "ArmV8 (AArch64) platform supporting NEON"; 161 | machineSupports = CPUNEON | CPUARM64; 162 | #endif 163 | #else 164 | system = "ArmV8 32bit platform supporting NEON"; // does this exist?? 165 | machineSupports = CPUNEON; 166 | #endif 167 | #else 168 | system = "Some non-x86-64-non-arm platform."; 169 | machineSupports = 0ULL; 170 | #endif 171 | } 172 | 173 | #endif 174 | 175 | string compilerinfo::PrintCpuFeatures(U64 f, bool onlyHighest) 176 | { 177 | string s = ""; 178 | for (int i = 0; f; i++, f = f >> 1) 179 | if (f & 1) s = (onlyHighest ? "" : ((s != "") ? s + " " : "")) + strCpuFeatures[i]; 180 | 181 | return s; 182 | } 183 | 184 | 185 | #ifdef CPUTEST 186 | 187 | int main() 188 | { 189 | compilerinfo ci; 190 | ci.GetSystemInfo(); 191 | cout << ci.PrintCpuFeatures(ci.machineSupports) << "\n"; 192 | 193 | } 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /src/release.cmd: -------------------------------------------------------------------------------- 1 | :: 2 | :: Batch to compile all Windows release binaries 3 | :: Needs MSVC build tools v141 for x64/x86 and arm64 4 | :: 5 | 6 | @echo off 7 | 8 | set SDE= 9 | :: Some defaults for the SDE on my computer 10 | if exist C:\bin\SDE\sde.exe ( 11 | set SDE=C:\bin\SDE\sde.exe 12 | echo Found SDE at C:\bin\SDE\sde.exe 13 | ) 14 | 15 | if not exist "%ProgramFiles%\LLVM%clangver%" ( 16 | :: Clang not installed in generic folder; search for latest version 17 | for /L %%v IN (30,-1,9) do ( 18 | if exist "%ProgramFiles%\LLVM%%v" ( 19 | set clangver=%%v 20 | goto foundllvm 21 | ) 22 | ) 23 | ) 24 | 25 | :foundllvm 26 | if exist "%ProgramFiles%\LLVM%clangver%" ( 27 | echo Found LLVM at "%ProgramFiles%\LLVM%clangver%" 28 | ) else ( 29 | echo Cannot find LLVM at %ProgramFiles%\LLVM*. Exit! 30 | goto end 31 | ) 32 | 33 | 34 | 35 | set vcvarscmdicx="%ProgramFiles(x86)%\Intel\oneAPI\setvars.bat" 36 | set vcvarscmd22="%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" 37 | set vcvarscmd19="%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" 38 | 39 | set vcvarscmd= 40 | set vsver= 41 | if exist %vcvarscmd22% ( 42 | set vcvarscmd=%vcvarscmd22% 43 | set vsver=vs2022 44 | echo Found Visual Studio 2022 Tools 45 | goto buildx64 46 | ) 47 | if exist %vcvarscmd19% ( 48 | set vcvarscmd=%vcvarscmd19% 49 | set vsver=vs2019 50 | echo Found Visual Studio 2019 Tools 51 | goto buildx64 52 | ) 53 | echo No supported MSVC build tools found. Exit! 54 | goto end 55 | 56 | :buildx64 57 | :: 58 | :: x64-64 buils 59 | :: 60 | if exist %vcvarscmdicx% ( 61 | echo Found Intel ICX compiler %vcvarscmdicx% 62 | call %vcvarscmdicx% intel64 %vsver% 63 | nmake -c -f Makefile.clang release COMP=icx 64 | ) else ( 65 | echo Found MSVC Build tools %vcvarscmd% 66 | call %vcvarscmd% x64 67 | nmake -c -f Makefile.clang release COMP=clang 68 | ) 69 | 70 | :buildarm 71 | :: 72 | :: ARM64 build 73 | :: 74 | call %vcvarscmd% x64_arm64 75 | nmake -c -f Makefile.clang release COMP=clang 76 | 77 | :end 78 | pause 79 | 80 | -------------------------------------------------------------------------------- /src/tbcore.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011-2015 Ronald de Man 3 | */ 4 | 5 | #ifndef TBCORE_H 6 | #define TBCORE_H 7 | 8 | #ifdef _WIN32 9 | #define __attribute__(A) /* do nothing */ 10 | #define DECOMP64 11 | #define __builtin_bswap32(x) _byteswap_ulong(x) 12 | #define __builtin_bswap64(x) _byteswap_uint64(x) 13 | #endif 14 | 15 | 16 | #ifndef _WIN32 17 | #include 18 | #define SEP_CHAR ':' 19 | #define FD int 20 | #define FD_ERR -1 21 | #else 22 | #include 23 | #define SEP_CHAR ';' 24 | #define FD HANDLE 25 | #define FD_ERR INVALID_HANDLE_VALUE 26 | #endif 27 | 28 | #ifndef _WIN32 29 | #define LOCK_T pthread_mutex_t 30 | #define LOCK_INIT(x) pthread_mutex_init(&(x), NULL) 31 | #define LOCK_DESTROY(x) pthread_mutex_destroy(&(x)) 32 | #define LOCK(x) pthread_mutex_lock(&(x)) 33 | #define UNLOCK(x) pthread_mutex_unlock(&(x)) 34 | #else 35 | #define LOCK_T HANDLE 36 | #define LOCK_INIT(x) do { x = CreateMutex(NULL, FALSE, NULL); } while (0) 37 | #define LOCK_DESTROY(x) CloseHandle(x) 38 | #define LOCK(x) WaitForSingleObject(x, INFINITE) 39 | #define UNLOCK(x) ReleaseMutex(x) 40 | #endif 41 | 42 | #define WDLSUFFIX ".rtbw" 43 | #define DTZSUFFIX ".rtbz" 44 | #define WDLDIR "RTBWDIR" 45 | #define DTZDIR "RTBZDIR" 46 | #define TBPIECES 7 47 | 48 | #define WDL_MAGIC 0x5d23e871 49 | #define DTZ_MAGIC 0xa50c66d7 50 | 51 | #define TBHASHBITS 12 52 | 53 | namespace rubichess { 54 | 55 | 56 | struct TBHashEntry; 57 | 58 | #ifdef DECOMP64 59 | typedef uint64_t base_t; 60 | #else 61 | typedef uint32_t base_t; 62 | #endif 63 | 64 | struct PairsData { 65 | char *indextable; 66 | uint16_t *sizetable; 67 | uint8_t *data; 68 | uint16_t *offset; 69 | uint8_t *symlen; 70 | uint8_t *sympat; 71 | int blocksize; 72 | int idxbits; 73 | int min_len; 74 | uint8_t constValue[2]; 75 | base_t base[1]; // C++ complains about base[]... 76 | }; 77 | 78 | struct TBEntry { 79 | char *data; 80 | uint64_t key; 81 | uint64_t mapping; 82 | uint8_t ready; 83 | uint8_t num; 84 | uint8_t symmetric; 85 | uint8_t has_pawns; 86 | } __attribute__((__may_alias__)); 87 | 88 | struct TBEntry_piece { 89 | char *data; 90 | uint64_t key; 91 | uint64_t mapping; 92 | uint8_t ready; 93 | uint8_t num; 94 | uint8_t symmetric; 95 | uint8_t has_pawns; 96 | uint8_t enc_type; 97 | struct PairsData *precomp[2]; 98 | uint64_t factor[2][TBPIECES]; 99 | uint8_t pieces[2][TBPIECES]; 100 | uint8_t norm[2][TBPIECES]; 101 | }; 102 | 103 | struct TBEntry_pawn { 104 | char *data; 105 | uint64_t key; 106 | uint64_t mapping; 107 | uint8_t ready; 108 | uint8_t num; 109 | uint8_t symmetric; 110 | uint8_t has_pawns; 111 | uint8_t pawns[2]; 112 | struct { 113 | struct PairsData *precomp[2]; 114 | uint64_t factor[2][TBPIECES]; 115 | uint8_t pieces[2][TBPIECES]; 116 | uint8_t norm[2][TBPIECES]; 117 | } file[4]; 118 | }; 119 | 120 | struct DTZEntry_piece { 121 | char *data; 122 | uint64_t key; 123 | uint64_t mapping; 124 | uint8_t ready; 125 | uint8_t num; 126 | uint8_t symmetric; 127 | uint8_t has_pawns; 128 | uint8_t enc_type; 129 | struct PairsData *precomp; 130 | uint64_t factor[TBPIECES]; 131 | uint8_t pieces[TBPIECES]; 132 | uint8_t norm[TBPIECES]; 133 | uint8_t flags; // accurate, mapped, side 134 | uint16_t map_idx[4]; 135 | uint8_t *map; 136 | }; 137 | 138 | struct DTZEntry_pawn { 139 | char *data; 140 | uint64_t key; 141 | uint64_t mapping; 142 | uint8_t ready; 143 | uint8_t num; 144 | uint8_t symmetric; 145 | uint8_t has_pawns; 146 | uint8_t pawns[2]; 147 | struct { 148 | struct PairsData *precomp; 149 | uint64_t factor[TBPIECES]; 150 | uint8_t pieces[TBPIECES]; 151 | uint8_t norm[TBPIECES]; 152 | } file[4]; 153 | uint8_t flags[4]; 154 | uint16_t map_idx[4][4]; 155 | uint8_t *map; 156 | }; 157 | 158 | struct TBHashEntry { 159 | uint64_t key; 160 | struct TBEntry *ptr; 161 | }; 162 | 163 | struct DTZTableEntry { 164 | uint64_t key1; 165 | uint64_t key2; 166 | struct TBEntry *entry; 167 | }; 168 | 169 | 170 | } // namespace rubichess 171 | 172 | #endif 173 | 174 | -------------------------------------------------------------------------------- /src/transposition.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | RubiChess is a UCI chess playing engine by Andreas Matthies. 3 | 4 | RubiChess is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | RubiChess is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | 18 | 19 | #include "RubiChess.h" 20 | 21 | #if defined(__linux__) && !defined(__ANDROID__) 22 | #include // madvise 23 | #endif 24 | 25 | using namespace rubichess; 26 | 27 | namespace rubichess { 28 | 29 | zobrist::zobrist() 30 | { 31 | raninit(&rnd, 0); 32 | int i; 33 | int j = 0; 34 | for (i = 0; i < 128 * 16; i++) 35 | { 36 | unsigned long long r = getRnd(); 37 | // make the boardtable and so the hash compatible with older 0x88-board representation 38 | if (!((i >> 4) & 0x88)) 39 | boardtable[j++] = r; 40 | } 41 | // make hashing simpler but stay compatible to board88 42 | unsigned long long castle[4]; 43 | unsigned long long ep[8]; 44 | for (i = 0; i < 4; i++) 45 | castle[i] = getRnd(); 46 | for (i = 0; i < 8; i++) 47 | ep[i] = getRnd(); 48 | for (i = 0; i < 32; i++) 49 | { 50 | cstl[i] = 0ULL; 51 | for (j = 0; j < 4; j++) 52 | { 53 | if (i & (1 << (j+1))) 54 | cstl[i] ^= castle[j]; 55 | } 56 | } 57 | for (i = 0; i < 64; i++) 58 | { 59 | ept[i] = 0ULL; 60 | if (RANK(i) == 2 || RANK(i) == 5) 61 | ept[i] = ep[FILE(i)]; 62 | } 63 | 64 | s2m = getRnd(); 65 | } 66 | 67 | 68 | unsigned long long zobrist::getRnd() 69 | { 70 | return ranval(&rnd); 71 | } 72 | 73 | 74 | void zobrist::getAllHashes(chessposition* pos) 75 | { 76 | U64 hash = 0, pawnhash = 0, nonpawnhash[2] = {0}; 77 | 78 | int i; 79 | int state = pos->state; 80 | for (i = WPAWN; i <= BKING; i++) 81 | { 82 | U64 pmask = pos->piece00[i]; 83 | unsigned int index; 84 | while (pmask) 85 | { 86 | index = pullLsb(&pmask); 87 | hash ^= boardtable[(index << 4) | i]; 88 | if (i <= BPAWN) 89 | pawnhash ^= boardtable[(index << 4) | i]; 90 | else 91 | nonpawnhash[i & S2MMASK] ^= boardtable[(index << 4) | i]; 92 | } 93 | } 94 | 95 | if (state & S2MMASK) 96 | hash ^= s2m; 97 | 98 | hash ^= cstl[state & CASTLEMASK]; 99 | hash ^= ept[pos->ept]; 100 | 101 | pos->hash = hash; 102 | pos->pawnhash = pawnhash; 103 | pos->nonpawnhash[WHITE] = nonpawnhash[WHITE]; 104 | pos->nonpawnhash[BLACK] = nonpawnhash[BLACK]; 105 | } 106 | 107 | 108 | U64 zobrist::getPawnKingHash(chessposition* pos) 109 | { 110 | return pos->pawnhash ^ boardtable[(pos->kingpos[0] << 4) | WKING] ^ boardtable[(pos->kingpos[1] << 4) | BKING]; 111 | } 112 | 113 | 114 | U64 zobrist::getMaterialHash(chessposition* pos) 115 | { 116 | U64 hash = 0; 117 | for (PieceCode pc = WPAWN; pc <= BKING; pc++) 118 | { 119 | int count = POPCOUNT(pos->piece00[pc]); 120 | for (int i = 0; i < count; i++) 121 | hash ^= zb.boardtable[(i << 4) | pc]; 122 | } 123 | return hash; 124 | } 125 | 126 | 127 | 128 | transposition::~transposition() 129 | { 130 | if (size > 0) 131 | my_large_free(table); 132 | } 133 | 134 | int transposition::setSize(int sizeMb) 135 | { 136 | int restMb = 0; 137 | int msb = 0; 138 | if (size > 0) 139 | my_large_free(table); 140 | size_t clustersize = sizeof(transpositioncluster); 141 | #ifdef SDEBUG 142 | // Don't use the debugging part of the cluster for calculation of size to get consistent search with non SDEBUG 143 | clustersize = offsetof(transpositioncluster, debugHash); 144 | #endif 145 | U64 maxsize = ((U64)sizeMb << 20) / clustersize; 146 | if (!maxsize) 147 | { 148 | size = 0ULL; 149 | return 0; 150 | } 151 | GETMSB(msb, maxsize); 152 | size = (1ULL << msb); 153 | restMb = (int)(((maxsize ^ size) >> 20) * clustersize); // return rest for pawnhash 154 | size_t allocsize = (size_t)(size * sizeof(transpositioncluster)); 155 | 156 | #if defined(__linux__) && !defined(__ANDROID__) // Many thanks to Sami Kiminki for advise on the huge page theory and for this patch 157 | // Round up hashSize to the next 2M for alignment 158 | constexpr size_t HashAlignBytes = 2ull << 20; 159 | allocsize = ((allocsize + HashAlignBytes - 1u) / HashAlignBytes) * HashAlignBytes; 160 | 161 | table = (transpositioncluster*)aligned_alloc(HashAlignBytes, allocsize); 162 | 163 | // Linux-specific call to request huge pages, in case the aligned_alloc() 164 | // call above doesn't already trigger them (depends on transparent huge page 165 | // settings) 166 | madvise(table, allocsize, MADV_HUGEPAGE); 167 | #else 168 | table = (transpositioncluster*)my_large_malloc(allocsize); 169 | #endif 170 | if (!table) { 171 | // alloc failed, back to old size 172 | size = 0; 173 | sizeMb = (int)(((sizemask + 1) * clustersize) >> 20); 174 | cerr << "Keeping " << sizeMb << "MByte Hash.\n"; 175 | return setSize(sizeMb); 176 | } 177 | 178 | sizemask = size - 1; 179 | clean(); 180 | return restMb; 181 | } 182 | 183 | void transposition::clean() 184 | { 185 | size_t totalsize = size * sizeof(transpositioncluster); 186 | size_t sizePerThread = totalsize / en.Threads; 187 | thread tthread[MAXTHREADS]; 188 | for (int i = 0; i < en.Threads; i++) 189 | { 190 | void *start = (char*)table + i * sizePerThread; 191 | tthread[i] = thread(memset, start, 0, sizePerThread); 192 | } 193 | memset((char*)table + en.Threads * sizePerThread, 0, totalsize - en.Threads * sizePerThread); 194 | for (int i = 0; i < en.Threads; i++) 195 | { 196 | if (tthread[i].joinable()) 197 | tthread[i].join(); 198 | } 199 | numOfSearchShiftTwo = 0; 200 | } 201 | 202 | 203 | unsigned int transposition::getUsedinPermill() 204 | { 205 | unsigned int used = 0; 206 | 207 | // Take 1000 samples 208 | for (int i = 0; i < 1000 / TTBUCKETNUM; i++) 209 | for (int j = 0; j < TTBUCKETNUM; j++) 210 | if ((table[i].entry[j].boundAndAge & AGEMASK) == numOfSearchShiftTwo) 211 | used++; 212 | 213 | return used; 214 | } 215 | 216 | 217 | void transposition::addHash(ttentry* entry, U64 hash, int val, int16_t staticeval, int bound, int depth, uint16_t movecode) 218 | { 219 | #ifdef EVALTUNE 220 | // don't use transposition table when tuning evaluation 221 | return; 222 | #endif 223 | const hashupper_t hashupper = GETHASHUPPER(hash); 224 | const uint8_t ttdepth = depth - TTDEPTH_OFFSET; 225 | 226 | // Don't overwrite an entry from the same position, unless we have 227 | // an exact bound or depth that is nearly as good as the old one 228 | if (bound == HASHEXACT 229 | || entry->hashupper != hashupper 230 | || ttdepth + 3 >= entry->depth) 231 | { 232 | entry->hashupper = hashupper; 233 | entry->depth = (uint8_t)ttdepth; 234 | entry->boundAndAge = (uint8_t)(bound | numOfSearchShiftTwo); 235 | entry->movecode = movecode; 236 | entry->staticeval = staticeval; 237 | entry->value = (int16_t)val; 238 | } 239 | } 240 | 241 | 242 | void transposition::printHashentry(U64 hash) 243 | { 244 | unsigned long long index = hash & sizemask; 245 | transpositioncluster *data = &table[index]; 246 | printf("Hashentry for %llx\n", hash); 247 | for (int i = 0; i < TTBUCKETNUM; i++) 248 | { 249 | if ((data->entry[i].hashupper) == GETHASHUPPER(hash)) 250 | { 251 | printf("Match in upper part: %x / %x\n", (unsigned int)data->entry[i].hashupper, (unsigned int)(hash >> 32)); 252 | printf("Move code: %x\n", (unsigned int)data->entry[i].movecode); 253 | printf("Depth: %d\n", data->entry[i].depth); 254 | printf("Value: %d\n", data->entry[i].value); 255 | printf("Eval: %d\n", data->entry[i].staticeval); 256 | printf("BoundAge: %d\n", data->entry[i].boundAndAge); 257 | return; 258 | } 259 | } 260 | printf("No match found\n"); 261 | } 262 | 263 | 264 | ttentry* transposition::probeHash(U64 hash, bool* bFound) 265 | { 266 | transpositioncluster* cluster = &table[hash & sizemask]; 267 | ttentry* e; 268 | const hashupper_t hashupper = GETHASHUPPER(hash); 269 | 270 | for (int i = 0; i < TTBUCKETNUM; i++) 271 | { 272 | // First try to find a free or matching entry 273 | e = &(cluster->entry[i]); 274 | if (e->hashupper == hashupper || !e->depth) 275 | { 276 | *bFound = (bool)e->depth; 277 | e->boundAndAge = (e->boundAndAge & BOUNDMASK) | numOfSearchShiftTwo; 278 | return e; 279 | } 280 | } 281 | 282 | *bFound = false; 283 | ttentry* leastValuableEntry = &(cluster->entry[0]); 284 | 285 | for (int i = 1; i < TTBUCKETNUM; i++) 286 | { 287 | e = &(cluster->entry[i]); 288 | if (e->depth - ((AGECYCLE + numOfSearchShiftTwo - e->boundAndAge) & AGEMASK) * 2 289 | < leastValuableEntry->depth - ((AGECYCLE + numOfSearchShiftTwo - leastValuableEntry->boundAndAge) & AGEMASK) * 2) 290 | { 291 | // found a new less valuable entry 292 | leastValuableEntry = e; 293 | } 294 | } 295 | return leastValuableEntry; 296 | } 297 | 298 | 299 | uint16_t transposition::getMoveCode(U64 hash) 300 | { 301 | unsigned long long index = hash & sizemask; 302 | transpositioncluster *data = &table[index]; 303 | for (int i = 0; i < TTBUCKETNUM; i++) 304 | { 305 | if ((data->entry[i].hashupper) == GETHASHUPPER(hash)) 306 | return data->entry[i].movecode; 307 | } 308 | return 0; 309 | } 310 | 311 | 312 | void Pawnhash::setSize(int sizeMb) 313 | { 314 | int msb = 0; 315 | sizeMb = max(sizeMb, 16); 316 | U64 size = ((U64)sizeMb << 20) / sizeof(S_PAWNHASHENTRY); 317 | if (!size) return; 318 | GETMSB(msb, size); 319 | size = (1ULL << msb); 320 | 321 | sizemask = size - 1; 322 | size_t tablesize = (size_t)size * sizeof(S_PAWNHASHENTRY); 323 | table = (S_PAWNHASHENTRY*)allocalign64(tablesize); 324 | memset(table, 0, tablesize); 325 | } 326 | 327 | 328 | void Pawnhash::remove() 329 | { 330 | freealigned64(table); 331 | } 332 | 333 | 334 | bool Pawnhash::probeHash(U64 hash, pawnhashentry **entry) 335 | { 336 | unsigned long long index = hash & sizemask; 337 | *entry = &table[index]; 338 | if (((*entry)->hashupper) == (hash >> 32)) 339 | { 340 | #ifndef EVALTUNE 341 | // don't use pawn hash when tuning evaluation 342 | return true; 343 | #endif 344 | } 345 | (*entry)->hashupper = (uint32_t)(hash >> 32); 346 | (*entry)->value = 0; 347 | (*entry)->semiopen[0] = (*entry)->semiopen[1] = 0xff; 348 | (*entry)->passedpawnbb[0] = (*entry)->passedpawnbb[1] = 0ULL; 349 | (*entry)->attacked[0] = (*entry)->attacked[1] = 0ULL; 350 | (*entry)->attackedBy2[0] = (*entry)->attackedBy2[1] = 0ULL; 351 | 352 | return false; 353 | } 354 | 355 | 356 | transposition tp; 357 | 358 | } // namespace rubichess 359 | -------------------------------------------------------------------------------- /src/zlib/README: -------------------------------------------------------------------------------- 1 | ZLIB DATA COMPRESSION LIBRARY 2 | 3 | zlib 1.3.1 is a general purpose data compression library. All the code is 4 | thread safe. The data format used by the zlib library is described by RFCs 5 | (Request for Comments) 1950 to 1952 in the files 6 | http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and 7 | rfc1952 (gzip format). 8 | 9 | All functions of the compression library are documented in the file zlib.h 10 | (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example 11 | of the library is given in the file test/example.c which also tests that 12 | the library is working correctly. Another example is given in the file 13 | test/minigzip.c. The compression library itself is composed of all source 14 | files in the root directory. 15 | 16 | To compile all files and run the test program, follow the instructions given at 17 | the top of Makefile.in. In short "./configure; make test", and if that goes 18 | well, "make install" should work for most flavors of Unix. For Windows, use 19 | one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use 20 | make_vms.com. 21 | 22 | Questions about zlib should be sent to , or to Gilles Vollant 23 | for the Windows DLL version. The zlib home page is 24 | http://zlib.net/ . Before reporting a problem, please check this site to 25 | verify that you have the latest version of zlib; otherwise get the latest 26 | version and check whether the problem still exists or not. 27 | 28 | PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. 29 | 30 | Mark Nelson wrote an article about zlib for the Jan. 1997 31 | issue of Dr. Dobb's Journal; a copy of the article is available at 32 | https://marknelson.us/posts/1997/01/01/zlib-engine.html . 33 | 34 | The changes made in version 1.3.1 are documented in the file ChangeLog. 35 | 36 | Unsupported third party contributions are provided in directory contrib/ . 37 | 38 | zlib is available in Java using the java.util.zip package. Follow the API 39 | Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . 40 | 41 | A Perl interface to zlib and bzip2 written by Paul Marquess 42 | can be found at https://github.com/pmqs/IO-Compress . 43 | 44 | A Python interface to zlib written by A.M. Kuchling is 45 | available in Python 1.5 and later versions, see 46 | http://docs.python.org/library/zlib.html . 47 | 48 | zlib is built into tcl: http://wiki.tcl.tk/4610 . 49 | 50 | An experimental package to read and write files in .zip format, written on top 51 | of zlib by Gilles Vollant , is available in the 52 | contrib/minizip directory of zlib. 53 | 54 | 55 | Notes for some targets: 56 | 57 | - For Windows DLL versions, please see win32/DLL_FAQ.txt 58 | 59 | - For 64-bit Irix, deflate.c must be compiled without any optimization. With 60 | -O, one libpng test fails. The test works in 32 bit mode (with the -n32 61 | compiler flag). The compiler bug has been reported to SGI. 62 | 63 | - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works 64 | when compiled with cc. 65 | 66 | - On Digital Unix 4.0D (formerly OSF/1) on AlphaServer, the cc option -std1 is 67 | necessary to get gzprintf working correctly. This is done by configure. 68 | 69 | - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with 70 | other compilers. Use "make test" to check your compiler. 71 | 72 | - gzdopen is not supported on RISCOS or BEOS. 73 | 74 | - For PalmOs, see http://palmzlib.sourceforge.net/ 75 | 76 | 77 | Acknowledgments: 78 | 79 | The deflate format used by zlib was defined by Phil Katz. The deflate and 80 | zlib specifications were written by L. Peter Deutsch. Thanks to all the 81 | people who reported problems and suggested various improvements in zlib; they 82 | are too numerous to cite here. 83 | 84 | Copyright notice: 85 | 86 | (C) 1995-2024 Jean-loup Gailly and Mark Adler 87 | 88 | This software is provided 'as-is', without any express or implied 89 | warranty. In no event will the authors be held liable for any damages 90 | arising from the use of this software. 91 | 92 | Permission is granted to anyone to use this software for any purpose, 93 | including commercial applications, and to alter it and redistribute it 94 | freely, subject to the following restrictions: 95 | 96 | 1. The origin of this software must not be misrepresented; you must not 97 | claim that you wrote the original software. If you use this software 98 | in a product, an acknowledgment in the product documentation would be 99 | appreciated but is not required. 100 | 2. Altered source versions must be plainly marked as such, and must not be 101 | misrepresented as being the original software. 102 | 3. This notice may not be removed or altered from any source distribution. 103 | 104 | Jean-loup Gailly Mark Adler 105 | jloup@gzip.org madler@alumni.caltech.edu 106 | 107 | If you use the zlib library in a product, we would appreciate *not* receiving 108 | lengthy legal documents to sign. The sources are provided for free but without 109 | warranty of any kind. The library has been entirely written by Jean-loup 110 | Gailly and Mark Adler; it does not include third-party code. We make all 111 | contributions to and distributions of this project solely in our personal 112 | capacity, and are not conveying any rights to any intellectual property of 113 | any third parties. 114 | 115 | If you redistribute modified sources, we would appreciate that you include in 116 | the file ChangeLog history information documenting your changes. Please read 117 | the FAQ for more information on the distribution of modified source versions. 118 | -------------------------------------------------------------------------------- /src/zlib/adler32.c: -------------------------------------------------------------------------------- 1 | /* adler32.c -- compute the Adler-32 checksum of a data stream 2 | * Copyright (C) 1995-2011, 2016 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | 10 | #define BASE 65521U /* largest prime smaller than 65536 */ 11 | #define NMAX 5552 12 | /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 13 | 14 | #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 15 | #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 16 | #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 17 | #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 18 | #define DO16(buf) DO8(buf,0); DO8(buf,8); 19 | 20 | /* use NO_DIVIDE if your processor does not do division in hardware -- 21 | try it both ways to see which is faster */ 22 | #ifdef NO_DIVIDE 23 | /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 24 | (thank you to John Reiser for pointing this out) */ 25 | # define CHOP(a) \ 26 | do { \ 27 | unsigned long tmp = a >> 16; \ 28 | a &= 0xffffUL; \ 29 | a += (tmp << 4) - tmp; \ 30 | } while (0) 31 | # define MOD28(a) \ 32 | do { \ 33 | CHOP(a); \ 34 | if (a >= BASE) a -= BASE; \ 35 | } while (0) 36 | # define MOD(a) \ 37 | do { \ 38 | CHOP(a); \ 39 | MOD28(a); \ 40 | } while (0) 41 | # define MOD63(a) \ 42 | do { /* this assumes a is not negative */ \ 43 | z_off64_t tmp = a >> 32; \ 44 | a &= 0xffffffffL; \ 45 | a += (tmp << 8) - (tmp << 5) + tmp; \ 46 | tmp = a >> 16; \ 47 | a &= 0xffffL; \ 48 | a += (tmp << 4) - tmp; \ 49 | tmp = a >> 16; \ 50 | a &= 0xffffL; \ 51 | a += (tmp << 4) - tmp; \ 52 | if (a >= BASE) a -= BASE; \ 53 | } while (0) 54 | #else 55 | # define MOD(a) a %= BASE 56 | # define MOD28(a) a %= BASE 57 | # define MOD63(a) a %= BASE 58 | #endif 59 | 60 | /* ========================================================================= */ 61 | uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { 62 | unsigned long sum2; 63 | unsigned n; 64 | 65 | /* split Adler-32 into component sums */ 66 | sum2 = (adler >> 16) & 0xffff; 67 | adler &= 0xffff; 68 | 69 | /* in case user likes doing a byte at a time, keep it fast */ 70 | if (len == 1) { 71 | adler += buf[0]; 72 | if (adler >= BASE) 73 | adler -= BASE; 74 | sum2 += adler; 75 | if (sum2 >= BASE) 76 | sum2 -= BASE; 77 | return adler | (sum2 << 16); 78 | } 79 | 80 | /* initial Adler-32 value (deferred check for len == 1 speed) */ 81 | if (buf == Z_NULL) 82 | return 1L; 83 | 84 | /* in case short lengths are provided, keep it somewhat fast */ 85 | if (len < 16) { 86 | while (len--) { 87 | adler += *buf++; 88 | sum2 += adler; 89 | } 90 | if (adler >= BASE) 91 | adler -= BASE; 92 | MOD28(sum2); /* only added so many BASE's */ 93 | return adler | (sum2 << 16); 94 | } 95 | 96 | /* do length NMAX blocks -- requires just one modulo operation */ 97 | while (len >= NMAX) { 98 | len -= NMAX; 99 | n = NMAX / 16; /* NMAX is divisible by 16 */ 100 | do { 101 | DO16(buf); /* 16 sums unrolled */ 102 | buf += 16; 103 | } while (--n); 104 | MOD(adler); 105 | MOD(sum2); 106 | } 107 | 108 | /* do remaining bytes (less than NMAX, still just one modulo) */ 109 | if (len) { /* avoid modulos if none remaining */ 110 | while (len >= 16) { 111 | len -= 16; 112 | DO16(buf); 113 | buf += 16; 114 | } 115 | while (len--) { 116 | adler += *buf++; 117 | sum2 += adler; 118 | } 119 | MOD(adler); 120 | MOD(sum2); 121 | } 122 | 123 | /* return recombined sums */ 124 | return adler | (sum2 << 16); 125 | } 126 | 127 | /* ========================================================================= */ 128 | uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { 129 | return adler32_z(adler, buf, len); 130 | } 131 | 132 | /* ========================================================================= */ 133 | local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { 134 | unsigned long sum1; 135 | unsigned long sum2; 136 | unsigned rem; 137 | 138 | /* for negative len, return invalid adler32 as a clue for debugging */ 139 | if (len2 < 0) 140 | return 0xffffffffUL; 141 | 142 | /* the derivation of this formula is left as an exercise for the reader */ 143 | MOD63(len2); /* assumes len2 >= 0 */ 144 | rem = (unsigned)len2; 145 | sum1 = adler1 & 0xffff; 146 | sum2 = rem * sum1; 147 | MOD(sum2); 148 | sum1 += (adler2 & 0xffff) + BASE - 1; 149 | sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 150 | if (sum1 >= BASE) sum1 -= BASE; 151 | if (sum1 >= BASE) sum1 -= BASE; 152 | if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); 153 | if (sum2 >= BASE) sum2 -= BASE; 154 | return sum1 | (sum2 << 16); 155 | } 156 | 157 | /* ========================================================================= */ 158 | uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { 159 | return adler32_combine_(adler1, adler2, len2); 160 | } 161 | 162 | uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { 163 | return adler32_combine_(adler1, adler2, len2); 164 | } 165 | -------------------------------------------------------------------------------- /src/zlib/compress.c: -------------------------------------------------------------------------------- 1 | /* compress.c -- compress a memory buffer 2 | * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Compresses the source buffer into the destination buffer. The level 13 | parameter has the same meaning as in deflateInit. sourceLen is the byte 14 | length of the source buffer. Upon entry, destLen is the total size of the 15 | destination buffer, which must be at least 0.1% larger than sourceLen plus 16 | 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 17 | 18 | compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 19 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, 20 | Z_STREAM_ERROR if the level parameter is invalid. 21 | */ 22 | int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, 23 | uLong sourceLen, int level) { 24 | z_stream stream; 25 | int err; 26 | const uInt max = (uInt)-1; 27 | uLong left; 28 | 29 | left = *destLen; 30 | *destLen = 0; 31 | 32 | stream.zalloc = (alloc_func)0; 33 | stream.zfree = (free_func)0; 34 | stream.opaque = (voidpf)0; 35 | 36 | err = deflateInit(&stream, level); 37 | if (err != Z_OK) return err; 38 | 39 | stream.next_out = dest; 40 | stream.avail_out = 0; 41 | stream.next_in = (z_const Bytef *)source; 42 | stream.avail_in = 0; 43 | 44 | do { 45 | if (stream.avail_out == 0) { 46 | stream.avail_out = left > (uLong)max ? max : (uInt)left; 47 | left -= stream.avail_out; 48 | } 49 | if (stream.avail_in == 0) { 50 | stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; 51 | sourceLen -= stream.avail_in; 52 | } 53 | err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); 54 | } while (err == Z_OK); 55 | 56 | *destLen = stream.total_out; 57 | deflateEnd(&stream); 58 | return err == Z_STREAM_END ? Z_OK : err; 59 | } 60 | 61 | /* =========================================================================== 62 | */ 63 | int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, 64 | uLong sourceLen) { 65 | return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); 66 | } 67 | 68 | /* =========================================================================== 69 | If the default memLevel or windowBits for deflateInit() is changed, then 70 | this function needs to be updated. 71 | */ 72 | uLong ZEXPORT compressBound(uLong sourceLen) { 73 | return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 74 | (sourceLen >> 25) + 13; 75 | } 76 | -------------------------------------------------------------------------------- /src/zlib/deflate.h: -------------------------------------------------------------------------------- 1 | /* deflate.h -- internal compression state 2 | * Copyright (C) 1995-2024 Jean-loup Gailly 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* @(#) $Id$ */ 12 | 13 | #ifndef DEFLATE_H 14 | #define DEFLATE_H 15 | 16 | #include "zutil.h" 17 | 18 | /* define NO_GZIP when compiling if you want to disable gzip header and 19 | trailer creation by deflate(). NO_GZIP would be used to avoid linking in 20 | the crc code when it is not needed. For shared libraries, gzip encoding 21 | should be left enabled. */ 22 | #ifndef NO_GZIP 23 | # define GZIP 24 | #endif 25 | 26 | /* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at 27 | the cost of a larger memory footprint */ 28 | /* #define LIT_MEM */ 29 | 30 | /* =========================================================================== 31 | * Internal compression state. 32 | */ 33 | 34 | #define LENGTH_CODES 29 35 | /* number of length codes, not counting the special END_BLOCK code */ 36 | 37 | #define LITERALS 256 38 | /* number of literal bytes 0..255 */ 39 | 40 | #define L_CODES (LITERALS+1+LENGTH_CODES) 41 | /* number of Literal or Length codes, including the END_BLOCK code */ 42 | 43 | #define D_CODES 30 44 | /* number of distance codes */ 45 | 46 | #define BL_CODES 19 47 | /* number of codes used to transfer the bit lengths */ 48 | 49 | #define HEAP_SIZE (2*L_CODES+1) 50 | /* maximum heap size */ 51 | 52 | #define MAX_BITS 15 53 | /* All codes must not exceed MAX_BITS bits */ 54 | 55 | #define Buf_size 16 56 | /* size of bit buffer in bi_buf */ 57 | 58 | #define INIT_STATE 42 /* zlib header -> BUSY_STATE */ 59 | #ifdef GZIP 60 | # define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ 61 | #endif 62 | #define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ 63 | #define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ 64 | #define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ 65 | #define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ 66 | #define BUSY_STATE 113 /* deflate -> FINISH_STATE */ 67 | #define FINISH_STATE 666 /* stream complete */ 68 | /* Stream status */ 69 | 70 | 71 | /* Data structure describing a single value and its code string. */ 72 | typedef struct ct_data_s { 73 | union { 74 | ush freq; /* frequency count */ 75 | ush code; /* bit string */ 76 | } fc; 77 | union { 78 | ush dad; /* father node in Huffman tree */ 79 | ush len; /* length of bit string */ 80 | } dl; 81 | } FAR ct_data; 82 | 83 | #define Freq fc.freq 84 | #define Code fc.code 85 | #define Dad dl.dad 86 | #define Len dl.len 87 | 88 | typedef struct static_tree_desc_s static_tree_desc; 89 | 90 | typedef struct tree_desc_s { 91 | ct_data *dyn_tree; /* the dynamic tree */ 92 | int max_code; /* largest code with non zero frequency */ 93 | const static_tree_desc *stat_desc; /* the corresponding static tree */ 94 | } FAR tree_desc; 95 | 96 | typedef ush Pos; 97 | typedef Pos FAR Posf; 98 | typedef unsigned IPos; 99 | 100 | /* A Pos is an index in the character window. We use short instead of int to 101 | * save space in the various tables. IPos is used only for parameter passing. 102 | */ 103 | 104 | typedef struct internal_state { 105 | z_streamp strm; /* pointer back to this zlib stream */ 106 | int status; /* as the name implies */ 107 | Bytef *pending_buf; /* output still pending */ 108 | ulg pending_buf_size; /* size of pending_buf */ 109 | Bytef *pending_out; /* next pending byte to output to the stream */ 110 | ulg pending; /* nb of bytes in the pending buffer */ 111 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ 112 | gz_headerp gzhead; /* gzip header information to write */ 113 | ulg gzindex; /* where in extra, name, or comment */ 114 | Byte method; /* can only be DEFLATED */ 115 | int last_flush; /* value of flush param for previous deflate call */ 116 | 117 | /* used by deflate.c: */ 118 | 119 | uInt w_size; /* LZ77 window size (32K by default) */ 120 | uInt w_bits; /* log2(w_size) (8..16) */ 121 | uInt w_mask; /* w_size - 1 */ 122 | 123 | Bytef *window; 124 | /* Sliding window. Input bytes are read into the second half of the window, 125 | * and move to the first half later to keep a dictionary of at least wSize 126 | * bytes. With this organization, matches are limited to a distance of 127 | * wSize-MAX_MATCH bytes, but this ensures that IO is always 128 | * performed with a length multiple of the block size. Also, it limits 129 | * the window size to 64K, which is quite useful on MSDOS. 130 | * To do: use the user input buffer as sliding window. 131 | */ 132 | 133 | ulg window_size; 134 | /* Actual size of window: 2*wSize, except when the user input buffer 135 | * is directly used as sliding window. 136 | */ 137 | 138 | Posf *prev; 139 | /* Link to older string with same hash index. To limit the size of this 140 | * array to 64K, this link is maintained only for the last 32K strings. 141 | * An index in this array is thus a window index modulo 32K. 142 | */ 143 | 144 | Posf *head; /* Heads of the hash chains or NIL. */ 145 | 146 | uInt ins_h; /* hash index of string to be inserted */ 147 | uInt hash_size; /* number of elements in hash table */ 148 | uInt hash_bits; /* log2(hash_size) */ 149 | uInt hash_mask; /* hash_size-1 */ 150 | 151 | uInt hash_shift; 152 | /* Number of bits by which ins_h must be shifted at each input 153 | * step. It must be such that after MIN_MATCH steps, the oldest 154 | * byte no longer takes part in the hash key, that is: 155 | * hash_shift * MIN_MATCH >= hash_bits 156 | */ 157 | 158 | long block_start; 159 | /* Window position at the beginning of the current output block. Gets 160 | * negative when the window is moved backwards. 161 | */ 162 | 163 | uInt match_length; /* length of best match */ 164 | IPos prev_match; /* previous match */ 165 | int match_available; /* set if previous match exists */ 166 | uInt strstart; /* start of string to insert */ 167 | uInt match_start; /* start of matching string */ 168 | uInt lookahead; /* number of valid bytes ahead in window */ 169 | 170 | uInt prev_length; 171 | /* Length of the best match at previous step. Matches not greater than this 172 | * are discarded. This is used in the lazy match evaluation. 173 | */ 174 | 175 | uInt max_chain_length; 176 | /* To speed up deflation, hash chains are never searched beyond this 177 | * length. A higher limit improves compression ratio but degrades the 178 | * speed. 179 | */ 180 | 181 | uInt max_lazy_match; 182 | /* Attempt to find a better match only when the current match is strictly 183 | * smaller than this value. This mechanism is used only for compression 184 | * levels >= 4. 185 | */ 186 | # define max_insert_length max_lazy_match 187 | /* Insert new strings in the hash table only if the match length is not 188 | * greater than this length. This saves time but degrades compression. 189 | * max_insert_length is used only for compression levels <= 3. 190 | */ 191 | 192 | int level; /* compression level (1..9) */ 193 | int strategy; /* favor or force Huffman coding*/ 194 | 195 | uInt good_match; 196 | /* Use a faster search when the previous match is longer than this */ 197 | 198 | int nice_match; /* Stop searching when current match exceeds this */ 199 | 200 | /* used by trees.c: */ 201 | /* Didn't use ct_data typedef below to suppress compiler warning */ 202 | struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ 203 | struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ 204 | struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ 205 | 206 | struct tree_desc_s l_desc; /* desc. for literal tree */ 207 | struct tree_desc_s d_desc; /* desc. for distance tree */ 208 | struct tree_desc_s bl_desc; /* desc. for bit length tree */ 209 | 210 | ush bl_count[MAX_BITS+1]; 211 | /* number of codes at each bit length for an optimal tree */ 212 | 213 | int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ 214 | int heap_len; /* number of elements in the heap */ 215 | int heap_max; /* element of largest frequency */ 216 | /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. 217 | * The same heap array is used to build all trees. 218 | */ 219 | 220 | uch depth[2*L_CODES+1]; 221 | /* Depth of each subtree used as tie breaker for trees of equal frequency 222 | */ 223 | 224 | #ifdef LIT_MEM 225 | # define LIT_BUFS 5 226 | ushf *d_buf; /* buffer for distances */ 227 | uchf *l_buf; /* buffer for literals/lengths */ 228 | #else 229 | # define LIT_BUFS 4 230 | uchf *sym_buf; /* buffer for distances and literals/lengths */ 231 | #endif 232 | 233 | uInt lit_bufsize; 234 | /* Size of match buffer for literals/lengths. There are 4 reasons for 235 | * limiting lit_bufsize to 64K: 236 | * - frequencies can be kept in 16 bit counters 237 | * - if compression is not successful for the first block, all input 238 | * data is still in the window so we can still emit a stored block even 239 | * when input comes from standard input. (This can also be done for 240 | * all blocks if lit_bufsize is not greater than 32K.) 241 | * - if compression is not successful for a file smaller than 64K, we can 242 | * even emit a stored file instead of a stored block (saving 5 bytes). 243 | * This is applicable only for zip (not gzip or zlib). 244 | * - creating new Huffman trees less frequently may not provide fast 245 | * adaptation to changes in the input data statistics. (Take for 246 | * example a binary file with poorly compressible code followed by 247 | * a highly compressible string table.) Smaller buffer sizes give 248 | * fast adaptation but have of course the overhead of transmitting 249 | * trees more frequently. 250 | * - I can't count above 4 251 | */ 252 | 253 | uInt sym_next; /* running index in symbol buffer */ 254 | uInt sym_end; /* symbol table full when sym_next reaches this */ 255 | 256 | ulg opt_len; /* bit length of current block with optimal trees */ 257 | ulg static_len; /* bit length of current block with static trees */ 258 | uInt matches; /* number of string matches in current block */ 259 | uInt insert; /* bytes at end of window left to insert */ 260 | 261 | #ifdef ZLIB_DEBUG 262 | ulg compressed_len; /* total bit length of compressed file mod 2^32 */ 263 | ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ 264 | #endif 265 | 266 | ush bi_buf; 267 | /* Output buffer. bits are inserted starting at the bottom (least 268 | * significant bits). 269 | */ 270 | int bi_valid; 271 | /* Number of valid bits in bi_buf. All bits above the last valid bit 272 | * are always zero. 273 | */ 274 | 275 | ulg high_water; 276 | /* High water mark offset in window for initialized bytes -- bytes above 277 | * this are set to zero in order to avoid memory check warnings when 278 | * longest match routines access bytes past the input. This is then 279 | * updated to the new high water mark. 280 | */ 281 | 282 | } FAR deflate_state; 283 | 284 | /* Output a byte on the stream. 285 | * IN assertion: there is enough room in pending_buf. 286 | */ 287 | #define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} 288 | 289 | 290 | #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) 291 | /* Minimum amount of lookahead, except at the end of the input file. 292 | * See deflate.c for comments about the MIN_MATCH+1. 293 | */ 294 | 295 | #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) 296 | /* In order to simplify the code, particularly on 16 bit machines, match 297 | * distances are limited to MAX_DIST instead of WSIZE. 298 | */ 299 | 300 | #define WIN_INIT MAX_MATCH 301 | /* Number of bytes after end of data in window to initialize in order to avoid 302 | memory checker errors from longest match routines */ 303 | 304 | /* in trees.c */ 305 | void ZLIB_INTERNAL _tr_init(deflate_state *s); 306 | int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); 307 | void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, 308 | ulg stored_len, int last); 309 | void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); 310 | void ZLIB_INTERNAL _tr_align(deflate_state *s); 311 | void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, 312 | ulg stored_len, int last); 313 | 314 | #define d_code(dist) \ 315 | ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) 316 | /* Mapping from a distance to a distance code. dist is the distance - 1 and 317 | * must not have side effects. _dist_code[256] and _dist_code[257] are never 318 | * used. 319 | */ 320 | 321 | #ifndef ZLIB_DEBUG 322 | /* Inline versions of _tr_tally for speed: */ 323 | 324 | #if defined(GEN_TREES_H) || !defined(STDC) 325 | extern uch ZLIB_INTERNAL _length_code[]; 326 | extern uch ZLIB_INTERNAL _dist_code[]; 327 | #else 328 | extern const uch ZLIB_INTERNAL _length_code[]; 329 | extern const uch ZLIB_INTERNAL _dist_code[]; 330 | #endif 331 | 332 | #ifdef LIT_MEM 333 | # define _tr_tally_lit(s, c, flush) \ 334 | { uch cc = (c); \ 335 | s->d_buf[s->sym_next] = 0; \ 336 | s->l_buf[s->sym_next++] = cc; \ 337 | s->dyn_ltree[cc].Freq++; \ 338 | flush = (s->sym_next == s->sym_end); \ 339 | } 340 | # define _tr_tally_dist(s, distance, length, flush) \ 341 | { uch len = (uch)(length); \ 342 | ush dist = (ush)(distance); \ 343 | s->d_buf[s->sym_next] = dist; \ 344 | s->l_buf[s->sym_next++] = len; \ 345 | dist--; \ 346 | s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ 347 | s->dyn_dtree[d_code(dist)].Freq++; \ 348 | flush = (s->sym_next == s->sym_end); \ 349 | } 350 | #else 351 | # define _tr_tally_lit(s, c, flush) \ 352 | { uch cc = (c); \ 353 | s->sym_buf[s->sym_next++] = 0; \ 354 | s->sym_buf[s->sym_next++] = 0; \ 355 | s->sym_buf[s->sym_next++] = cc; \ 356 | s->dyn_ltree[cc].Freq++; \ 357 | flush = (s->sym_next == s->sym_end); \ 358 | } 359 | # define _tr_tally_dist(s, distance, length, flush) \ 360 | { uch len = (uch)(length); \ 361 | ush dist = (ush)(distance); \ 362 | s->sym_buf[s->sym_next++] = (uch)dist; \ 363 | s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ 364 | s->sym_buf[s->sym_next++] = len; \ 365 | dist--; \ 366 | s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ 367 | s->dyn_dtree[d_code(dist)].Freq++; \ 368 | flush = (s->sym_next == s->sym_end); \ 369 | } 370 | #endif 371 | #else 372 | # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) 373 | # define _tr_tally_dist(s, distance, length, flush) \ 374 | flush = _tr_tally(s, distance, length) 375 | #endif 376 | 377 | #endif /* DEFLATE_H */ 378 | -------------------------------------------------------------------------------- /src/zlib/gzclose.c: -------------------------------------------------------------------------------- 1 | /* gzclose.c -- zlib gzclose() function 2 | * Copyright (C) 2004, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | #include "gzguts.h" 7 | 8 | /* gzclose() is in a separate file so that it is linked in only if it is used. 9 | That way the other gzclose functions can be used instead to avoid linking in 10 | unneeded compression or decompression routines. */ 11 | int ZEXPORT gzclose(gzFile file) { 12 | #ifndef NO_GZCOMPRESS 13 | gz_statep state; 14 | 15 | if (file == NULL) 16 | return Z_STREAM_ERROR; 17 | state = (gz_statep)file; 18 | 19 | return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); 20 | #else 21 | return gzclose_r(file); 22 | #endif 23 | } 24 | -------------------------------------------------------------------------------- /src/zlib/gzguts.h: -------------------------------------------------------------------------------- 1 | /* gzguts.h -- zlib internal header definitions for gz* operations 2 | * Copyright (C) 2004-2024 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | #ifdef _LARGEFILE64_SOURCE 7 | # ifndef _LARGEFILE_SOURCE 8 | # define _LARGEFILE_SOURCE 1 9 | # endif 10 | # undef _FILE_OFFSET_BITS 11 | # undef _TIME_BITS 12 | #endif 13 | 14 | #ifdef HAVE_HIDDEN 15 | # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) 16 | #else 17 | # define ZLIB_INTERNAL 18 | #endif 19 | 20 | #include 21 | #include "zlib.h" 22 | #ifdef STDC 23 | # include 24 | # include 25 | # include 26 | #endif 27 | 28 | #ifndef _POSIX_SOURCE 29 | # define _POSIX_SOURCE 30 | #endif 31 | #include 32 | 33 | #ifdef _WIN32 34 | # include 35 | #endif 36 | 37 | #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) 38 | # include 39 | #endif 40 | 41 | #if defined(_WIN32) 42 | # define WIDECHAR 43 | #endif 44 | 45 | #ifdef WINAPI_FAMILY 46 | # define open _open 47 | # define read _read 48 | # define write _write 49 | # define close _close 50 | #endif 51 | 52 | #ifdef NO_DEFLATE /* for compatibility with old definition */ 53 | # define NO_GZCOMPRESS 54 | #endif 55 | 56 | #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) 57 | # ifndef HAVE_VSNPRINTF 58 | # define HAVE_VSNPRINTF 59 | # endif 60 | #endif 61 | 62 | #if defined(__CYGWIN__) 63 | # ifndef HAVE_VSNPRINTF 64 | # define HAVE_VSNPRINTF 65 | # endif 66 | #endif 67 | 68 | #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) 69 | # ifndef HAVE_VSNPRINTF 70 | # define HAVE_VSNPRINTF 71 | # endif 72 | #endif 73 | 74 | #ifndef HAVE_VSNPRINTF 75 | # ifdef MSDOS 76 | /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), 77 | but for now we just assume it doesn't. */ 78 | # define NO_vsnprintf 79 | # endif 80 | # ifdef __TURBOC__ 81 | # define NO_vsnprintf 82 | # endif 83 | # ifdef WIN32 84 | /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ 85 | # if !defined(vsnprintf) && !defined(NO_vsnprintf) 86 | # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) 87 | # define vsnprintf _vsnprintf 88 | # endif 89 | # endif 90 | # endif 91 | # ifdef __SASC 92 | # define NO_vsnprintf 93 | # endif 94 | # ifdef VMS 95 | # define NO_vsnprintf 96 | # endif 97 | # ifdef __OS400__ 98 | # define NO_vsnprintf 99 | # endif 100 | # ifdef __MVS__ 101 | # define NO_vsnprintf 102 | # endif 103 | #endif 104 | 105 | /* unlike snprintf (which is required in C99), _snprintf does not guarantee 106 | null termination of the result -- however this is only used in gzlib.c where 107 | the result is assured to fit in the space provided */ 108 | #if defined(_MSC_VER) && _MSC_VER < 1900 109 | # define snprintf _snprintf 110 | #endif 111 | 112 | #ifndef local 113 | # define local static 114 | #endif 115 | /* since "static" is used to mean two completely different things in C, we 116 | define "local" for the non-static meaning of "static", for readability 117 | (compile with -Dlocal if your debugger can't find static symbols) */ 118 | 119 | /* gz* functions always use library allocation functions */ 120 | #ifndef STDC 121 | extern voidp malloc(uInt size); 122 | extern void free(voidpf ptr); 123 | #endif 124 | 125 | /* get errno and strerror definition */ 126 | #if defined UNDER_CE 127 | # include 128 | # define zstrerror() gz_strwinerror((DWORD)GetLastError()) 129 | #else 130 | # ifndef NO_STRERROR 131 | # include 132 | # define zstrerror() strerror(errno) 133 | # else 134 | # define zstrerror() "stdio error (consult errno)" 135 | # endif 136 | #endif 137 | 138 | /* provide prototypes for these when building zlib without LFS */ 139 | #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 140 | ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); 141 | ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); 142 | ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); 143 | ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); 144 | #endif 145 | 146 | /* default memLevel */ 147 | #if MAX_MEM_LEVEL >= 8 148 | # define DEF_MEM_LEVEL 8 149 | #else 150 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 151 | #endif 152 | 153 | /* default i/o buffer size -- double this for output when reading (this and 154 | twice this must be able to fit in an unsigned type) */ 155 | #define GZBUFSIZE 8192 156 | 157 | /* gzip modes, also provide a little integrity check on the passed structure */ 158 | #define GZ_NONE 0 159 | #define GZ_READ 7247 160 | #define GZ_WRITE 31153 161 | #define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ 162 | 163 | /* values for gz_state how */ 164 | #define LOOK 0 /* look for a gzip header */ 165 | #define COPY 1 /* copy input directly */ 166 | #define GZIP 2 /* decompress a gzip stream */ 167 | 168 | /* internal gzip file state data structure */ 169 | typedef struct { 170 | /* exposed contents for gzgetc() macro */ 171 | struct gzFile_s x; /* "x" for exposed */ 172 | /* x.have: number of bytes available at x.next */ 173 | /* x.next: next output data to deliver or write */ 174 | /* x.pos: current position in uncompressed data */ 175 | /* used for both reading and writing */ 176 | int mode; /* see gzip modes above */ 177 | int fd; /* file descriptor */ 178 | char *path; /* path or fd for error messages */ 179 | unsigned size; /* buffer size, zero if not allocated yet */ 180 | unsigned want; /* requested buffer size, default is GZBUFSIZE */ 181 | unsigned char *in; /* input buffer (double-sized when writing) */ 182 | unsigned char *out; /* output buffer (double-sized when reading) */ 183 | int direct; /* 0 if processing gzip, 1 if transparent */ 184 | /* just for reading */ 185 | int how; /* 0: get header, 1: copy, 2: decompress */ 186 | z_off64_t start; /* where the gzip data started, for rewinding */ 187 | int eof; /* true if end of input file reached */ 188 | int past; /* true if read requested past end */ 189 | /* just for writing */ 190 | int level; /* compression level */ 191 | int strategy; /* compression strategy */ 192 | int reset; /* true if a reset is pending after a Z_FINISH */ 193 | /* seek request */ 194 | z_off64_t skip; /* amount to skip (already rewound if backwards) */ 195 | int seek; /* true if seek request pending */ 196 | /* error information */ 197 | int err; /* error code */ 198 | char *msg; /* error message */ 199 | /* zlib inflate or deflate stream */ 200 | z_stream strm; /* stream structure in-place (not a pointer) */ 201 | } gz_state; 202 | typedef gz_state FAR *gz_statep; 203 | 204 | /* shared functions */ 205 | void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); 206 | #if defined UNDER_CE 207 | char ZLIB_INTERNAL *gz_strwinerror(DWORD error); 208 | #endif 209 | 210 | /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t 211 | value -- needed when comparing unsigned to z_off64_t, which is signed 212 | (possible z_off64_t types off_t, off64_t, and long are all signed) */ 213 | unsigned ZLIB_INTERNAL gz_intmax(void); 214 | #define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) 215 | -------------------------------------------------------------------------------- /src/zlib/inffast.c: -------------------------------------------------------------------------------- 1 | /* inffast.c -- fast decoding 2 | * Copyright (C) 1995-2017 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | #include "zutil.h" 7 | #include "inftrees.h" 8 | #include "inflate.h" 9 | #include "inffast.h" 10 | 11 | #ifdef ASMINF 12 | # pragma message("Assembler code may have bugs -- use at your own risk") 13 | #else 14 | 15 | /* 16 | Decode literal, length, and distance codes and write out the resulting 17 | literal and match bytes until either not enough input or output is 18 | available, an end-of-block is encountered, or a data error is encountered. 19 | When large enough input and output buffers are supplied to inflate(), for 20 | example, a 16K input buffer and a 64K output buffer, more than 95% of the 21 | inflate execution time is spent in this routine. 22 | 23 | Entry assumptions: 24 | 25 | state->mode == LEN 26 | strm->avail_in >= 6 27 | strm->avail_out >= 258 28 | start >= strm->avail_out 29 | state->bits < 8 30 | 31 | On return, state->mode is one of: 32 | 33 | LEN -- ran out of enough output space or enough available input 34 | TYPE -- reached end of block code, inflate() to interpret next block 35 | BAD -- error in block data 36 | 37 | Notes: 38 | 39 | - The maximum input bits used by a length/distance pair is 15 bits for the 40 | length code, 5 bits for the length extra, 15 bits for the distance code, 41 | and 13 bits for the distance extra. This totals 48 bits, or six bytes. 42 | Therefore if strm->avail_in >= 6, then there is enough input to avoid 43 | checking for available input while decoding. 44 | 45 | - The maximum bytes that a single length/distance pair can output is 258 46 | bytes, which is the maximum length that can be coded. inflate_fast() 47 | requires strm->avail_out >= 258 for each loop to avoid checking for 48 | output space. 49 | */ 50 | void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { 51 | struct inflate_state FAR *state; 52 | z_const unsigned char FAR *in; /* local strm->next_in */ 53 | z_const unsigned char FAR *last; /* have enough input while in < last */ 54 | unsigned char FAR *out; /* local strm->next_out */ 55 | unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ 56 | unsigned char FAR *end; /* while out < end, enough space available */ 57 | #ifdef INFLATE_STRICT 58 | unsigned dmax; /* maximum distance from zlib header */ 59 | #endif 60 | unsigned wsize; /* window size or zero if not using window */ 61 | unsigned whave; /* valid bytes in the window */ 62 | unsigned wnext; /* window write index */ 63 | unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ 64 | unsigned long hold; /* local strm->hold */ 65 | unsigned bits; /* local strm->bits */ 66 | code const FAR *lcode; /* local strm->lencode */ 67 | code const FAR *dcode; /* local strm->distcode */ 68 | unsigned lmask; /* mask for first level of length codes */ 69 | unsigned dmask; /* mask for first level of distance codes */ 70 | code const *here; /* retrieved table entry */ 71 | unsigned op; /* code bits, operation, extra bits, or */ 72 | /* window position, window bytes to copy */ 73 | unsigned len; /* match length, unused bytes */ 74 | unsigned dist; /* match distance */ 75 | unsigned char FAR *from; /* where to copy match from */ 76 | 77 | /* copy state to local variables */ 78 | state = (struct inflate_state FAR *)strm->state; 79 | in = strm->next_in; 80 | last = in + (strm->avail_in - 5); 81 | out = strm->next_out; 82 | beg = out - (start - strm->avail_out); 83 | end = out + (strm->avail_out - 257); 84 | #ifdef INFLATE_STRICT 85 | dmax = state->dmax; 86 | #endif 87 | wsize = state->wsize; 88 | whave = state->whave; 89 | wnext = state->wnext; 90 | window = state->window; 91 | hold = state->hold; 92 | bits = state->bits; 93 | lcode = state->lencode; 94 | dcode = state->distcode; 95 | lmask = (1U << state->lenbits) - 1; 96 | dmask = (1U << state->distbits) - 1; 97 | 98 | /* decode literals and length/distances until end-of-block or not enough 99 | input data or output space */ 100 | do { 101 | if (bits < 15) { 102 | hold += (unsigned long)(*in++) << bits; 103 | bits += 8; 104 | hold += (unsigned long)(*in++) << bits; 105 | bits += 8; 106 | } 107 | here = lcode + (hold & lmask); 108 | dolen: 109 | op = (unsigned)(here->bits); 110 | hold >>= op; 111 | bits -= op; 112 | op = (unsigned)(here->op); 113 | if (op == 0) { /* literal */ 114 | Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? 115 | "inflate: literal '%c'\n" : 116 | "inflate: literal 0x%02x\n", here->val)); 117 | *out++ = (unsigned char)(here->val); 118 | } 119 | else if (op & 16) { /* length base */ 120 | len = (unsigned)(here->val); 121 | op &= 15; /* number of extra bits */ 122 | if (op) { 123 | if (bits < op) { 124 | hold += (unsigned long)(*in++) << bits; 125 | bits += 8; 126 | } 127 | len += (unsigned)hold & ((1U << op) - 1); 128 | hold >>= op; 129 | bits -= op; 130 | } 131 | Tracevv((stderr, "inflate: length %u\n", len)); 132 | if (bits < 15) { 133 | hold += (unsigned long)(*in++) << bits; 134 | bits += 8; 135 | hold += (unsigned long)(*in++) << bits; 136 | bits += 8; 137 | } 138 | here = dcode + (hold & dmask); 139 | dodist: 140 | op = (unsigned)(here->bits); 141 | hold >>= op; 142 | bits -= op; 143 | op = (unsigned)(here->op); 144 | if (op & 16) { /* distance base */ 145 | dist = (unsigned)(here->val); 146 | op &= 15; /* number of extra bits */ 147 | if (bits < op) { 148 | hold += (unsigned long)(*in++) << bits; 149 | bits += 8; 150 | if (bits < op) { 151 | hold += (unsigned long)(*in++) << bits; 152 | bits += 8; 153 | } 154 | } 155 | dist += (unsigned)hold & ((1U << op) - 1); 156 | #ifdef INFLATE_STRICT 157 | if (dist > dmax) { 158 | strm->msg = (char *)"invalid distance too far back"; 159 | state->mode = BAD; 160 | break; 161 | } 162 | #endif 163 | hold >>= op; 164 | bits -= op; 165 | Tracevv((stderr, "inflate: distance %u\n", dist)); 166 | op = (unsigned)(out - beg); /* max distance in output */ 167 | if (dist > op) { /* see if copy from window */ 168 | op = dist - op; /* distance back in window */ 169 | if (op > whave) { 170 | if (state->sane) { 171 | strm->msg = 172 | (char *)"invalid distance too far back"; 173 | state->mode = BAD; 174 | break; 175 | } 176 | #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 177 | if (len <= op - whave) { 178 | do { 179 | *out++ = 0; 180 | } while (--len); 181 | continue; 182 | } 183 | len -= op - whave; 184 | do { 185 | *out++ = 0; 186 | } while (--op > whave); 187 | if (op == 0) { 188 | from = out - dist; 189 | do { 190 | *out++ = *from++; 191 | } while (--len); 192 | continue; 193 | } 194 | #endif 195 | } 196 | from = window; 197 | if (wnext == 0) { /* very common case */ 198 | from += wsize - op; 199 | if (op < len) { /* some from window */ 200 | len -= op; 201 | do { 202 | *out++ = *from++; 203 | } while (--op); 204 | from = out - dist; /* rest from output */ 205 | } 206 | } 207 | else if (wnext < op) { /* wrap around window */ 208 | from += wsize + wnext - op; 209 | op -= wnext; 210 | if (op < len) { /* some from end of window */ 211 | len -= op; 212 | do { 213 | *out++ = *from++; 214 | } while (--op); 215 | from = window; 216 | if (wnext < len) { /* some from start of window */ 217 | op = wnext; 218 | len -= op; 219 | do { 220 | *out++ = *from++; 221 | } while (--op); 222 | from = out - dist; /* rest from output */ 223 | } 224 | } 225 | } 226 | else { /* contiguous in window */ 227 | from += wnext - op; 228 | if (op < len) { /* some from window */ 229 | len -= op; 230 | do { 231 | *out++ = *from++; 232 | } while (--op); 233 | from = out - dist; /* rest from output */ 234 | } 235 | } 236 | while (len > 2) { 237 | *out++ = *from++; 238 | *out++ = *from++; 239 | *out++ = *from++; 240 | len -= 3; 241 | } 242 | if (len) { 243 | *out++ = *from++; 244 | if (len > 1) 245 | *out++ = *from++; 246 | } 247 | } 248 | else { 249 | from = out - dist; /* copy direct from output */ 250 | do { /* minimum length is three */ 251 | *out++ = *from++; 252 | *out++ = *from++; 253 | *out++ = *from++; 254 | len -= 3; 255 | } while (len > 2); 256 | if (len) { 257 | *out++ = *from++; 258 | if (len > 1) 259 | *out++ = *from++; 260 | } 261 | } 262 | } 263 | else if ((op & 64) == 0) { /* 2nd level distance code */ 264 | here = dcode + here->val + (hold & ((1U << op) - 1)); 265 | goto dodist; 266 | } 267 | else { 268 | strm->msg = (char *)"invalid distance code"; 269 | state->mode = BAD; 270 | break; 271 | } 272 | } 273 | else if ((op & 64) == 0) { /* 2nd level length code */ 274 | here = lcode + here->val + (hold & ((1U << op) - 1)); 275 | goto dolen; 276 | } 277 | else if (op & 32) { /* end-of-block */ 278 | Tracevv((stderr, "inflate: end of block\n")); 279 | state->mode = TYPE; 280 | break; 281 | } 282 | else { 283 | strm->msg = (char *)"invalid literal/length code"; 284 | state->mode = BAD; 285 | break; 286 | } 287 | } while (in < last && out < end); 288 | 289 | /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ 290 | len = bits >> 3; 291 | in -= len; 292 | bits -= len << 3; 293 | hold &= (1U << bits) - 1; 294 | 295 | /* update state and return */ 296 | strm->next_in = in; 297 | strm->next_out = out; 298 | strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); 299 | strm->avail_out = (unsigned)(out < end ? 300 | 257 + (end - out) : 257 - (out - end)); 301 | state->hold = hold; 302 | state->bits = bits; 303 | return; 304 | } 305 | 306 | /* 307 | inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): 308 | - Using bit fields for code structure 309 | - Different op definition to avoid & for extra bits (do & for table bits) 310 | - Three separate decoding do-loops for direct, window, and wnext == 0 311 | - Special case for distance > 1 copies to do overlapped load and store copy 312 | - Explicit branch predictions (based on measured branch probabilities) 313 | - Deferring match copy and interspersed it with decoding subsequent codes 314 | - Swapping literal/length else 315 | - Swapping window/direct else 316 | - Larger unrolled copy loops (three is about right) 317 | - Moving len -= 3 statement into middle of loop 318 | */ 319 | 320 | #endif /* !ASMINF */ 321 | -------------------------------------------------------------------------------- /src/zlib/inffast.h: -------------------------------------------------------------------------------- 1 | /* inffast.h -- header to use inffast.c 2 | * Copyright (C) 1995-2003, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); 12 | -------------------------------------------------------------------------------- /src/zlib/inffixed.h: -------------------------------------------------------------------------------- 1 | /* inffixed.h -- table for decoding fixed codes 2 | * Generated automatically by makefixed(). 3 | */ 4 | 5 | /* WARNING: this file should *not* be used by applications. 6 | It is part of the implementation of this library and is 7 | subject to change. Applications should only use zlib.h. 8 | */ 9 | 10 | static const code lenfix[512] = { 11 | {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, 12 | {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, 13 | {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, 14 | {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, 15 | {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, 16 | {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, 17 | {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, 18 | {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, 19 | {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, 20 | {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, 21 | {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, 22 | {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, 23 | {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, 24 | {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, 25 | {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, 26 | {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, 27 | {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, 28 | {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, 29 | {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, 30 | {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, 31 | {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, 32 | {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, 33 | {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, 34 | {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, 35 | {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, 36 | {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, 37 | {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, 38 | {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, 39 | {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, 40 | {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, 41 | {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, 42 | {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, 43 | {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, 44 | {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, 45 | {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, 46 | {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, 47 | {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, 48 | {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, 49 | {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, 50 | {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, 51 | {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, 52 | {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, 53 | {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, 54 | {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, 55 | {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, 56 | {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, 57 | {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, 58 | {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, 59 | {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, 60 | {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, 61 | {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, 62 | {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, 63 | {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, 64 | {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, 65 | {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, 66 | {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, 67 | {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, 68 | {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, 69 | {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, 70 | {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, 71 | {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, 72 | {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, 73 | {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, 74 | {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, 75 | {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, 76 | {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, 77 | {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, 78 | {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, 79 | {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, 80 | {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, 81 | {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, 82 | {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, 83 | {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, 84 | {0,9,255} 85 | }; 86 | 87 | static const code distfix[32] = { 88 | {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, 89 | {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, 90 | {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, 91 | {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, 92 | {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, 93 | {22,5,193},{64,5,0} 94 | }; 95 | -------------------------------------------------------------------------------- /src/zlib/inflate.h: -------------------------------------------------------------------------------- 1 | /* inflate.h -- internal inflate state definition 2 | * Copyright (C) 1995-2019 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* define NO_GZIP when compiling if you want to disable gzip header and 12 | trailer decoding by inflate(). NO_GZIP would be used to avoid linking in 13 | the crc code when it is not needed. For shared libraries, gzip decoding 14 | should be left enabled. */ 15 | #ifndef NO_GZIP 16 | # define GUNZIP 17 | #endif 18 | 19 | /* Possible inflate modes between inflate() calls */ 20 | typedef enum { 21 | HEAD = 16180, /* i: waiting for magic header */ 22 | FLAGS, /* i: waiting for method and flags (gzip) */ 23 | TIME, /* i: waiting for modification time (gzip) */ 24 | OS, /* i: waiting for extra flags and operating system (gzip) */ 25 | EXLEN, /* i: waiting for extra length (gzip) */ 26 | EXTRA, /* i: waiting for extra bytes (gzip) */ 27 | NAME, /* i: waiting for end of file name (gzip) */ 28 | COMMENT, /* i: waiting for end of comment (gzip) */ 29 | HCRC, /* i: waiting for header crc (gzip) */ 30 | DICTID, /* i: waiting for dictionary check value */ 31 | DICT, /* waiting for inflateSetDictionary() call */ 32 | TYPE, /* i: waiting for type bits, including last-flag bit */ 33 | TYPEDO, /* i: same, but skip check to exit inflate on new block */ 34 | STORED, /* i: waiting for stored size (length and complement) */ 35 | COPY_, /* i/o: same as COPY below, but only first time in */ 36 | COPY, /* i/o: waiting for input or output to copy stored block */ 37 | TABLE, /* i: waiting for dynamic block table lengths */ 38 | LENLENS, /* i: waiting for code length code lengths */ 39 | CODELENS, /* i: waiting for length/lit and distance code lengths */ 40 | LEN_, /* i: same as LEN below, but only first time in */ 41 | LEN, /* i: waiting for length/lit/eob code */ 42 | LENEXT, /* i: waiting for length extra bits */ 43 | DIST, /* i: waiting for distance code */ 44 | DISTEXT, /* i: waiting for distance extra bits */ 45 | MATCH, /* o: waiting for output space to copy string */ 46 | LIT, /* o: waiting for output space to write literal */ 47 | CHECK, /* i: waiting for 32-bit check value */ 48 | LENGTH, /* i: waiting for 32-bit length (gzip) */ 49 | DONE, /* finished check, done -- remain here until reset */ 50 | BAD, /* got a data error -- remain here until reset */ 51 | MEM, /* got an inflate() memory error -- remain here until reset */ 52 | SYNC /* looking for synchronization bytes to restart inflate() */ 53 | } inflate_mode; 54 | 55 | /* 56 | State transitions between above modes - 57 | 58 | (most modes can go to BAD or MEM on error -- not shown for clarity) 59 | 60 | Process header: 61 | HEAD -> (gzip) or (zlib) or (raw) 62 | (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> 63 | HCRC -> TYPE 64 | (zlib) -> DICTID or TYPE 65 | DICTID -> DICT -> TYPE 66 | (raw) -> TYPEDO 67 | Read deflate blocks: 68 | TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK 69 | STORED -> COPY_ -> COPY -> TYPE 70 | TABLE -> LENLENS -> CODELENS -> LEN_ 71 | LEN_ -> LEN 72 | Read deflate codes in fixed or dynamic block: 73 | LEN -> LENEXT or LIT or TYPE 74 | LENEXT -> DIST -> DISTEXT -> MATCH -> LEN 75 | LIT -> LEN 76 | Process trailer: 77 | CHECK -> LENGTH -> DONE 78 | */ 79 | 80 | /* State maintained between inflate() calls -- approximately 7K bytes, not 81 | including the allocated sliding window, which is up to 32K bytes. */ 82 | struct inflate_state { 83 | z_streamp strm; /* pointer back to this zlib stream */ 84 | inflate_mode mode; /* current inflate mode */ 85 | int last; /* true if processing last block */ 86 | int wrap; /* bit 0 true for zlib, bit 1 true for gzip, 87 | bit 2 true to validate check value */ 88 | int havedict; /* true if dictionary provided */ 89 | int flags; /* gzip header method and flags, 0 if zlib, or 90 | -1 if raw or no header yet */ 91 | unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ 92 | unsigned long check; /* protected copy of check value */ 93 | unsigned long total; /* protected copy of output count */ 94 | gz_headerp head; /* where to save gzip header information */ 95 | /* sliding window */ 96 | unsigned wbits; /* log base 2 of requested window size */ 97 | unsigned wsize; /* window size or zero if not using window */ 98 | unsigned whave; /* valid bytes in the window */ 99 | unsigned wnext; /* window write index */ 100 | unsigned char FAR *window; /* allocated sliding window, if needed */ 101 | /* bit accumulator */ 102 | unsigned long hold; /* input bit accumulator */ 103 | unsigned bits; /* number of bits in "in" */ 104 | /* for string and stored block copying */ 105 | unsigned length; /* literal or length of data to copy */ 106 | unsigned offset; /* distance back to copy string from */ 107 | /* for table and code decoding */ 108 | unsigned extra; /* extra bits needed */ 109 | /* fixed and dynamic code tables */ 110 | code const FAR *lencode; /* starting table for length/literal codes */ 111 | code const FAR *distcode; /* starting table for distance codes */ 112 | unsigned lenbits; /* index bits for lencode */ 113 | unsigned distbits; /* index bits for distcode */ 114 | /* dynamic table building */ 115 | unsigned ncode; /* number of code length code lengths */ 116 | unsigned nlen; /* number of length code lengths */ 117 | unsigned ndist; /* number of distance code lengths */ 118 | unsigned have; /* number of code lengths in lens[] */ 119 | code FAR *next; /* next available space in codes[] */ 120 | unsigned short lens[320]; /* temporary storage for code lengths */ 121 | unsigned short work[288]; /* work area for code table building */ 122 | code codes[ENOUGH]; /* space for code tables */ 123 | int sane; /* if false, allow invalid distance too far */ 124 | int back; /* bits back of last unprocessed length/lit */ 125 | unsigned was; /* initial length of match */ 126 | }; 127 | -------------------------------------------------------------------------------- /src/zlib/inftrees.c: -------------------------------------------------------------------------------- 1 | /* inftrees.c -- generate Huffman trees for efficient decoding 2 | * Copyright (C) 1995-2024 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | #include "zutil.h" 7 | #include "inftrees.h" 8 | 9 | #define MAXBITS 15 10 | 11 | const char inflate_copyright[] = 12 | " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; 13 | /* 14 | If you use the zlib library in a product, an acknowledgment is welcome 15 | in the documentation of your product. If for some reason you cannot 16 | include such an acknowledgment, I would appreciate that you keep this 17 | copyright string in the executable of your product. 18 | */ 19 | 20 | /* 21 | Build a set of tables to decode the provided canonical Huffman code. 22 | The code lengths are lens[0..codes-1]. The result starts at *table, 23 | whose indices are 0..2^bits-1. work is a writable array of at least 24 | lens shorts, which is used as a work area. type is the type of code 25 | to be generated, CODES, LENS, or DISTS. On return, zero is success, 26 | -1 is an invalid code, and +1 means that ENOUGH isn't enough. table 27 | on return points to the next available entry's address. bits is the 28 | requested root table index bits, and on return it is the actual root 29 | table index bits. It will differ if the request is greater than the 30 | longest code or if it is less than the shortest code. 31 | */ 32 | int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 33 | unsigned codes, code FAR * FAR *table, 34 | unsigned FAR *bits, unsigned short FAR *work) { 35 | unsigned len; /* a code's length in bits */ 36 | unsigned sym; /* index of code symbols */ 37 | unsigned min, max; /* minimum and maximum code lengths */ 38 | unsigned root; /* number of index bits for root table */ 39 | unsigned curr; /* number of index bits for current table */ 40 | unsigned drop; /* code bits to drop for sub-table */ 41 | int left; /* number of prefix codes available */ 42 | unsigned used; /* code entries in table used */ 43 | unsigned huff; /* Huffman code */ 44 | unsigned incr; /* for incrementing code, index */ 45 | unsigned fill; /* index for replicating entries */ 46 | unsigned low; /* low bits for current root entry */ 47 | unsigned mask; /* mask for low root bits */ 48 | code here; /* table entry for duplication */ 49 | code FAR *next; /* next available space in table */ 50 | const unsigned short FAR *base; /* base value table to use */ 51 | const unsigned short FAR *extra; /* extra bits table to use */ 52 | unsigned match; /* use base and extra for symbol >= match */ 53 | unsigned short count[MAXBITS+1]; /* number of codes of each length */ 54 | unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ 55 | static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 56 | 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 57 | 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 58 | static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 59 | 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 60 | 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; 61 | static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 62 | 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 63 | 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 64 | 8193, 12289, 16385, 24577, 0, 0}; 65 | static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 66 | 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 67 | 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 68 | 28, 28, 29, 29, 64, 64}; 69 | 70 | /* 71 | Process a set of code lengths to create a canonical Huffman code. The 72 | code lengths are lens[0..codes-1]. Each length corresponds to the 73 | symbols 0..codes-1. The Huffman code is generated by first sorting the 74 | symbols by length from short to long, and retaining the symbol order 75 | for codes with equal lengths. Then the code starts with all zero bits 76 | for the first code of the shortest length, and the codes are integer 77 | increments for the same length, and zeros are appended as the length 78 | increases. For the deflate format, these bits are stored backwards 79 | from their more natural integer increment ordering, and so when the 80 | decoding tables are built in the large loop below, the integer codes 81 | are incremented backwards. 82 | 83 | This routine assumes, but does not check, that all of the entries in 84 | lens[] are in the range 0..MAXBITS. The caller must assure this. 85 | 1..MAXBITS is interpreted as that code length. zero means that that 86 | symbol does not occur in this code. 87 | 88 | The codes are sorted by computing a count of codes for each length, 89 | creating from that a table of starting indices for each length in the 90 | sorted table, and then entering the symbols in order in the sorted 91 | table. The sorted table is work[], with that space being provided by 92 | the caller. 93 | 94 | The length counts are used for other purposes as well, i.e. finding 95 | the minimum and maximum length codes, determining if there are any 96 | codes at all, checking for a valid set of lengths, and looking ahead 97 | at length counts to determine sub-table sizes when building the 98 | decoding tables. 99 | */ 100 | 101 | /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ 102 | for (len = 0; len <= MAXBITS; len++) 103 | count[len] = 0; 104 | for (sym = 0; sym < codes; sym++) 105 | count[lens[sym]]++; 106 | 107 | /* bound code lengths, force root to be within code lengths */ 108 | root = *bits; 109 | for (max = MAXBITS; max >= 1; max--) 110 | if (count[max] != 0) break; 111 | if (root > max) root = max; 112 | if (max == 0) { /* no symbols to code at all */ 113 | here.op = (unsigned char)64; /* invalid code marker */ 114 | here.bits = (unsigned char)1; 115 | here.val = (unsigned short)0; 116 | *(*table)++ = here; /* make a table to force an error */ 117 | *(*table)++ = here; 118 | *bits = 1; 119 | return 0; /* no symbols, but wait for decoding to report error */ 120 | } 121 | for (min = 1; min < max; min++) 122 | if (count[min] != 0) break; 123 | if (root < min) root = min; 124 | 125 | /* check for an over-subscribed or incomplete set of lengths */ 126 | left = 1; 127 | for (len = 1; len <= MAXBITS; len++) { 128 | left <<= 1; 129 | left -= count[len]; 130 | if (left < 0) return -1; /* over-subscribed */ 131 | } 132 | if (left > 0 && (type == CODES || max != 1)) 133 | return -1; /* incomplete set */ 134 | 135 | /* generate offsets into symbol table for each length for sorting */ 136 | offs[1] = 0; 137 | for (len = 1; len < MAXBITS; len++) 138 | offs[len + 1] = offs[len] + count[len]; 139 | 140 | /* sort symbols by length, by symbol order within each length */ 141 | for (sym = 0; sym < codes; sym++) 142 | if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; 143 | 144 | /* 145 | Create and fill in decoding tables. In this loop, the table being 146 | filled is at next and has curr index bits. The code being used is huff 147 | with length len. That code is converted to an index by dropping drop 148 | bits off of the bottom. For codes where len is less than drop + curr, 149 | those top drop + curr - len bits are incremented through all values to 150 | fill the table with replicated entries. 151 | 152 | root is the number of index bits for the root table. When len exceeds 153 | root, sub-tables are created pointed to by the root entry with an index 154 | of the low root bits of huff. This is saved in low to check for when a 155 | new sub-table should be started. drop is zero when the root table is 156 | being filled, and drop is root when sub-tables are being filled. 157 | 158 | When a new sub-table is needed, it is necessary to look ahead in the 159 | code lengths to determine what size sub-table is needed. The length 160 | counts are used for this, and so count[] is decremented as codes are 161 | entered in the tables. 162 | 163 | used keeps track of how many table entries have been allocated from the 164 | provided *table space. It is checked for LENS and DIST tables against 165 | the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in 166 | the initial root table size constants. See the comments in inftrees.h 167 | for more information. 168 | 169 | sym increments through all symbols, and the loop terminates when 170 | all codes of length max, i.e. all codes, have been processed. This 171 | routine permits incomplete codes, so another loop after this one fills 172 | in the rest of the decoding tables with invalid code markers. 173 | */ 174 | 175 | /* set up for code type */ 176 | switch (type) { 177 | case CODES: 178 | base = extra = work; /* dummy value--not used */ 179 | match = 20; 180 | break; 181 | case LENS: 182 | base = lbase; 183 | extra = lext; 184 | match = 257; 185 | break; 186 | default: /* DISTS */ 187 | base = dbase; 188 | extra = dext; 189 | match = 0; 190 | } 191 | 192 | /* initialize state for loop */ 193 | huff = 0; /* starting code */ 194 | sym = 0; /* starting code symbol */ 195 | len = min; /* starting code length */ 196 | next = *table; /* current table to fill in */ 197 | curr = root; /* current table index bits */ 198 | drop = 0; /* current bits to drop from code for index */ 199 | low = (unsigned)(-1); /* trigger new sub-table when len > root */ 200 | used = 1U << root; /* use root table entries */ 201 | mask = used - 1; /* mask for comparing low */ 202 | 203 | /* check available table space */ 204 | if ((type == LENS && used > ENOUGH_LENS) || 205 | (type == DISTS && used > ENOUGH_DISTS)) 206 | return 1; 207 | 208 | /* process all codes and make table entries */ 209 | for (;;) { 210 | /* create table entry */ 211 | here.bits = (unsigned char)(len - drop); 212 | if (work[sym] + 1U < match) { 213 | here.op = (unsigned char)0; 214 | here.val = work[sym]; 215 | } 216 | else if (work[sym] >= match) { 217 | here.op = (unsigned char)(extra[work[sym] - match]); 218 | here.val = base[work[sym] - match]; 219 | } 220 | else { 221 | here.op = (unsigned char)(32 + 64); /* end of block */ 222 | here.val = 0; 223 | } 224 | 225 | /* replicate for those indices with low len bits equal to huff */ 226 | incr = 1U << (len - drop); 227 | fill = 1U << curr; 228 | min = fill; /* save offset to next table */ 229 | do { 230 | fill -= incr; 231 | next[(huff >> drop) + fill] = here; 232 | } while (fill != 0); 233 | 234 | /* backwards increment the len-bit code huff */ 235 | incr = 1U << (len - 1); 236 | while (huff & incr) 237 | incr >>= 1; 238 | if (incr != 0) { 239 | huff &= incr - 1; 240 | huff += incr; 241 | } 242 | else 243 | huff = 0; 244 | 245 | /* go to next symbol, update count, len */ 246 | sym++; 247 | if (--(count[len]) == 0) { 248 | if (len == max) break; 249 | len = lens[work[sym]]; 250 | } 251 | 252 | /* create new sub-table if needed */ 253 | if (len > root && (huff & mask) != low) { 254 | /* if first time, transition to sub-tables */ 255 | if (drop == 0) 256 | drop = root; 257 | 258 | /* increment past last table */ 259 | next += min; /* here min is 1 << curr */ 260 | 261 | /* determine length of next table */ 262 | curr = len - drop; 263 | left = (int)(1 << curr); 264 | while (curr + drop < max) { 265 | left -= count[curr + drop]; 266 | if (left <= 0) break; 267 | curr++; 268 | left <<= 1; 269 | } 270 | 271 | /* check for enough space */ 272 | used += 1U << curr; 273 | if ((type == LENS && used > ENOUGH_LENS) || 274 | (type == DISTS && used > ENOUGH_DISTS)) 275 | return 1; 276 | 277 | /* point entry in root table to sub-table */ 278 | low = huff & mask; 279 | (*table)[low].op = (unsigned char)curr; 280 | (*table)[low].bits = (unsigned char)root; 281 | (*table)[low].val = (unsigned short)(next - *table); 282 | } 283 | } 284 | 285 | /* fill in remaining table entry if code is incomplete (guaranteed to have 286 | at most one remaining entry, since if the code is incomplete, the 287 | maximum code length that was allowed to get this far is one bit) */ 288 | if (huff != 0) { 289 | here.op = (unsigned char)64; /* invalid code marker */ 290 | here.bits = (unsigned char)(len - drop); 291 | here.val = (unsigned short)0; 292 | next[huff] = here; 293 | } 294 | 295 | /* set return parameters */ 296 | *table += used; 297 | *bits = root; 298 | return 0; 299 | } 300 | -------------------------------------------------------------------------------- /src/zlib/inftrees.h: -------------------------------------------------------------------------------- 1 | /* inftrees.h -- header to use inftrees.c 2 | * Copyright (C) 1995-2005, 2010 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* Structure for decoding tables. Each entry provides either the 12 | information needed to do the operation requested by the code that 13 | indexed that table entry, or it provides a pointer to another 14 | table that indexes more bits of the code. op indicates whether 15 | the entry is a pointer to another table, a literal, a length or 16 | distance, an end-of-block, or an invalid code. For a table 17 | pointer, the low four bits of op is the number of index bits of 18 | that table. For a length or distance, the low four bits of op 19 | is the number of extra bits to get after the code. bits is 20 | the number of bits in this code or part of the code to drop off 21 | of the bit buffer. val is the actual byte to output in the case 22 | of a literal, the base length or distance, or the offset from 23 | the current table to the next table. Each entry is four bytes. */ 24 | typedef struct { 25 | unsigned char op; /* operation, extra bits, table bits */ 26 | unsigned char bits; /* bits in this part of the code */ 27 | unsigned short val; /* offset in table or code value */ 28 | } code; 29 | 30 | /* op values as set by inflate_table(): 31 | 00000000 - literal 32 | 0000tttt - table link, tttt != 0 is the number of table index bits 33 | 0001eeee - length or distance, eeee is the number of extra bits 34 | 01100000 - end of block 35 | 01000000 - invalid code 36 | */ 37 | 38 | /* Maximum size of the dynamic table. The maximum number of code structures is 39 | 1444, which is the sum of 852 for literal/length codes and 592 for distance 40 | codes. These values were found by exhaustive searches using the program 41 | examples/enough.c found in the zlib distribution. The arguments to that 42 | program are the number of symbols, the initial root table size, and the 43 | maximum bit length of a code. "enough 286 9 15" for literal/length codes 44 | returns 852, and "enough 30 6 15" for distance codes returns 592. The 45 | initial root table size (9 or 6) is found in the fifth argument of the 46 | inflate_table() calls in inflate.c and infback.c. If the root table size is 47 | changed, then these maximum sizes would be need to be recalculated and 48 | updated. */ 49 | #define ENOUGH_LENS 852 50 | #define ENOUGH_DISTS 592 51 | #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) 52 | 53 | /* Type of code to build for inflate_table() */ 54 | typedef enum { 55 | CODES, 56 | LENS, 57 | DISTS 58 | } codetype; 59 | 60 | int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 61 | unsigned codes, code FAR * FAR *table, 62 | unsigned FAR *bits, unsigned short FAR *work); 63 | -------------------------------------------------------------------------------- /src/zlib/trees.h: -------------------------------------------------------------------------------- 1 | /* header created automatically with -DGEN_TREES_H */ 2 | 3 | local const ct_data static_ltree[L_CODES+2] = { 4 | {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, 5 | {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, 6 | {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, 7 | {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, 8 | {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, 9 | {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, 10 | {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, 11 | {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, 12 | {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, 13 | {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, 14 | {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, 15 | {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, 16 | {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, 17 | {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, 18 | {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, 19 | {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, 20 | {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, 21 | {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, 22 | {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, 23 | {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, 24 | {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, 25 | {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, 26 | {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, 27 | {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, 28 | {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, 29 | {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, 30 | {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, 31 | {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, 32 | {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, 33 | {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, 34 | {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, 35 | {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, 36 | {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, 37 | {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, 38 | {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, 39 | {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, 40 | {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, 41 | {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, 42 | {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, 43 | {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, 44 | {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, 45 | {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, 46 | {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, 47 | {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, 48 | {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, 49 | {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, 50 | {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, 51 | {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, 52 | {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, 53 | {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, 54 | {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, 55 | {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, 56 | {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, 57 | {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, 58 | {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, 59 | {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, 60 | {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, 61 | {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} 62 | }; 63 | 64 | local const ct_data static_dtree[D_CODES] = { 65 | {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, 66 | {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, 67 | {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, 68 | {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, 69 | {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, 70 | {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} 71 | }; 72 | 73 | const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 74 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 75 | 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 76 | 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 77 | 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 78 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 79 | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 80 | 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 81 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 82 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 84 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 87 | 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 88 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 89 | 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 90 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 91 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 92 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 93 | 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 94 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 95 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 96 | 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 97 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 98 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 99 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 100 | }; 101 | 102 | const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 103 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 104 | 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 105 | 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 106 | 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 107 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 108 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 109 | 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 110 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 111 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 112 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 113 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 114 | 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 115 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 116 | }; 117 | 118 | local const int base_length[LENGTH_CODES] = { 119 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 120 | 64, 80, 96, 112, 128, 160, 192, 224, 0 121 | }; 122 | 123 | local const int base_dist[D_CODES] = { 124 | 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 125 | 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 126 | 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 127 | }; 128 | 129 | -------------------------------------------------------------------------------- /src/zlib/uncompr.c: -------------------------------------------------------------------------------- 1 | /* uncompr.c -- decompress a memory buffer 2 | * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Decompresses the source buffer into the destination buffer. *sourceLen is 13 | the byte length of the source buffer. Upon entry, *destLen is the total size 14 | of the destination buffer, which must be large enough to hold the entire 15 | uncompressed data. (The size of the uncompressed data must have been saved 16 | previously by the compressor and transmitted to the decompressor by some 17 | mechanism outside the scope of this compression library.) Upon exit, 18 | *destLen is the size of the decompressed data and *sourceLen is the number 19 | of source bytes consumed. Upon return, source + *sourceLen points to the 20 | first unused input byte. 21 | 22 | uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough 23 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, or 24 | Z_DATA_ERROR if the input data was corrupted, including if the input data is 25 | an incomplete zlib stream. 26 | */ 27 | int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, 28 | uLong *sourceLen) { 29 | z_stream stream; 30 | int err; 31 | const uInt max = (uInt)-1; 32 | uLong len, left; 33 | Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ 34 | 35 | len = *sourceLen; 36 | if (*destLen) { 37 | left = *destLen; 38 | *destLen = 0; 39 | } 40 | else { 41 | left = 1; 42 | dest = buf; 43 | } 44 | 45 | stream.next_in = (z_const Bytef *)source; 46 | stream.avail_in = 0; 47 | stream.zalloc = (alloc_func)0; 48 | stream.zfree = (free_func)0; 49 | stream.opaque = (voidpf)0; 50 | 51 | err = inflateInit(&stream); 52 | if (err != Z_OK) return err; 53 | 54 | stream.next_out = dest; 55 | stream.avail_out = 0; 56 | 57 | do { 58 | if (stream.avail_out == 0) { 59 | stream.avail_out = left > (uLong)max ? max : (uInt)left; 60 | left -= stream.avail_out; 61 | } 62 | if (stream.avail_in == 0) { 63 | stream.avail_in = len > (uLong)max ? max : (uInt)len; 64 | len -= stream.avail_in; 65 | } 66 | err = inflate(&stream, Z_NO_FLUSH); 67 | } while (err == Z_OK); 68 | 69 | *sourceLen -= len + stream.avail_in; 70 | if (dest != buf) 71 | *destLen = stream.total_out; 72 | else if (stream.total_out && err == Z_BUF_ERROR) 73 | left = 1; 74 | 75 | inflateEnd(&stream); 76 | return err == Z_STREAM_END ? Z_OK : 77 | err == Z_NEED_DICT ? Z_DATA_ERROR : 78 | err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : 79 | err; 80 | } 81 | 82 | int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, 83 | uLong sourceLen) { 84 | return uncompress2(dest, destLen, source, &sourceLen); 85 | } 86 | -------------------------------------------------------------------------------- /src/zlib/zconf.h: -------------------------------------------------------------------------------- 1 | /* zconf.h -- configuration of the zlib compression library 2 | * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #ifndef ZCONF_H 9 | #define ZCONF_H 10 | 11 | /* 12 | * If you *really* need a unique prefix for all types and library functions, 13 | * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. 14 | * Even better than compiling with -DZ_PREFIX would be to use configure to set 15 | * this permanently in zconf.h using "./configure --zprefix". 16 | */ 17 | #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ 18 | # define Z_PREFIX_SET 19 | 20 | /* all linked symbols and init macros */ 21 | # define _dist_code z__dist_code 22 | # define _length_code z__length_code 23 | # define _tr_align z__tr_align 24 | # define _tr_flush_bits z__tr_flush_bits 25 | # define _tr_flush_block z__tr_flush_block 26 | # define _tr_init z__tr_init 27 | # define _tr_stored_block z__tr_stored_block 28 | # define _tr_tally z__tr_tally 29 | # define adler32 z_adler32 30 | # define adler32_combine z_adler32_combine 31 | # define adler32_combine64 z_adler32_combine64 32 | # define adler32_z z_adler32_z 33 | # ifndef Z_SOLO 34 | # define compress z_compress 35 | # define compress2 z_compress2 36 | # define compressBound z_compressBound 37 | # endif 38 | # define crc32 z_crc32 39 | # define crc32_combine z_crc32_combine 40 | # define crc32_combine64 z_crc32_combine64 41 | # define crc32_combine_gen z_crc32_combine_gen 42 | # define crc32_combine_gen64 z_crc32_combine_gen64 43 | # define crc32_combine_op z_crc32_combine_op 44 | # define crc32_z z_crc32_z 45 | # define deflate z_deflate 46 | # define deflateBound z_deflateBound 47 | # define deflateCopy z_deflateCopy 48 | # define deflateEnd z_deflateEnd 49 | # define deflateGetDictionary z_deflateGetDictionary 50 | # define deflateInit z_deflateInit 51 | # define deflateInit2 z_deflateInit2 52 | # define deflateInit2_ z_deflateInit2_ 53 | # define deflateInit_ z_deflateInit_ 54 | # define deflateParams z_deflateParams 55 | # define deflatePending z_deflatePending 56 | # define deflatePrime z_deflatePrime 57 | # define deflateReset z_deflateReset 58 | # define deflateResetKeep z_deflateResetKeep 59 | # define deflateSetDictionary z_deflateSetDictionary 60 | # define deflateSetHeader z_deflateSetHeader 61 | # define deflateTune z_deflateTune 62 | # define deflate_copyright z_deflate_copyright 63 | # define get_crc_table z_get_crc_table 64 | # ifndef Z_SOLO 65 | # define gz_error z_gz_error 66 | # define gz_intmax z_gz_intmax 67 | # define gz_strwinerror z_gz_strwinerror 68 | # define gzbuffer z_gzbuffer 69 | # define gzclearerr z_gzclearerr 70 | # define gzclose z_gzclose 71 | # define gzclose_r z_gzclose_r 72 | # define gzclose_w z_gzclose_w 73 | # define gzdirect z_gzdirect 74 | # define gzdopen z_gzdopen 75 | # define gzeof z_gzeof 76 | # define gzerror z_gzerror 77 | # define gzflush z_gzflush 78 | # define gzfread z_gzfread 79 | # define gzfwrite z_gzfwrite 80 | # define gzgetc z_gzgetc 81 | # define gzgetc_ z_gzgetc_ 82 | # define gzgets z_gzgets 83 | # define gzoffset z_gzoffset 84 | # define gzoffset64 z_gzoffset64 85 | # define gzopen z_gzopen 86 | # define gzopen64 z_gzopen64 87 | # ifdef _WIN32 88 | # define gzopen_w z_gzopen_w 89 | # endif 90 | # define gzprintf z_gzprintf 91 | # define gzputc z_gzputc 92 | # define gzputs z_gzputs 93 | # define gzread z_gzread 94 | # define gzrewind z_gzrewind 95 | # define gzseek z_gzseek 96 | # define gzseek64 z_gzseek64 97 | # define gzsetparams z_gzsetparams 98 | # define gztell z_gztell 99 | # define gztell64 z_gztell64 100 | # define gzungetc z_gzungetc 101 | # define gzvprintf z_gzvprintf 102 | # define gzwrite z_gzwrite 103 | # endif 104 | # define inflate z_inflate 105 | # define inflateBack z_inflateBack 106 | # define inflateBackEnd z_inflateBackEnd 107 | # define inflateBackInit z_inflateBackInit 108 | # define inflateBackInit_ z_inflateBackInit_ 109 | # define inflateCodesUsed z_inflateCodesUsed 110 | # define inflateCopy z_inflateCopy 111 | # define inflateEnd z_inflateEnd 112 | # define inflateGetDictionary z_inflateGetDictionary 113 | # define inflateGetHeader z_inflateGetHeader 114 | # define inflateInit z_inflateInit 115 | # define inflateInit2 z_inflateInit2 116 | # define inflateInit2_ z_inflateInit2_ 117 | # define inflateInit_ z_inflateInit_ 118 | # define inflateMark z_inflateMark 119 | # define inflatePrime z_inflatePrime 120 | # define inflateReset z_inflateReset 121 | # define inflateReset2 z_inflateReset2 122 | # define inflateResetKeep z_inflateResetKeep 123 | # define inflateSetDictionary z_inflateSetDictionary 124 | # define inflateSync z_inflateSync 125 | # define inflateSyncPoint z_inflateSyncPoint 126 | # define inflateUndermine z_inflateUndermine 127 | # define inflateValidate z_inflateValidate 128 | # define inflate_copyright z_inflate_copyright 129 | # define inflate_fast z_inflate_fast 130 | # define inflate_table z_inflate_table 131 | # ifndef Z_SOLO 132 | # define uncompress z_uncompress 133 | # define uncompress2 z_uncompress2 134 | # endif 135 | # define zError z_zError 136 | # ifndef Z_SOLO 137 | # define zcalloc z_zcalloc 138 | # define zcfree z_zcfree 139 | # endif 140 | # define zlibCompileFlags z_zlibCompileFlags 141 | # define zlibVersion z_zlibVersion 142 | 143 | /* all zlib typedefs in zlib.h and zconf.h */ 144 | # define Byte z_Byte 145 | # define Bytef z_Bytef 146 | # define alloc_func z_alloc_func 147 | # define charf z_charf 148 | # define free_func z_free_func 149 | # ifndef Z_SOLO 150 | # define gzFile z_gzFile 151 | # endif 152 | # define gz_header z_gz_header 153 | # define gz_headerp z_gz_headerp 154 | # define in_func z_in_func 155 | # define intf z_intf 156 | # define out_func z_out_func 157 | # define uInt z_uInt 158 | # define uIntf z_uIntf 159 | # define uLong z_uLong 160 | # define uLongf z_uLongf 161 | # define voidp z_voidp 162 | # define voidpc z_voidpc 163 | # define voidpf z_voidpf 164 | 165 | /* all zlib structs in zlib.h and zconf.h */ 166 | # define gz_header_s z_gz_header_s 167 | # define internal_state z_internal_state 168 | 169 | #endif 170 | 171 | #if defined(__MSDOS__) && !defined(MSDOS) 172 | # define MSDOS 173 | #endif 174 | #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) 175 | # define OS2 176 | #endif 177 | #if defined(_WINDOWS) && !defined(WINDOWS) 178 | # define WINDOWS 179 | #endif 180 | #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) 181 | # ifndef WIN32 182 | # define WIN32 183 | # endif 184 | #endif 185 | #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) 186 | # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) 187 | # ifndef SYS16BIT 188 | # define SYS16BIT 189 | # endif 190 | # endif 191 | #endif 192 | 193 | /* 194 | * Compile with -DMAXSEG_64K if the alloc function cannot allocate more 195 | * than 64k bytes at a time (needed on systems with 16-bit int). 196 | */ 197 | #ifdef SYS16BIT 198 | # define MAXSEG_64K 199 | #endif 200 | #ifdef MSDOS 201 | # define UNALIGNED_OK 202 | #endif 203 | 204 | #ifdef __STDC_VERSION__ 205 | # ifndef STDC 206 | # define STDC 207 | # endif 208 | # if __STDC_VERSION__ >= 199901L 209 | # ifndef STDC99 210 | # define STDC99 211 | # endif 212 | # endif 213 | #endif 214 | #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) 215 | # define STDC 216 | #endif 217 | #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) 218 | # define STDC 219 | #endif 220 | #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) 221 | # define STDC 222 | #endif 223 | #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) 224 | # define STDC 225 | #endif 226 | 227 | #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ 228 | # define STDC 229 | #endif 230 | 231 | #ifndef STDC 232 | # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ 233 | # define const /* note: need a more gentle solution here */ 234 | # endif 235 | #endif 236 | 237 | #if defined(ZLIB_CONST) && !defined(z_const) 238 | # define z_const const 239 | #else 240 | # define z_const 241 | #endif 242 | 243 | #ifdef Z_SOLO 244 | # ifdef _WIN64 245 | typedef unsigned long long z_size_t; 246 | # else 247 | typedef unsigned long z_size_t; 248 | # endif 249 | #else 250 | # define z_longlong long long 251 | # if defined(NO_SIZE_T) 252 | typedef unsigned NO_SIZE_T z_size_t; 253 | # elif defined(STDC) 254 | # include 255 | typedef size_t z_size_t; 256 | # else 257 | typedef unsigned long z_size_t; 258 | # endif 259 | # undef z_longlong 260 | #endif 261 | 262 | /* Maximum value for memLevel in deflateInit2 */ 263 | #ifndef MAX_MEM_LEVEL 264 | # ifdef MAXSEG_64K 265 | # define MAX_MEM_LEVEL 8 266 | # else 267 | # define MAX_MEM_LEVEL 9 268 | # endif 269 | #endif 270 | 271 | /* Maximum value for windowBits in deflateInit2 and inflateInit2. 272 | * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files 273 | * created by gzip. (Files created by minigzip can still be extracted by 274 | * gzip.) 275 | */ 276 | #ifndef MAX_WBITS 277 | # define MAX_WBITS 15 /* 32K LZ77 window */ 278 | #endif 279 | 280 | /* The memory requirements for deflate are (in bytes): 281 | (1 << (windowBits+2)) + (1 << (memLevel+9)) 282 | that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) 283 | plus a few kilobytes for small objects. For example, if you want to reduce 284 | the default memory requirements from 256K to 128K, compile with 285 | make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" 286 | Of course this will generally degrade compression (there's no free lunch). 287 | 288 | The memory requirements for inflate are (in bytes) 1 << windowBits 289 | that is, 32K for windowBits=15 (default value) plus about 7 kilobytes 290 | for small objects. 291 | */ 292 | 293 | /* Type declarations */ 294 | 295 | #ifndef OF /* function prototypes */ 296 | # ifdef STDC 297 | # define OF(args) args 298 | # else 299 | # define OF(args) () 300 | # endif 301 | #endif 302 | 303 | /* The following definitions for FAR are needed only for MSDOS mixed 304 | * model programming (small or medium model with some far allocations). 305 | * This was tested only with MSC; for other MSDOS compilers you may have 306 | * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, 307 | * just define FAR to be empty. 308 | */ 309 | #ifdef SYS16BIT 310 | # if defined(M_I86SM) || defined(M_I86MM) 311 | /* MSC small or medium model */ 312 | # define SMALL_MEDIUM 313 | # ifdef _MSC_VER 314 | # define FAR _far 315 | # else 316 | # define FAR far 317 | # endif 318 | # endif 319 | # if (defined(__SMALL__) || defined(__MEDIUM__)) 320 | /* Turbo C small or medium model */ 321 | # define SMALL_MEDIUM 322 | # ifdef __BORLANDC__ 323 | # define FAR _far 324 | # else 325 | # define FAR far 326 | # endif 327 | # endif 328 | #endif 329 | 330 | #if defined(WINDOWS) || defined(WIN32) 331 | /* If building or using zlib as a DLL, define ZLIB_DLL. 332 | * This is not mandatory, but it offers a little performance increase. 333 | */ 334 | # ifdef ZLIB_DLL 335 | # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) 336 | # ifdef ZLIB_INTERNAL 337 | # define ZEXTERN extern __declspec(dllexport) 338 | # else 339 | # define ZEXTERN extern __declspec(dllimport) 340 | # endif 341 | # endif 342 | # endif /* ZLIB_DLL */ 343 | /* If building or using zlib with the WINAPI/WINAPIV calling convention, 344 | * define ZLIB_WINAPI. 345 | * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. 346 | */ 347 | # ifdef ZLIB_WINAPI 348 | # ifdef FAR 349 | # undef FAR 350 | # endif 351 | # ifndef WIN32_LEAN_AND_MEAN 352 | # define WIN32_LEAN_AND_MEAN 353 | # endif 354 | # include 355 | /* No need for _export, use ZLIB.DEF instead. */ 356 | /* For complete Windows compatibility, use WINAPI, not __stdcall. */ 357 | # define ZEXPORT WINAPI 358 | # ifdef WIN32 359 | # define ZEXPORTVA WINAPIV 360 | # else 361 | # define ZEXPORTVA FAR CDECL 362 | # endif 363 | # endif 364 | #endif 365 | 366 | #if defined (__BEOS__) 367 | # ifdef ZLIB_DLL 368 | # ifdef ZLIB_INTERNAL 369 | # define ZEXPORT __declspec(dllexport) 370 | # define ZEXPORTVA __declspec(dllexport) 371 | # else 372 | # define ZEXPORT __declspec(dllimport) 373 | # define ZEXPORTVA __declspec(dllimport) 374 | # endif 375 | # endif 376 | #endif 377 | 378 | #ifndef ZEXTERN 379 | # define ZEXTERN extern 380 | #endif 381 | #ifndef ZEXPORT 382 | # define ZEXPORT 383 | #endif 384 | #ifndef ZEXPORTVA 385 | # define ZEXPORTVA 386 | #endif 387 | 388 | #ifndef FAR 389 | # define FAR 390 | #endif 391 | 392 | #if !defined(__MACTYPES__) 393 | typedef unsigned char Byte; /* 8 bits */ 394 | #endif 395 | typedef unsigned int uInt; /* 16 bits or more */ 396 | typedef unsigned long uLong; /* 32 bits or more */ 397 | 398 | #ifdef SMALL_MEDIUM 399 | /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ 400 | # define Bytef Byte FAR 401 | #else 402 | typedef Byte FAR Bytef; 403 | #endif 404 | typedef char FAR charf; 405 | typedef int FAR intf; 406 | typedef uInt FAR uIntf; 407 | typedef uLong FAR uLongf; 408 | 409 | #ifdef STDC 410 | typedef void const *voidpc; 411 | typedef void FAR *voidpf; 412 | typedef void *voidp; 413 | #else 414 | typedef Byte const *voidpc; 415 | typedef Byte FAR *voidpf; 416 | typedef Byte *voidp; 417 | #endif 418 | 419 | #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) 420 | # include 421 | # if (UINT_MAX == 0xffffffffUL) 422 | # define Z_U4 unsigned 423 | # elif (ULONG_MAX == 0xffffffffUL) 424 | # define Z_U4 unsigned long 425 | # elif (USHRT_MAX == 0xffffffffUL) 426 | # define Z_U4 unsigned short 427 | # endif 428 | #endif 429 | 430 | #ifdef Z_U4 431 | typedef Z_U4 z_crc_t; 432 | #else 433 | typedef unsigned long z_crc_t; 434 | #endif 435 | 436 | #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ 437 | # define Z_HAVE_UNISTD_H 438 | #endif 439 | 440 | #ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ 441 | # define Z_HAVE_STDARG_H 442 | #endif 443 | 444 | #ifdef STDC 445 | # ifndef Z_SOLO 446 | # include /* for off_t */ 447 | # endif 448 | #endif 449 | 450 | #if defined(STDC) || defined(Z_HAVE_STDARG_H) 451 | # ifndef Z_SOLO 452 | # include /* for va_list */ 453 | # endif 454 | #endif 455 | 456 | #ifdef _WIN32 457 | # ifndef Z_SOLO 458 | # include /* for wchar_t */ 459 | # endif 460 | #endif 461 | 462 | /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and 463 | * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even 464 | * though the former does not conform to the LFS document), but considering 465 | * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as 466 | * equivalently requesting no 64-bit operations 467 | */ 468 | #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 469 | # undef _LARGEFILE64_SOURCE 470 | #endif 471 | 472 | #ifndef Z_HAVE_UNISTD_H 473 | # ifdef __WATCOMC__ 474 | # define Z_HAVE_UNISTD_H 475 | # endif 476 | #endif 477 | #ifndef Z_HAVE_UNISTD_H 478 | # if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) 479 | # define Z_HAVE_UNISTD_H 480 | # endif 481 | #endif 482 | #ifndef Z_SOLO 483 | # if defined(Z_HAVE_UNISTD_H) 484 | # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ 485 | # ifdef VMS 486 | # include /* for off_t */ 487 | # endif 488 | # ifndef z_off_t 489 | # define z_off_t off_t 490 | # endif 491 | # endif 492 | #endif 493 | 494 | #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 495 | # define Z_LFS64 496 | #endif 497 | 498 | #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) 499 | # define Z_LARGE64 500 | #endif 501 | 502 | #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) 503 | # define Z_WANT64 504 | #endif 505 | 506 | #if !defined(SEEK_SET) && !defined(Z_SOLO) 507 | # define SEEK_SET 0 /* Seek from beginning of file. */ 508 | # define SEEK_CUR 1 /* Seek from current position. */ 509 | # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ 510 | #endif 511 | 512 | #ifndef z_off_t 513 | # define z_off_t long 514 | #endif 515 | 516 | #if !defined(_WIN32) && defined(Z_LARGE64) 517 | # define z_off64_t off64_t 518 | #else 519 | # if defined(_WIN32) && !defined(__GNUC__) 520 | # define z_off64_t __int64 521 | # else 522 | # define z_off64_t z_off_t 523 | # endif 524 | #endif 525 | 526 | /* MVS linker does not support external names larger than 8 bytes */ 527 | #if defined(__MVS__) 528 | #pragma map(deflateInit_,"DEIN") 529 | #pragma map(deflateInit2_,"DEIN2") 530 | #pragma map(deflateEnd,"DEEND") 531 | #pragma map(deflateBound,"DEBND") 532 | #pragma map(inflateInit_,"ININ") 533 | #pragma map(inflateInit2_,"ININ2") 534 | #pragma map(inflateEnd,"INEND") 535 | #pragma map(inflateSync,"INSY") 536 | #pragma map(inflateSetDictionary,"INSEDI") 537 | #pragma map(compressBound,"CMBND") 538 | #pragma map(inflate_table,"INTABL") 539 | #pragma map(inflate_fast,"INFA") 540 | #pragma map(inflate_copyright,"INCOPY") 541 | #endif 542 | 543 | #endif /* ZCONF_H */ 544 | -------------------------------------------------------------------------------- /src/zlib/zutil.c: -------------------------------------------------------------------------------- 1 | /* zutil.c -- target dependent utility functions for the compression library 2 | * Copyright (C) 1995-2017 Jean-loup Gailly 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #include "zutil.h" 9 | #ifndef Z_SOLO 10 | # include "gzguts.h" 11 | #endif 12 | 13 | z_const char * const z_errmsg[10] = { 14 | (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ 15 | (z_const char *)"stream end", /* Z_STREAM_END 1 */ 16 | (z_const char *)"", /* Z_OK 0 */ 17 | (z_const char *)"file error", /* Z_ERRNO (-1) */ 18 | (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ 19 | (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ 20 | (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ 21 | (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ 22 | (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ 23 | (z_const char *)"" 24 | }; 25 | 26 | 27 | const char * ZEXPORT zlibVersion(void) { 28 | return ZLIB_VERSION; 29 | } 30 | 31 | uLong ZEXPORT zlibCompileFlags(void) { 32 | uLong flags; 33 | 34 | flags = 0; 35 | switch ((int)(sizeof(uInt))) { 36 | case 2: break; 37 | case 4: flags += 1; break; 38 | case 8: flags += 2; break; 39 | default: flags += 3; 40 | } 41 | switch ((int)(sizeof(uLong))) { 42 | case 2: break; 43 | case 4: flags += 1 << 2; break; 44 | case 8: flags += 2 << 2; break; 45 | default: flags += 3 << 2; 46 | } 47 | switch ((int)(sizeof(voidpf))) { 48 | case 2: break; 49 | case 4: flags += 1 << 4; break; 50 | case 8: flags += 2 << 4; break; 51 | default: flags += 3 << 4; 52 | } 53 | switch ((int)(sizeof(z_off_t))) { 54 | case 2: break; 55 | case 4: flags += 1 << 6; break; 56 | case 8: flags += 2 << 6; break; 57 | default: flags += 3 << 6; 58 | } 59 | #ifdef ZLIB_DEBUG 60 | flags += 1 << 8; 61 | #endif 62 | /* 63 | #if defined(ASMV) || defined(ASMINF) 64 | flags += 1 << 9; 65 | #endif 66 | */ 67 | #ifdef ZLIB_WINAPI 68 | flags += 1 << 10; 69 | #endif 70 | #ifdef BUILDFIXED 71 | flags += 1 << 12; 72 | #endif 73 | #ifdef DYNAMIC_CRC_TABLE 74 | flags += 1 << 13; 75 | #endif 76 | #ifdef NO_GZCOMPRESS 77 | flags += 1L << 16; 78 | #endif 79 | #ifdef NO_GZIP 80 | flags += 1L << 17; 81 | #endif 82 | #ifdef PKZIP_BUG_WORKAROUND 83 | flags += 1L << 20; 84 | #endif 85 | #ifdef FASTEST 86 | flags += 1L << 21; 87 | #endif 88 | #if defined(STDC) || defined(Z_HAVE_STDARG_H) 89 | # ifdef NO_vsnprintf 90 | flags += 1L << 25; 91 | # ifdef HAS_vsprintf_void 92 | flags += 1L << 26; 93 | # endif 94 | # else 95 | # ifdef HAS_vsnprintf_void 96 | flags += 1L << 26; 97 | # endif 98 | # endif 99 | #else 100 | flags += 1L << 24; 101 | # ifdef NO_snprintf 102 | flags += 1L << 25; 103 | # ifdef HAS_sprintf_void 104 | flags += 1L << 26; 105 | # endif 106 | # else 107 | # ifdef HAS_snprintf_void 108 | flags += 1L << 26; 109 | # endif 110 | # endif 111 | #endif 112 | return flags; 113 | } 114 | 115 | #ifdef ZLIB_DEBUG 116 | #include 117 | # ifndef verbose 118 | # define verbose 0 119 | # endif 120 | int ZLIB_INTERNAL z_verbose = verbose; 121 | 122 | void ZLIB_INTERNAL z_error(char *m) { 123 | fprintf(stderr, "%s\n", m); 124 | exit(1); 125 | } 126 | #endif 127 | 128 | /* exported to allow conversion of error code to string for compress() and 129 | * uncompress() 130 | */ 131 | const char * ZEXPORT zError(int err) { 132 | return ERR_MSG(err); 133 | } 134 | 135 | #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 136 | /* The older Microsoft C Run-Time Library for Windows CE doesn't have 137 | * errno. We define it as a global variable to simplify porting. 138 | * Its value is always 0 and should not be used. 139 | */ 140 | int errno = 0; 141 | #endif 142 | 143 | #ifndef HAVE_MEMCPY 144 | 145 | void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { 146 | if (len == 0) return; 147 | do { 148 | *dest++ = *source++; /* ??? to be unrolled */ 149 | } while (--len != 0); 150 | } 151 | 152 | int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { 153 | uInt j; 154 | 155 | for (j = 0; j < len; j++) { 156 | if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; 157 | } 158 | return 0; 159 | } 160 | 161 | void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { 162 | if (len == 0) return; 163 | do { 164 | *dest++ = 0; /* ??? to be unrolled */ 165 | } while (--len != 0); 166 | } 167 | #endif 168 | 169 | #ifndef Z_SOLO 170 | 171 | #ifdef SYS16BIT 172 | 173 | #ifdef __TURBOC__ 174 | /* Turbo C in 16-bit mode */ 175 | 176 | # define MY_ZCALLOC 177 | 178 | /* Turbo C malloc() does not allow dynamic allocation of 64K bytes 179 | * and farmalloc(64K) returns a pointer with an offset of 8, so we 180 | * must fix the pointer. Warning: the pointer must be put back to its 181 | * original form in order to free it, use zcfree(). 182 | */ 183 | 184 | #define MAX_PTR 10 185 | /* 10*64K = 640K */ 186 | 187 | local int next_ptr = 0; 188 | 189 | typedef struct ptr_table_s { 190 | voidpf org_ptr; 191 | voidpf new_ptr; 192 | } ptr_table; 193 | 194 | local ptr_table table[MAX_PTR]; 195 | /* This table is used to remember the original form of pointers 196 | * to large buffers (64K). Such pointers are normalized with a zero offset. 197 | * Since MSDOS is not a preemptive multitasking OS, this table is not 198 | * protected from concurrent access. This hack doesn't work anyway on 199 | * a protected system like OS/2. Use Microsoft C instead. 200 | */ 201 | 202 | voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { 203 | voidpf buf; 204 | ulg bsize = (ulg)items*size; 205 | 206 | (void)opaque; 207 | 208 | /* If we allocate less than 65520 bytes, we assume that farmalloc 209 | * will return a usable pointer which doesn't have to be normalized. 210 | */ 211 | if (bsize < 65520L) { 212 | buf = farmalloc(bsize); 213 | if (*(ush*)&buf != 0) return buf; 214 | } else { 215 | buf = farmalloc(bsize + 16L); 216 | } 217 | if (buf == NULL || next_ptr >= MAX_PTR) return NULL; 218 | table[next_ptr].org_ptr = buf; 219 | 220 | /* Normalize the pointer to seg:0 */ 221 | *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; 222 | *(ush*)&buf = 0; 223 | table[next_ptr++].new_ptr = buf; 224 | return buf; 225 | } 226 | 227 | void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { 228 | int n; 229 | 230 | (void)opaque; 231 | 232 | if (*(ush*)&ptr != 0) { /* object < 64K */ 233 | farfree(ptr); 234 | return; 235 | } 236 | /* Find the original pointer */ 237 | for (n = 0; n < next_ptr; n++) { 238 | if (ptr != table[n].new_ptr) continue; 239 | 240 | farfree(table[n].org_ptr); 241 | while (++n < next_ptr) { 242 | table[n-1] = table[n]; 243 | } 244 | next_ptr--; 245 | return; 246 | } 247 | Assert(0, "zcfree: ptr not found"); 248 | } 249 | 250 | #endif /* __TURBOC__ */ 251 | 252 | 253 | #ifdef M_I86 254 | /* Microsoft C in 16-bit mode */ 255 | 256 | # define MY_ZCALLOC 257 | 258 | #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) 259 | # define _halloc halloc 260 | # define _hfree hfree 261 | #endif 262 | 263 | voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { 264 | (void)opaque; 265 | return _halloc((long)items, size); 266 | } 267 | 268 | void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { 269 | (void)opaque; 270 | _hfree(ptr); 271 | } 272 | 273 | #endif /* M_I86 */ 274 | 275 | #endif /* SYS16BIT */ 276 | 277 | 278 | #ifndef MY_ZCALLOC /* Any system without a special alloc function */ 279 | 280 | #ifndef STDC 281 | extern voidp malloc(uInt size); 282 | extern voidp calloc(uInt items, uInt size); 283 | extern void free(voidpf ptr); 284 | #endif 285 | 286 | voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { 287 | (void)opaque; 288 | return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : 289 | (voidpf)calloc(items, size); 290 | } 291 | 292 | void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { 293 | (void)opaque; 294 | free(ptr); 295 | } 296 | 297 | #endif /* MY_ZCALLOC */ 298 | 299 | #endif /* !Z_SOLO */ 300 | -------------------------------------------------------------------------------- /src/zlib/zutil.h: -------------------------------------------------------------------------------- 1 | /* zutil.h -- internal interface and configuration of the compression library 2 | * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* @(#) $Id$ */ 12 | 13 | #ifndef ZUTIL_H 14 | #define ZUTIL_H 15 | 16 | #ifdef HAVE_HIDDEN 17 | # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) 18 | #else 19 | # define ZLIB_INTERNAL 20 | #endif 21 | 22 | #include "zlib.h" 23 | 24 | #if defined(STDC) && !defined(Z_SOLO) 25 | # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) 26 | # include 27 | # endif 28 | # include 29 | # include 30 | #endif 31 | 32 | #ifndef local 33 | # define local static 34 | #endif 35 | /* since "static" is used to mean two completely different things in C, we 36 | define "local" for the non-static meaning of "static", for readability 37 | (compile with -Dlocal if your debugger can't find static symbols) */ 38 | 39 | typedef unsigned char uch; 40 | typedef uch FAR uchf; 41 | typedef unsigned short ush; 42 | typedef ush FAR ushf; 43 | typedef unsigned long ulg; 44 | 45 | #if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) 46 | # include 47 | # if (ULONG_MAX == 0xffffffffffffffff) 48 | # define Z_U8 unsigned long 49 | # elif (ULLONG_MAX == 0xffffffffffffffff) 50 | # define Z_U8 unsigned long long 51 | # elif (UINT_MAX == 0xffffffffffffffff) 52 | # define Z_U8 unsigned 53 | # endif 54 | #endif 55 | 56 | extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ 57 | /* (size given to avoid silly warnings with Visual C++) */ 58 | 59 | #define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] 60 | 61 | #define ERR_RETURN(strm,err) \ 62 | return (strm->msg = ERR_MSG(err), (err)) 63 | /* To be used only when the state is known to be valid */ 64 | 65 | /* common constants */ 66 | 67 | #ifndef DEF_WBITS 68 | # define DEF_WBITS MAX_WBITS 69 | #endif 70 | /* default windowBits for decompression. MAX_WBITS is for compression only */ 71 | 72 | #if MAX_MEM_LEVEL >= 8 73 | # define DEF_MEM_LEVEL 8 74 | #else 75 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 76 | #endif 77 | /* default memLevel */ 78 | 79 | #define STORED_BLOCK 0 80 | #define STATIC_TREES 1 81 | #define DYN_TREES 2 82 | /* The three kinds of block type */ 83 | 84 | #define MIN_MATCH 3 85 | #define MAX_MATCH 258 86 | /* The minimum and maximum match lengths */ 87 | 88 | #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ 89 | 90 | /* target dependencies */ 91 | 92 | #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) 93 | # define OS_CODE 0x00 94 | # ifndef Z_SOLO 95 | # if defined(__TURBOC__) || defined(__BORLANDC__) 96 | # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) 97 | /* Allow compilation with ANSI keywords only enabled */ 98 | void _Cdecl farfree( void *block ); 99 | void *_Cdecl farmalloc( unsigned long nbytes ); 100 | # else 101 | # include 102 | # endif 103 | # else /* MSC or DJGPP */ 104 | # include 105 | # endif 106 | # endif 107 | #endif 108 | 109 | #ifdef AMIGA 110 | # define OS_CODE 1 111 | #endif 112 | 113 | #if defined(VAXC) || defined(VMS) 114 | # define OS_CODE 2 115 | # define F_OPEN(name, mode) \ 116 | fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") 117 | #endif 118 | 119 | #ifdef __370__ 120 | # if __TARGET_LIB__ < 0x20000000 121 | # define OS_CODE 4 122 | # elif __TARGET_LIB__ < 0x40000000 123 | # define OS_CODE 11 124 | # else 125 | # define OS_CODE 8 126 | # endif 127 | #endif 128 | 129 | #if defined(ATARI) || defined(atarist) 130 | # define OS_CODE 5 131 | #endif 132 | 133 | #ifdef OS2 134 | # define OS_CODE 6 135 | # if defined(M_I86) && !defined(Z_SOLO) 136 | # include 137 | # endif 138 | #endif 139 | 140 | #if defined(MACOS) 141 | # define OS_CODE 7 142 | #endif 143 | 144 | #ifdef __acorn 145 | # define OS_CODE 13 146 | #endif 147 | 148 | #if defined(WIN32) && !defined(__CYGWIN__) 149 | # define OS_CODE 10 150 | #endif 151 | 152 | #ifdef _BEOS_ 153 | # define OS_CODE 16 154 | #endif 155 | 156 | #ifdef __TOS_OS400__ 157 | # define OS_CODE 18 158 | #endif 159 | 160 | #ifdef __APPLE__ 161 | # define OS_CODE 19 162 | #endif 163 | 164 | #if defined(__BORLANDC__) && !defined(MSDOS) 165 | #pragma warn -8004 166 | #pragma warn -8008 167 | #pragma warn -8066 168 | #endif 169 | 170 | /* provide prototypes for these when building zlib without LFS */ 171 | #if !defined(_WIN32) && \ 172 | (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) 173 | ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); 174 | ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); 175 | ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); 176 | #endif 177 | 178 | /* common defaults */ 179 | 180 | #ifndef OS_CODE 181 | # define OS_CODE 3 /* assume Unix */ 182 | #endif 183 | 184 | #ifndef F_OPEN 185 | # define F_OPEN(name, mode) fopen((name), (mode)) 186 | #endif 187 | 188 | /* functions */ 189 | 190 | #if defined(pyr) || defined(Z_SOLO) 191 | # define NO_MEMCPY 192 | #endif 193 | #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) 194 | /* Use our own functions for small and medium model with MSC <= 5.0. 195 | * You may have to use the same strategy for Borland C (untested). 196 | * The __SC__ check is for Symantec. 197 | */ 198 | # define NO_MEMCPY 199 | #endif 200 | #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) 201 | # define HAVE_MEMCPY 202 | #endif 203 | #ifdef HAVE_MEMCPY 204 | # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ 205 | # define zmemcpy _fmemcpy 206 | # define zmemcmp _fmemcmp 207 | # define zmemzero(dest, len) _fmemset(dest, 0, len) 208 | # else 209 | # define zmemcpy memcpy 210 | # define zmemcmp memcmp 211 | # define zmemzero(dest, len) memset(dest, 0, len) 212 | # endif 213 | #else 214 | void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); 215 | int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); 216 | void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); 217 | #endif 218 | 219 | /* Diagnostic functions */ 220 | #ifdef ZLIB_DEBUG 221 | # include 222 | extern int ZLIB_INTERNAL z_verbose; 223 | extern void ZLIB_INTERNAL z_error(char *m); 224 | # define Assert(cond,msg) {if(!(cond)) z_error(msg);} 225 | # define Trace(x) {if (z_verbose>=0) fprintf x ;} 226 | # define Tracev(x) {if (z_verbose>0) fprintf x ;} 227 | # define Tracevv(x) {if (z_verbose>1) fprintf x ;} 228 | # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} 229 | # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} 230 | #else 231 | # define Assert(cond,msg) 232 | # define Trace(x) 233 | # define Tracev(x) 234 | # define Tracevv(x) 235 | # define Tracec(c,x) 236 | # define Tracecv(c,x) 237 | #endif 238 | 239 | #ifndef Z_SOLO 240 | voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, 241 | unsigned size); 242 | void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); 243 | #endif 244 | 245 | #define ZALLOC(strm, items, size) \ 246 | (*((strm)->zalloc))((strm)->opaque, (items), (size)) 247 | #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) 248 | #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} 249 | 250 | /* Reverse the bytes in a 32-bit value */ 251 | #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ 252 | (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) 253 | 254 | #endif /* ZUTIL_H */ 255 | --------------------------------------------------------------------------------