├── .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 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
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 |
--------------------------------------------------------------------------------