├── .gitignore
├── Code
├── App.config
├── Costura32
│ └── DdsFileTypePlusIO_x86.dll
├── Costura64
│ └── DdsFileTypePlusIO_x64.dll
├── Cupscale.csproj
├── Cupscale.sln
├── CupscaleLogo1.ico
├── Data
│ └── ModelData.cs
├── FFmpeg
│ ├── FFmpeg.cs
│ ├── FFmpegCommands.cs
│ └── FFmpegStrings.cs
├── FodyWeavers.xml
├── FodyWeavers.xsd
├── Forms
│ ├── AdvancedModelForm.Designer.cs
│ ├── AdvancedModelForm.cs
│ ├── AdvancedModelForm.resx
│ ├── DependencyCheckerForm.Designer.cs
│ ├── DependencyCheckerForm.cs
│ ├── DependencyCheckerForm.resx
│ ├── DialogForm.Designer.cs
│ ├── DialogForm.cs
│ ├── DialogForm.resx
│ ├── InterpForm.Designer.cs
│ ├── InterpForm.cs
│ ├── InterpForm.resx
│ ├── ModelComparisonForm.Designer.cs
│ ├── ModelComparisonForm.cs
│ ├── ModelComparisonForm.resx
│ ├── ModelSelectForm.Designer.cs
│ ├── ModelSelectForm.cs
│ ├── ModelSelectForm.resx
│ ├── MsgBox.Designer.cs
│ ├── MsgBox.cs
│ ├── MsgBox.resx
│ ├── SettingsForm.Designer.cs
│ ├── SettingsForm.cs
│ └── SettingsForm.resx
├── IO
│ ├── Config.cs
│ ├── ConfigParser.cs
│ ├── IOUtils.cs
│ ├── Installer.cs
│ └── Paths.cs
├── ImageUtils
│ ├── Filters.cs
│ ├── ImageOperations.cs
│ ├── ImageProcessing.cs
│ ├── ImgUtils.cs
│ ├── MozJpeg.cs
│ └── NvCompress.cs
├── Implementations
│ ├── EsrganNcnn.cs
│ ├── EsrganPytorch.cs
│ ├── Implementation.cs
│ ├── ImplementationBase.cs
│ ├── Imps.cs
│ └── RealEsrganNcnn.cs
├── Main
│ ├── AdvancedModelSelection.cs
│ ├── Dependencies.cs
│ ├── EsrganData.cs
│ ├── GeneralOutputHandler.cs
│ ├── Logger.cs
│ ├── MainForm.Designer.cs
│ ├── MainForm.cs
│ ├── MainForm.resx
│ ├── PostProcessing.cs
│ ├── PostProcessingQueue.cs
│ ├── PreviewState.cs
│ ├── Program.cs
│ ├── Servers.cs
│ └── Upscale.cs
├── OS
│ ├── EmbeddedPython.cs
│ ├── NcnnUtils.cs
│ ├── NvApi.cs
│ └── OSUtils.cs
├── Preview
│ ├── ClipboardComparison.cs
│ └── PreviewMerger.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Resources
│ ├── 7za.exe
│ ├── CupscaleLogo1.ico
│ ├── baseline_fact_check_white_48dp.png
│ ├── baseline_folder_open_white_48dp.png
│ ├── baseline_photo_library_white_48dp.png
│ ├── baseline_refresh_white_48dp.png
│ ├── baseline_settings_white_48dp.png
│ ├── discordIcoColored.png
│ ├── ffmpeg-h264.exe
│ ├── interp.png
│ ├── modelCompare.png
│ ├── patreon256pxColored.png
│ ├── paypal256px.png
│ ├── questmark.png
│ └── shipped-files-version.txt
├── UI
│ ├── BatchUpscaleUI.cs
│ ├── Controls
│ │ └── ModelCombox.cs
│ ├── DialogQueue.cs
│ ├── ExtensionMethods.cs
│ ├── ModelComparisonTool.cs
│ ├── PreviewUI.cs
│ ├── UIHelpers.cs
│ └── VideoUpscaleUI.cs
└── app.manifest
├── Installer Files
├── av.7z
├── esrgan-ncnn.7z
└── esrgan.7z
├── LICENSE
├── Media
├── baseline_settings_white_48dp.png
├── discordIcoColored.png
└── patreon256pxColored.png
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/Code/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Code/Costura32/DdsFileTypePlusIO_x86.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/n00mkrad/cupscale/35d418c55c80c5426ebd2695c0396c7ad3cc7605/Code/Costura32/DdsFileTypePlusIO_x86.dll
--------------------------------------------------------------------------------
/Code/Costura64/DdsFileTypePlusIO_x64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/n00mkrad/cupscale/35d418c55c80c5426ebd2695c0396c7ad3cc7605/Code/Costura64/DdsFileTypePlusIO_x64.dll
--------------------------------------------------------------------------------
/Code/Cupscale.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Cupscale
4 | False
5 | WinExe
6 | True
7 | net472
8 | True
9 | AnyCPU;x64;x86
10 | Debug;Release;NoNCNN
11 |
12 |
13 | Preview
14 | True
15 | CupscaleLogo1.ico
16 | app.manifest
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Never
28 |
29 |
30 | Never
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | all
41 | runtime; build; native; contentfiles; analyzers; buildtransitive
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll
58 |
59 |
60 | C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.IO.Compression.FileSystem\v4.0_4.0.0.0__b77a5c561934e089\System.IO.Compression.FileSystem.dll
61 |
62 |
63 |
64 |
65 | Form
66 |
67 |
68 | True
69 | True
70 | Resources.resx
71 |
72 |
73 | True
74 | True
75 | Settings.settings
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | PublicResXFileCodeGenerator
85 | Resources.Designer.cs
86 |
87 |
88 |
89 |
90 | SettingsSingleFileGenerator
91 | Settings.Designer.cs
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | Never
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/Code/Cupscale.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30413.136
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cupscale", "Cupscale.csproj", "{CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | NoNCNN|Any CPU = NoNCNN|Any CPU
14 | NoNCNN|x64 = NoNCNN|x64
15 | NoNCNN|x86 = NoNCNN|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|x64 = Release|x64
18 | Release|x86 = Release|x86
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|x64.ActiveCfg = Debug|x64
24 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|x64.Build.0 = Debug|x64
25 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|x86.ActiveCfg = Debug|x86
26 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Debug|x86.Build.0 = Debug|x86
27 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|Any CPU.ActiveCfg = NoNCNN|Any CPU
28 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|Any CPU.Build.0 = NoNCNN|Any CPU
29 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|x64.ActiveCfg = NoNCNN|x64
30 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|x64.Build.0 = NoNCNN|x64
31 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|x86.ActiveCfg = NoNCNN|x86
32 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.NoNCNN|x86.Build.0 = NoNCNN|x86
33 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|x64.ActiveCfg = Release|x64
36 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|x64.Build.0 = Release|x64
37 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|x86.ActiveCfg = Release|x86
38 | {CB003524-BE0F-42E5-BDE2-A98DCE51CE0A}.Release|x86.Build.0 = Release|x86
39 | EndGlobalSection
40 | GlobalSection(SolutionProperties) = preSolution
41 | HideSolutionNode = FALSE
42 | EndGlobalSection
43 | GlobalSection(ExtensibilityGlobals) = postSolution
44 | SolutionGuid = {7687F542-1BB8-46CE-B661-A7F24E6F1BB4}
45 | EndGlobalSection
46 | EndGlobal
47 |
--------------------------------------------------------------------------------
/Code/CupscaleLogo1.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/n00mkrad/cupscale/35d418c55c80c5426ebd2695c0396c7ad3cc7605/Code/CupscaleLogo1.ico
--------------------------------------------------------------------------------
/Code/Data/ModelData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Cupscale.Data
9 | {
10 | struct ModelData
11 | {
12 | public string model1Name;
13 | public string model2Name;
14 | public string model1Path;
15 | public string model2Path;
16 | public enum ModelMode { Single, Interp, Chain, Advanced }
17 | public ModelMode mode;
18 | public int interp;
19 |
20 | public ModelData(string model1, string model2, ModelMode modelMode, int interpolation = 0)
21 | {
22 | model1Name = Path.GetFileNameWithoutExtension(model1);
23 | model2Name = Path.GetFileNameWithoutExtension(model2);
24 | model1Path = model1;
25 | model2Path = model2;
26 | mode = modelMode;
27 | interp = interpolation;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Code/FFmpeg/FFmpeg.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.OS;
3 | using Cupscale.UI;
4 | using System.Diagnostics;
5 | using System.Threading.Tasks;
6 |
7 | namespace Cupscale
8 | {
9 | class FFmpeg
10 | {
11 | public static string lastOutputFfmpeg;
12 |
13 | public static async Task Run(string args)
14 | {
15 | lastOutputFfmpeg = "";
16 | Process ffmpeg = OsUtils.NewProcess(true);
17 | ffmpeg.StartInfo.Arguments = $"/C cd /D {Paths.binPath.Wrap()} & ffmpeg.exe -hide_banner -loglevel warning -y -stats {args}";
18 | Logger.Log("Running ffmpeg...");
19 | Logger.Log("cmd.exe " + ffmpeg.StartInfo.Arguments);
20 | ffmpeg.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
21 | ffmpeg.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
22 | ffmpeg.Start();
23 | ffmpeg.BeginOutputReadLine();
24 | ffmpeg.BeginErrorReadLine();
25 |
26 | while (!ffmpeg.HasExited)
27 | await Task.Delay(100);
28 |
29 | Logger.Log("Done running ffmpeg.");
30 | }
31 |
32 | static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
33 | {
34 | string line = outLine.Data;
35 | if (outLine == null || line == null) return;
36 | lastOutputFfmpeg = lastOutputFfmpeg + line + "\n";
37 | Logger.Log("[FFmpeg] " + line);
38 |
39 | if (line.ToLower().Contains("error"))
40 | Program.ShowMessage("FFmpeg Error:\n\n" + line);
41 | }
42 |
43 | public static async Task RunGifski (string args)
44 | {
45 | Process ffmpeg = OsUtils.NewProcess(true);
46 | ffmpeg.StartInfo.Arguments = $"/C cd /D {Paths.binPath.Wrap()} & gifski.exe {args}";
47 | Logger.Log("Running gifski...");
48 | Logger.Log("cmd.exe " + ffmpeg.StartInfo.Arguments);
49 | ffmpeg.OutputDataReceived += new DataReceivedEventHandler(OutputHandlerGifski);
50 | ffmpeg.ErrorDataReceived += new DataReceivedEventHandler(OutputHandlerGifski);
51 | ffmpeg.Start();
52 | ffmpeg.BeginOutputReadLine();
53 | ffmpeg.BeginErrorReadLine();
54 |
55 | while (!ffmpeg.HasExited)
56 | await Task.Delay(100);
57 |
58 | Logger.Log("Done running gifski.");
59 | }
60 |
61 | static void OutputHandlerGifski (object sendingProcess, DataReceivedEventArgs outLine)
62 | {
63 | string line = outLine.Data;
64 | if (outLine == null || line == null) return;
65 | Logger.Log("[gifski] " + line);
66 |
67 | if (line.ToLower().Contains("error"))
68 | Program.ShowMessage("Gifski Error:\n\n" + line);
69 | }
70 |
71 | public static string RunAndGetOutput (string args)
72 | {
73 | Process ffmpeg = OsUtils.NewProcess(true);
74 | ffmpeg.StartInfo.Arguments = $"/C cd /D {Paths.binPath.Wrap()} & ffmpeg.exe -hide_banner -y -stats {args}";
75 | ffmpeg.Start();
76 | ffmpeg.WaitForExit();
77 | string output = ffmpeg.StandardOutput.ReadToEnd();
78 | string err = ffmpeg.StandardError.ReadToEnd();
79 |
80 | if (!string.IsNullOrWhiteSpace(err))
81 | output = output + "\n" + err;
82 |
83 | return output;
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/Code/FFmpeg/FFmpegStrings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Cupscale
8 | {
9 | class FFmpegStrings
10 | {
11 | public static string hdrFilter = @"-vf select=gte(n\,%frNum%),zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Code/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Code/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
23 |
24 |
25 |
26 |
27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
28 |
29 |
30 |
31 |
32 | The order of preloaded assemblies, delimited with line breaks.
33 |
34 |
35 |
36 |
37 |
38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
39 |
40 |
41 |
42 |
43 | Controls if .pdbs for reference assemblies are also embedded.
44 |
45 |
46 |
47 |
48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
49 |
50 |
51 |
52 |
53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
54 |
55 |
56 |
57 |
58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
59 |
60 |
61 |
62 |
63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
64 |
65 |
66 |
67 |
68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
69 |
70 |
71 |
72 |
73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
74 |
75 |
76 |
77 |
78 | A list of unmanaged 32 bit assembly names to include, delimited with |.
79 |
80 |
81 |
82 |
83 | A list of unmanaged 64 bit assembly names to include, delimited with |.
84 |
85 |
86 |
87 |
88 | The order of preloaded assemblies, delimited with |.
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
97 |
98 |
99 |
100 |
101 | A comma-separated list of error codes that can be safely ignored in assembly verification.
102 |
103 |
104 |
105 |
106 | 'false' to turn off automatic generation of the XML Schema file.
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/Code/Forms/AdvancedModelForm.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Main;
2 | using Cupscale.UI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Data;
7 | using System.Drawing;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 | using System.Windows.Forms;
13 | using static Cupscale.Main.AdvancedModelSelection;
14 |
15 | namespace Cupscale.Forms
16 | {
17 | public partial class AdvancedModelForm : Form
18 | {
19 |
20 | public AdvancedModelForm()
21 | {
22 | InitializeComponent();
23 | Show();
24 | }
25 |
26 | private void entry1Model1Interp_TextChanged(object sender, EventArgs e)
27 | {
28 | int input = entry1Model1Interp.GetInt().Clamp(0, 100);
29 | entry1Model1Interp.Text = input.ToString();
30 | e1m1i = input;
31 | e1m2i = 100 - e1m1i;
32 | entry1Model2Interp.Text = e1m2i.ToString();
33 | }
34 |
35 | private void entry2Model1Interp_TextChanged(object sender, EventArgs e)
36 | {
37 | int input = entry2Model1Interp.GetInt().Clamp(0, 100);
38 | entry2Model1Interp.Text = input.ToString();
39 | e2m1i = input;
40 | e2m2i = 100 - e2m1i;
41 | entry2Model2Interp.Text = e2m2i.ToString();
42 | }
43 |
44 | private void entry3Model1Interp_TextChanged(object sender, EventArgs e)
45 | {
46 | int input = entry3Model1Interp.GetInt().Clamp(0, 100);
47 | entry3Model1Interp.Text = input.ToString();
48 | e3m1i = input;
49 | e3m2i = 100 - e3m1i;
50 | entry3Model2Interp.Text = e3m2i.ToString();
51 | }
52 |
53 | private void entry1Model1_Click(object sender, EventArgs e)
54 | {
55 | using (var modelForm = new ModelSelectForm(entry1Model1, 0))
56 | {
57 | if (modelForm.ShowDialog() == DialogResult.OK)
58 | e1m1 = modelForm.selectedModel;
59 | }
60 | }
61 |
62 | private void entry1Model2_Click(object sender, EventArgs e)
63 | {
64 | using (var modelForm = new ModelSelectForm(entry1Model2, 0))
65 | {
66 | if (modelForm.ShowDialog() == DialogResult.OK)
67 | e1m2 = modelForm.selectedModel;
68 | }
69 | }
70 |
71 | private void entry2Model1_Click(object sender, EventArgs e)
72 | {
73 | using (var modelForm = new ModelSelectForm(entry2Model1, 0))
74 | {
75 | if (modelForm.ShowDialog() == DialogResult.OK)
76 | e2m1 = modelForm.selectedModel;
77 | }
78 | }
79 |
80 | private void entry2Model2_Click(object sender, EventArgs e)
81 | {
82 | using (var modelForm = new ModelSelectForm(entry2Model2, 0))
83 | {
84 | if (modelForm.ShowDialog() == DialogResult.OK)
85 | e2m2 = modelForm.selectedModel;
86 | }
87 | }
88 |
89 | private void entry3Model1_Click(object sender, EventArgs e)
90 | {
91 | using (var modelForm = new ModelSelectForm(entry3Model1, 0))
92 | {
93 | if (modelForm.ShowDialog() == DialogResult.OK)
94 | e3m1 = modelForm.selectedModel;
95 | }
96 | }
97 |
98 | private void entry3Model2_Click(object sender, EventArgs e)
99 | {
100 | using (var modelForm = new ModelSelectForm(entry3Model2, 0))
101 | {
102 | if (modelForm.ShowDialog() == DialogResult.OK)
103 | e3m2 = modelForm.selectedModel;
104 | }
105 | }
106 |
107 | private void cancelBtn_Click(object sender, EventArgs e)
108 | {
109 | e1m1 = null;
110 | e1m2 = null;
111 | e2m1 = null;
112 | e2m2 = null;
113 | e3m1 = null;
114 | e3m2 = null;
115 | Close();
116 | }
117 |
118 | private void confirmBtn_Click(object sender, EventArgs e)
119 | {
120 | Logger.Log("Advanced Model Arg: " + GetArg());
121 | SavePreset("lastUsed");
122 | Close();
123 | }
124 |
125 | private void AdvancedModelForm_Load(object sender, EventArgs e)
126 | {
127 | if (!LoadPreset("lastUsed"))
128 | return;
129 |
130 | ChangeButtonText(entry1Model1, GetModelName(e1m1));
131 | entry1Model1Interp.Text = e1m1i.ToString();
132 | ChangeButtonText(entry1Model2, GetModelName(e1m2));
133 | entry1Model2Interp.Text = e1m2i.ToString();
134 |
135 | ChangeButtonText(entry2Model1, GetModelName(e2m1));
136 | entry2Model1Interp.Text = e2m1i.ToString();
137 | ChangeButtonText(entry2Model2, GetModelName(e2m2));
138 | entry2Model2Interp.Text = e3m2i.ToString();
139 |
140 | ChangeButtonText(entry3Model1, GetModelName(e3m1));
141 | entry3Model1Interp.Text = e3m1i.ToString();
142 | ChangeButtonText(entry3Model2, GetModelName(e3m2));
143 | entry3Model2Interp.Text = e3m2i.ToString();
144 | }
145 |
146 | void ChangeButtonText (Button btn, string newText)
147 | {
148 | if (!string.IsNullOrWhiteSpace(newText))
149 | btn.Text = newText;
150 |
151 | }
152 |
153 | string GetModelName (string path)
154 | {
155 | return Path.GetFileNameWithoutExtension(path);
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/Code/Forms/AdvancedModelForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Select the models you want to interpolate/chain.
122 | You don't need to fill out all model fields - empty ones will be ignored.
123 | This way you can, for example, chain two interpolated models, or three single models, or even three interpolated models.
124 | Entry 1 will be chained with Entry 2 and then Entry 3, but you can also just chain two models by leaving Entry 3 empty.
125 |
126 |
127 |
--------------------------------------------------------------------------------
/Code/Forms/DependencyCheckerForm.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Main;
2 | using Cupscale.OS;
3 | using Cupscale.UI;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.ComponentModel;
7 | using System.Data;
8 | using System.Diagnostics;
9 | using System.Drawing;
10 | using System.IO;
11 | using System.Linq;
12 | using System.Management;
13 | using System.Text;
14 | using System.Threading.Tasks;
15 | using System.Windows.Forms;
16 |
17 | namespace Cupscale.Forms
18 | {
19 | public partial class DependencyCheckerForm : Form
20 | {
21 | Stopwatch sw = new Stopwatch();
22 |
23 | bool gpuAvail;
24 | bool nvGpuAvail;
25 | bool sysPyAvail;
26 | bool embedPyAvail;
27 | bool torchAvail;
28 | bool cv2Avail;
29 |
30 | public DependencyCheckerForm(bool openPyInstaller = false, bool startPyInstall = false)
31 | {
32 | InitializeComponent();
33 |
34 | if (openPyInstaller)
35 | tabList1.SelectedIndex = 1;
36 |
37 | if (openPyInstaller && startPyInstall)
38 | installBtn_Click(null, null);
39 | }
40 |
41 | private async void DependencyCheckerForm_Load(object sender, EventArgs e)
42 | {
43 |
44 | }
45 |
46 | public async Task Refresh ()
47 | {
48 | if (sw.ElapsedMilliseconds < 1000 && sw.ElapsedMilliseconds != 0)
49 | {
50 | Logger.Log($"[DepCheck] Skipping refresh - Only {sw.ElapsedMilliseconds}ms have passed since last refresh!");
51 | return;
52 | }
53 |
54 | sw.Restart();
55 | Logger.Log("[DepCheck] Refreshing...");
56 |
57 | gpuAvail = false;
58 | nvGpuAvail = false;
59 | sysPyAvail = false;
60 | embedPyAvail = false;
61 | torchAvail = false;
62 | cv2Avail = false;
63 |
64 | SetChecking(gpu);
65 |
66 | if (Dependencies.HasGpu())
67 | {
68 | SetGreen(gpu, "Available");
69 | gpuAvail = true;
70 | }
71 | else
72 | {
73 | SetRed(gpu);
74 | }
75 |
76 | await Task.Delay(10);
77 | SetChecking(nvGpu);
78 |
79 | if (NvApi.gpuList.Count > 0)
80 | {
81 | string gpuText = NvApi.GetFirstGpuName().Replace("NVIDIA ", "").Replace("AMD ", "").Replace("GeForce ", "");
82 | Logger.Log("[DepCheck] First GPU Name: " + gpuText);
83 |
84 | if (NvApi.gpuList.Count > 1)
85 | gpuText = $"{gpuText} + {NvApi.gpuList.Count - 1}";
86 |
87 | SetGreen(nvGpu, gpuText);
88 | nvGpuAvail = true;
89 | }
90 | else
91 | {
92 | SetRed(nvGpu);
93 | }
94 |
95 | await Task.Delay(10);
96 |
97 | SetChecking(sysPython);
98 | string sysPyVer = Dependencies.GetSysPyVersion();
99 |
100 | if (!string.IsNullOrWhiteSpace(sysPyVer) && !sysPyVer.ToLower().Contains("not found") && sysPyVer.Length <= 35)
101 | {
102 | SetGreen(sysPython, sysPyVer);
103 | sysPyAvail = true;
104 | }
105 | else
106 | {
107 | SetRed(sysPython);
108 | }
109 |
110 | await Task.Delay(10);
111 |
112 | SetChecking(embedPython);
113 | string embedPyVer = Dependencies.GetEmbedPyVersion();
114 |
115 | if (!string.IsNullOrWhiteSpace(embedPyVer) && !embedPyVer.ToLower().Contains("not found") && embedPyVer.Length <= 35)
116 | {
117 | SetGreen(embedPython, embedPyVer);
118 | embedPyAvail = true;
119 | }
120 | else
121 | {
122 | SetRed(embedPython);
123 | }
124 |
125 | if (!sysPyAvail && embedPyAvail)
126 | SetGrey(sysPython, "Not Needed");
127 |
128 | if (!embedPyAvail&& sysPyAvail)
129 | SetGrey(embedPython, "Not Needed");
130 |
131 | await Task.Delay(10);
132 |
133 | SetChecking(torch);
134 | string torchVer = Dependencies.GetPytorchVer();
135 |
136 | if (!string.IsNullOrWhiteSpace(torchVer) && torchVer.Length <= 35)
137 | {
138 | SetGreen(torch, torchVer);
139 | torchAvail = true;
140 | }
141 | else
142 | {
143 | SetRed(torch);
144 | }
145 |
146 | await Task.Delay(10);
147 |
148 | SetChecking(cv2);
149 | string cv2Ver = Dependencies.GetOpenCvVer();
150 |
151 | if (!string.IsNullOrWhiteSpace(cv2Ver) && !cv2Ver.ToLower().Contains("ModuleNotFoundError") && cv2Ver.Length <= 35)
152 | {
153 | SetGreen(cv2, cv2Ver);
154 | cv2Avail = true;
155 | }
156 | else
157 | {
158 | SetRed(cv2);
159 | }
160 |
161 | RefreshAvailOptions();
162 | }
163 |
164 | void RefreshAvailOptions ()
165 | {
166 | bool hasAnyPy = sysPyAvail || embedPyAvail;
167 | bool hasPyDepends = torchAvail && cv2Avail;
168 |
169 | if(hasAnyPy && hasPyDepends)
170 | {
171 | SetGreen(cpuUpscaling, "Available");
172 |
173 | if (nvGpuAvail)
174 | SetGreen(cudaUpscaling, "Available");
175 | else
176 | SetRed(cudaUpscaling, "No Nvidia GPU");
177 | }
178 | else
179 | {
180 | SetRed(cpuUpscaling, "Missing Dependencies");
181 | SetRed(cudaUpscaling, "Missing Dependencies");
182 | }
183 |
184 | if(gpuAvail)
185 | SetGreen(ncnnUpscaling, "Available");
186 | else
187 | SetRed(ncnnUpscaling, "Not Available");
188 | }
189 |
190 | void SetChecking(Label l)
191 | {
192 | l.Text = "Checking...";
193 | l.ForeColor = Color.Silver;
194 | }
195 |
196 | void SetGreen(Label l, string t)
197 | {
198 | l.Text = t;
199 | l.ForeColor = Color.Lime;
200 | }
201 |
202 | void SetRed (Label l, string t = "Not Found")
203 | {
204 | l.Text = t;
205 | l.ForeColor = Color.Red;
206 | }
207 |
208 | void SetGrey(Label l, string t = "Not Found")
209 | {
210 | l.Text = t;
211 | l.ForeColor = Color.Gray;
212 | }
213 |
214 | private async void label8_VisibleChanged(object sender, EventArgs e)
215 | {
216 | if (!label8.Visible)
217 | return;
218 |
219 | await Task.Delay(100);
220 | await Refresh();
221 | }
222 |
223 | private async void installBtn_Click(object sender, EventArgs e)
224 | {
225 | await EmbeddedPython.Download(installerLogBox, installBtn);
226 | }
227 |
228 | private void DependencyCheckerForm_FormClosing(object sender, FormClosingEventArgs e)
229 | {
230 | if(!installBtn.Enabled)
231 | e.Cancel = true;
232 | }
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/Code/Forms/DependencyCheckerForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Code/Forms/DialogForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cupscale.Forms
2 | {
3 | partial class DialogForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DialogForm));
32 | this.mainLabel = new System.Windows.Forms.Label();
33 | this.panel1 = new System.Windows.Forms.Panel();
34 | this.panel1.SuspendLayout();
35 | this.SuspendLayout();
36 | //
37 | // mainLabel
38 | //
39 | this.mainLabel.Dock = System.Windows.Forms.DockStyle.Fill;
40 | this.mainLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
41 | this.mainLabel.ForeColor = System.Drawing.Color.White;
42 | this.mainLabel.Location = new System.Drawing.Point(0, 0);
43 | this.mainLabel.Name = "mainLabel";
44 | this.mainLabel.Size = new System.Drawing.Size(498, 78);
45 | this.mainLabel.TabIndex = 0;
46 | this.mainLabel.Text = "Dialog Text Here...";
47 | this.mainLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
48 | //
49 | // panel1
50 | //
51 | this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
52 | this.panel1.Controls.Add(this.mainLabel);
53 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
54 | this.panel1.Location = new System.Drawing.Point(0, 0);
55 | this.panel1.Name = "panel1";
56 | this.panel1.Size = new System.Drawing.Size(500, 80);
57 | this.panel1.TabIndex = 1;
58 | //
59 | // DialogForm
60 | //
61 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
62 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
63 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48)))));
64 | this.ClientSize = new System.Drawing.Size(500, 80);
65 | this.Controls.Add(this.panel1);
66 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
67 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
68 | this.Name = "DialogForm";
69 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
70 | this.Text = "DialogForm";
71 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DialogForm_FormClosing);
72 | this.panel1.ResumeLayout(false);
73 | this.ResumeLayout(false);
74 |
75 | }
76 |
77 | #endregion
78 |
79 | private System.Windows.Forms.Label mainLabel;
80 | private System.Windows.Forms.Panel panel1;
81 | }
82 | }
--------------------------------------------------------------------------------
/Code/Forms/DialogForm.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.UI;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | namespace Cupscale.Forms
13 | {
14 | public partial class DialogForm : Form
15 | {
16 | public DialogForm(string message, float selfDestructTime = 60f)
17 | {
18 | InitializeComponent();
19 | Program.currentTemporaryForms.Add(this);
20 | mainLabel.Text = message;
21 | Show();
22 | //TopMost = true;
23 | SelfDestruct(selfDestructTime);
24 | }
25 |
26 | public void ChangeText (string s)
27 | {
28 | mainLabel.Text = s;
29 | }
30 |
31 | public string GetText ()
32 | {
33 | return mainLabel.Text;
34 | }
35 |
36 | private async Task SelfDestruct (float time)
37 | {
38 | await Task.Delay((time * 1000f).RoundToInt());
39 | Close();
40 | }
41 |
42 | private void DialogForm_FormClosing(object sender, FormClosingEventArgs e)
43 | {
44 | Program.currentTemporaryForms.Remove(this);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Code/Forms/InterpForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cupscale.Forms
2 | {
3 | partial class AdvancedModelsForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.interpSlider = new System.Windows.Forms.TrackBar();
32 | this.label1 = new System.Windows.Forms.Label();
33 | this.panel1 = new System.Windows.Forms.Panel();
34 | this.leftModelLabel = new System.Windows.Forms.Label();
35 | this.panel2 = new System.Windows.Forms.Panel();
36 | this.rightModelLabel = new System.Windows.Forms.Label();
37 | this.saveBtn = new System.Windows.Forms.Button();
38 | ((System.ComponentModel.ISupportInitialize)(this.interpSlider)).BeginInit();
39 | this.panel1.SuspendLayout();
40 | this.panel2.SuspendLayout();
41 | this.SuspendLayout();
42 | //
43 | // interpSlider
44 | //
45 | this.interpSlider.Location = new System.Drawing.Point(109, 185);
46 | this.interpSlider.Margin = new System.Windows.Forms.Padding(100, 10, 100, 10);
47 | this.interpSlider.Maximum = 20;
48 | this.interpSlider.Name = "interpSlider";
49 | this.interpSlider.Size = new System.Drawing.Size(366, 45);
50 | this.interpSlider.TabIndex = 0;
51 | this.interpSlider.Value = 10;
52 | this.interpSlider.ValueChanged += new System.EventHandler(this.interpSlider_ValueChanged);
53 | //
54 | // label1
55 | //
56 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
57 | | System.Windows.Forms.AnchorStyles.Right)));
58 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
59 | this.label1.Location = new System.Drawing.Point(8, 9);
60 | this.label1.Name = "label1";
61 | this.label1.Size = new System.Drawing.Size(560, 23);
62 | this.label1.TabIndex = 1;
63 | this.label1.Text = "Drag the slider to adjust how strong the effect of each model will be.";
64 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
65 | //
66 | // panel1
67 | //
68 | this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
69 | | System.Windows.Forms.AnchorStyles.Right)));
70 | this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
71 | this.panel1.Controls.Add(this.leftModelLabel);
72 | this.panel1.Location = new System.Drawing.Point(12, 72);
73 | this.panel1.Name = "panel1";
74 | this.panel1.Size = new System.Drawing.Size(560, 40);
75 | this.panel1.TabIndex = 2;
76 | //
77 | // leftModelLabel
78 | //
79 | this.leftModelLabel.Dock = System.Windows.Forms.DockStyle.Fill;
80 | this.leftModelLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
81 | this.leftModelLabel.Location = new System.Drawing.Point(0, 0);
82 | this.leftModelLabel.Margin = new System.Windows.Forms.Padding(3);
83 | this.leftModelLabel.Name = "leftModelLabel";
84 | this.leftModelLabel.Size = new System.Drawing.Size(558, 38);
85 | this.leftModelLabel.TabIndex = 0;
86 | this.leftModelLabel.Text = "Left Model Name: 50%";
87 | this.leftModelLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
88 | //
89 | // panel2
90 | //
91 | this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
92 | | System.Windows.Forms.AnchorStyles.Right)));
93 | this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
94 | this.panel2.Controls.Add(this.rightModelLabel);
95 | this.panel2.Location = new System.Drawing.Point(12, 125);
96 | this.panel2.Margin = new System.Windows.Forms.Padding(3, 10, 3, 10);
97 | this.panel2.Name = "panel2";
98 | this.panel2.Size = new System.Drawing.Size(560, 40);
99 | this.panel2.TabIndex = 3;
100 | //
101 | // rightModelLabel
102 | //
103 | this.rightModelLabel.Dock = System.Windows.Forms.DockStyle.Fill;
104 | this.rightModelLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
105 | this.rightModelLabel.Location = new System.Drawing.Point(0, 0);
106 | this.rightModelLabel.Name = "rightModelLabel";
107 | this.rightModelLabel.Size = new System.Drawing.Size(558, 38);
108 | this.rightModelLabel.TabIndex = 0;
109 | this.rightModelLabel.Text = "Right Model Name: 50%";
110 | this.rightModelLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
111 | //
112 | // saveBtn
113 | //
114 | this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
115 | | System.Windows.Forms.AnchorStyles.Right)));
116 | this.saveBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
117 | this.saveBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
118 | this.saveBtn.Location = new System.Drawing.Point(159, 243);
119 | this.saveBtn.Margin = new System.Windows.Forms.Padding(150, 3, 150, 3);
120 | this.saveBtn.Name = "saveBtn";
121 | this.saveBtn.Size = new System.Drawing.Size(266, 30);
122 | this.saveBtn.TabIndex = 8;
123 | this.saveBtn.Text = "Save";
124 | this.saveBtn.UseVisualStyleBackColor = false;
125 | this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
126 | //
127 | // AdvancedModelsForm
128 | //
129 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
130 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
131 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
132 | this.ClientSize = new System.Drawing.Size(584, 285);
133 | this.Controls.Add(this.saveBtn);
134 | this.Controls.Add(this.panel2);
135 | this.Controls.Add(this.panel1);
136 | this.Controls.Add(this.label1);
137 | this.Controls.Add(this.interpSlider);
138 | this.ForeColor = System.Drawing.Color.White;
139 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
140 | this.Name = "AdvancedModelsForm";
141 | this.Text = "Set Interpolation Factor";
142 | this.Load += new System.EventHandler(this.InterpForm_Load);
143 | ((System.ComponentModel.ISupportInitialize)(this.interpSlider)).EndInit();
144 | this.panel1.ResumeLayout(false);
145 | this.panel2.ResumeLayout(false);
146 | this.ResumeLayout(false);
147 | this.PerformLayout();
148 |
149 | }
150 |
151 | #endregion
152 |
153 | private System.Windows.Forms.TrackBar interpSlider;
154 | private System.Windows.Forms.Label label1;
155 | private System.Windows.Forms.Panel panel1;
156 | private System.Windows.Forms.Label leftModelLabel;
157 | private System.Windows.Forms.Panel panel2;
158 | private System.Windows.Forms.Label rightModelLabel;
159 | private System.Windows.Forms.Button saveBtn;
160 | }
161 | }
--------------------------------------------------------------------------------
/Code/Forms/InterpForm.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.UI;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | namespace Cupscale.Forms
13 | {
14 | public partial class AdvancedModelsForm : Form
15 | {
16 | string leftModelName;
17 | string rightModelName;
18 |
19 | public AdvancedModelsForm(string leftModel, string rightModel)
20 | {
21 | leftModelName = leftModel;
22 | rightModelName = rightModel;
23 | InitializeComponent();
24 | //Show();
25 | CenterToParent();
26 | }
27 |
28 | private void InterpForm_Load(object sender, EventArgs e)
29 | {
30 | interpSlider.Value = PreviewUi.interpValue / 5;
31 | UpdateLabels();
32 | }
33 |
34 | private void saveBtn_Click(object sender, EventArgs e)
35 | {
36 | PreviewUi.interpValue = interpSlider.Value * 5;
37 | Close();
38 | }
39 |
40 | private void interpSlider_ValueChanged(object sender, EventArgs e)
41 | {
42 | UpdateLabels();
43 | }
44 |
45 | void UpdateLabels ()
46 | {
47 | leftModelLabel.Text = leftModelName + ": " + (100 - interpSlider.Value * 5) + "%";
48 | rightModelLabel.Text = rightModelName + ": " + interpSlider.Value * 5 + "%";
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Code/Forms/InterpForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Code/Forms/ModelComparisonForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Code/Forms/ModelSelectForm.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.OS;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Data;
7 | using System.Diagnostics;
8 | using System.Drawing;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Text;
12 | using System.Threading.Tasks;
13 | using System.Windows.Forms;
14 |
15 | namespace Cupscale.Forms
16 | {
17 | public partial class ModelSelectForm : Form
18 | {
19 | public string selectedModel { get; set; }
20 | public int modelNo;
21 | public Button modelBtn;
22 |
23 | public ModelSelectForm(Button modelButton, int modelNumber)
24 | {
25 | InitializeComponent();
26 | modelBtn = modelButton;
27 | modelNo = modelNumber;
28 | SelectLastUsed();
29 | }
30 |
31 | private void ModelSelectForm_Load(object sender, EventArgs e)
32 | {
33 | string modelDir = Config.Get("modelPath");
34 |
35 | if (!Directory.Exists(modelDir))
36 | {
37 | Program.ShowMessage("The saved model directory does not exist - Make sure you've set a models folder!");
38 | Close();
39 | return;
40 | }
41 |
42 | if (IoUtils.GetAmountOfFiles(modelDir, true, "*.pth") < 1)
43 | {
44 | Program.ShowMessage($"The saved model directory does not contain any model (.pth) files!\n\nPlease put some models into '{modelDir}'.");
45 | Close();
46 | Process.Start("explorer.exe", Config.Get("modelPath"));
47 | return;
48 | }
49 |
50 | ForceLowercaseExtensions(modelDir);
51 | DirectoryInfo modelsDir = new DirectoryInfo(modelDir);
52 | BuildTree(modelsDir, modelTree.Nodes);
53 |
54 | if (Config.GetBool("modelSelectAutoExpand"))
55 | modelTree.ExpandAll();
56 | else
57 | modelTree.Nodes[0].Expand();
58 | }
59 |
60 | private async void SelectLastUsed()
61 | {
62 | if (!Directory.Exists(Config.Get("modelPath")))
63 | return;
64 |
65 | while (modelTree.Nodes.Count < 1)
66 | await Task.Delay(100);
67 |
68 | if (string.IsNullOrWhiteSpace(Program.currentModel1))
69 | modelTree.SelectedNode = modelTree.Nodes[0];
70 | else
71 | CheckNodesRecursive(modelTree.Nodes[0]);
72 | }
73 |
74 | private void CheckNodesRecursive(TreeNode parentNode)
75 | {
76 | if (modelBtn != null && parentNode.Text.Trim() == modelBtn.Text.Trim())
77 | modelTree.SelectedNode = parentNode;
78 |
79 | foreach (TreeNode subNode in parentNode.Nodes)
80 | {
81 | CheckNodesRecursive(subNode);
82 | }
83 | }
84 |
85 | private void ForceLowercaseExtensions(string path)
86 | {
87 | foreach (FileInfo file in IoUtils.GetFileInfosSorted(path, true, "*.*"))
88 | {
89 | if (file.Extension == ".PTH")
90 | file.MoveTo(Path.ChangeExtension(file.FullName, "pth"));
91 | }
92 | }
93 |
94 | private void BuildTree(DirectoryInfo directoryInfo, TreeNodeCollection nodeCollection)
95 | {
96 | TreeNode currNode = nodeCollection.Add(directoryInfo.Name);
97 |
98 | foreach (FileInfo file in directoryInfo.GetFiles())
99 | {
100 | if (file.Extension == ".pth") // Hide any other file extension
101 | currNode.Nodes.Add(file.FullName, Path.ChangeExtension(file.Name, null));
102 | }
103 |
104 | foreach (DirectoryInfo subDir in directoryInfo.GetDirectories())
105 | {
106 | bool isNcnnModel = NcnnUtils.IsDirNcnnModel(subDir.FullName);
107 |
108 | if (isNcnnModel)
109 | currNode.Nodes.Add(subDir.FullName, subDir.Name.Substring(0, subDir.Name.Length - 5));
110 |
111 | bool hasAnyPthFiles = subDir.GetFiles("*.pth", SearchOption.AllDirectories).Length > 0;
112 | bool hasAnyBinFiles = subDir.GetFiles("*.bin", SearchOption.AllDirectories).Length > 0;
113 | bool hasAnyParamFiles = subDir.GetFiles("*.param", SearchOption.AllDirectories).Length > 0;
114 |
115 | if (isNcnnModel || subDir.Name.StartsWith("."))
116 | continue; // Don't add this folder to the tree if it's a model, not a dir with more models
117 |
118 | if (hasAnyPthFiles || hasAnyBinFiles || hasAnyParamFiles) // Don't list folders that have no model files
119 | BuildTree(subDir, currNode.Nodes);
120 | }
121 | }
122 |
123 | private void confirmBtn_Click(object sender, EventArgs e)
124 | {
125 | selectedModel = modelTree.SelectedNode.Name;
126 | string modelName = Path.GetFileNameWithoutExtension(selectedModel);
127 |
128 | if (modelBtn != null)
129 | modelBtn.Text = modelName;
130 |
131 | if (modelNo == 1) Program.currentModel1 = selectedModel;
132 | if (modelNo == 2) Program.currentModel2 = selectedModel;
133 |
134 | Config.Set("lastMdl1", Program.currentModel1);
135 | Config.Set("lastMdl2", Program.currentModel2);
136 |
137 | DialogResult = DialogResult.OK;
138 | Close();
139 | }
140 |
141 | private void cancelBtn_Click(object sender, EventArgs e)
142 | {
143 | Close();
144 | }
145 |
146 | private void modelTree_AfterSelect(object sender, TreeViewEventArgs e)
147 | {
148 | confirmBtn.Enabled = (Path.GetExtension(modelTree.SelectedNode.Name) == ".pth" || modelTree.SelectedNode.Name.EndsWith(".ncnn"));
149 | }
150 |
151 | private void ModelSelectForm_KeyPress(object sender, KeyPressEventArgs e)
152 | {
153 | if (e.KeyChar == (char)Keys.Enter)
154 | {
155 | e.Handled = true;
156 | if (confirmBtn.Enabled)
157 | confirmBtn_Click(null, null);
158 | }
159 |
160 | if (e.KeyChar == (char)Keys.Escape)
161 | {
162 | e.Handled = true;
163 | Close();
164 | }
165 | }
166 |
167 | private void clearBtn_Click(object sender, EventArgs e)
168 | {
169 | selectedModel = "";
170 | modelBtn.Text = "None";
171 | if (modelNo == 1) Program.currentModel1 = null;
172 | if (modelNo == 2) Program.currentModel2 = null;
173 | DialogResult = DialogResult.OK;
174 | Close();
175 | }
176 |
177 | private void openFolderBtn_Click(object sender, EventArgs e)
178 | {
179 | Process.Start("explorer.exe", Config.Get("modelPath"));
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/Code/Forms/ModelSelectForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Code/Forms/MsgBox.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Cupscale.Forms
2 | {
3 | partial class MsgBox
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.confirmBtn = new HTAlt.WinForms.HTButton();
32 | this.msgTextbox = new System.Windows.Forms.TextBox();
33 | this.SuspendLayout();
34 | //
35 | // confirmBtn
36 | //
37 | this.confirmBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
38 | | System.Windows.Forms.AnchorStyles.Right)));
39 | this.confirmBtn.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
40 | this.confirmBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
41 | this.confirmBtn.FlatAppearance.BorderSize = 0;
42 | this.confirmBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
43 | this.confirmBtn.ForeColor = System.Drawing.Color.White;
44 | this.confirmBtn.Location = new System.Drawing.Point(407, 177);
45 | this.confirmBtn.Margin = new System.Windows.Forms.Padding(8);
46 | this.confirmBtn.Name = "confirmBtn";
47 | this.confirmBtn.Size = new System.Drawing.Size(200, 32);
48 | this.confirmBtn.TabIndex = 13;
49 | this.confirmBtn.Text = "OK";
50 | this.confirmBtn.UseVisualStyleBackColor = false;
51 | this.confirmBtn.Click += new System.EventHandler(this.confirmBtn_Click);
52 | //
53 | // msgTextbox
54 | //
55 | this.msgTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
56 | | System.Windows.Forms.AnchorStyles.Left)
57 | | System.Windows.Forms.AnchorStyles.Right)));
58 | this.msgTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
59 | this.msgTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None;
60 | this.msgTextbox.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
61 | this.msgTextbox.ForeColor = System.Drawing.Color.White;
62 | this.msgTextbox.Location = new System.Drawing.Point(28, 17);
63 | this.msgTextbox.Margin = new System.Windows.Forms.Padding(8);
64 | this.msgTextbox.Multiline = true;
65 | this.msgTextbox.Name = "msgTextbox";
66 | this.msgTextbox.ReadOnly = true;
67 | this.msgTextbox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
68 | this.msgTextbox.Size = new System.Drawing.Size(579, 144);
69 | this.msgTextbox.TabIndex = 35;
70 | this.msgTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
71 | this.msgTextbox.TextChanged += new System.EventHandler(this.msgTextbox_TextChanged);
72 | //
73 | // MsgBox
74 | //
75 | this.AcceptButton = this.confirmBtn;
76 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
77 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
78 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
79 | this.ClientSize = new System.Drawing.Size(624, 226);
80 | this.Controls.Add(this.msgTextbox);
81 | this.Controls.Add(this.confirmBtn);
82 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
83 | this.MaximizeBox = false;
84 | this.MinimizeBox = false;
85 | this.Name = "MsgBox";
86 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
87 | this.Text = "Message";
88 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MsgBox_FormClosing);
89 | this.Load += new System.EventHandler(this.MsgBox_Load);
90 | this.ResumeLayout(false);
91 | this.PerformLayout();
92 |
93 | }
94 |
95 | #endregion
96 |
97 | private HTAlt.WinForms.HTButton confirmBtn;
98 | private System.Windows.Forms.TextBox msgTextbox;
99 | }
100 | }
--------------------------------------------------------------------------------
/Code/Forms/MsgBox.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.UI;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Text.RegularExpressions;
10 | using System.Threading.Tasks;
11 | using System.Windows.Forms;
12 |
13 | namespace Cupscale.Forms
14 | {
15 | public partial class MsgBox : Form
16 | {
17 | public bool usedConfirmBtn;
18 |
19 | public MsgBox(string msg, string title = "Message")
20 | {
21 | InitializeComponent();
22 | Text = title;
23 | msgTextbox.Text = msg;
24 | }
25 |
26 | private void MsgBox_Load(object sender, EventArgs e)
27 | {
28 |
29 | }
30 |
31 | private void confirmBtn_Click(object sender, EventArgs e)
32 | {
33 | usedConfirmBtn = true;
34 | DialogResult = DialogResult.OK;
35 | DialogQueue.CloseCurrent();
36 | }
37 |
38 | private void msgTextbox_TextChanged(object sender, EventArgs e)
39 | {
40 | int linebreaks = Regex.Split(msgTextbox.Text, "\r\n|\r|\n").Length;
41 | if (linebreaks > 6)
42 | msgTextbox.ScrollBars = ScrollBars.Vertical;
43 | else
44 | msgTextbox.ScrollBars = ScrollBars.None;
45 |
46 | if (linebreaks > 10)
47 | Size = new Size(Size.Width, 450);
48 |
49 | if (msgTextbox.Text.Contains("Stack Trace"))
50 | msgTextbox.TextAlign = HorizontalAlignment.Left;
51 | else
52 | msgTextbox.TextAlign = HorizontalAlignment.Center;
53 | }
54 |
55 | private void MsgBox_FormClosing(object sender, FormClosingEventArgs e)
56 | {
57 | if (!usedConfirmBtn)
58 | {
59 | DialogResult = DialogResult.OK;
60 | DialogQueue.CloseCurrent();
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Code/Forms/MsgBox.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Code/IO/ConfigParser.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.UI;
2 | using System;
3 | using System.Windows.Forms;
4 |
5 | namespace Cupscale.IO
6 | {
7 | class ConfigParser
8 | {
9 |
10 | public enum StringMode { Any, Int, Float }
11 |
12 | public static void SaveGuiElement(TextBox textbox, StringMode stringMode = StringMode.Any)
13 | {
14 | switch (stringMode)
15 | {
16 | case StringMode.Any: Config.Set(textbox.Name, textbox.Text); break;
17 | case StringMode.Int: Config.Set(textbox.Name, textbox.Text.GetInt().ToString()); break;
18 | case StringMode.Float: Config.Set(textbox.Name, textbox.Text.GetFloat().ToString()); break;
19 | }
20 | }
21 |
22 | public static void SaveGuiElement(ComboBox comboBox, StringMode stringMode = StringMode.Any)
23 | {
24 | switch (stringMode)
25 | {
26 | case StringMode.Any: Config.Set(comboBox.Name, comboBox.Text); break;
27 | case StringMode.Int: Config.Set(comboBox.Name, comboBox.Text.GetInt().ToString()); break;
28 | case StringMode.Float: Config.Set(comboBox.Name, comboBox.Text.GetFloat().ToString().Replace(",", ".")); break;
29 | }
30 | }
31 |
32 | public static void SaveGuiElement(CheckBox checkbox)
33 | {
34 | Config.Set(checkbox.Name, checkbox.Checked.ToString());
35 | }
36 |
37 | public static void SaveGuiElement(NumericUpDown upDown, StringMode stringMode = StringMode.Any)
38 | {
39 | switch (stringMode)
40 | {
41 | case StringMode.Any: Config.Set(upDown.Name, ((float)upDown.Value).ToString().Replace(",", ".")); break;
42 | case StringMode.Int: Config.Set(upDown.Name, ((int)upDown.Value).ToString()); break;
43 | case StringMode.Float: Config.Set(upDown.Name, ((float)upDown.Value).ToString().Replace(",", ".")); ; break;
44 | }
45 | }
46 |
47 | public static void SaveComboxIndex(ComboBox comboBox)
48 | {
49 | Config.Set(comboBox.Name, comboBox.SelectedIndex.ToString());
50 | }
51 |
52 | public static void LoadGuiElement(ComboBox comboBox, string suffix = "")
53 | {
54 | comboBox.Text = Config.Get(comboBox.Name) + suffix;
55 | }
56 |
57 | public static void LoadGuiElement(TextBox textbox, string suffix = "")
58 | {
59 | textbox.Text = Config.Get(textbox.Name) + suffix; ;
60 | }
61 |
62 | public static void LoadGuiElement(CheckBox checkbox)
63 | {
64 | checkbox.Checked = Config.GetBool(checkbox.Name);
65 | }
66 |
67 | public static void LoadGuiElement(NumericUpDown upDown)
68 | {
69 | upDown.Value = Convert.ToDecimal(Config.GetFloat(upDown.Name));
70 | }
71 |
72 | public static void LoadComboxIndex(ComboBox comboBox)
73 | {
74 | comboBox.SelectedIndex = Config.GetInt(comboBox.Name);
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Code/IO/Installer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/n00mkrad/cupscale/35d418c55c80c5426ebd2695c0396c7ad3cc7605/Code/IO/Installer.cs
--------------------------------------------------------------------------------
/Code/IO/Paths.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Cupscale.UI;
3 | using System.IO;
4 |
5 | namespace Cupscale.IO
6 | {
7 | internal class Paths
8 | {
9 |
10 | public static string binPath;
11 | public static string defaultModelPath;
12 | public static string previewPath;
13 | public static string previewOutPath;
14 | public static string imgInPath;
15 | public static string imgOutPath;
16 | public static string tempImgPath;
17 | public static string clipboardFolderPath;
18 | public static string presetsPath;
19 | public static string compositionOut;
20 | public static string framesOutPath;
21 |
22 | public static readonly string pythonTuringPath = "flowframes/setupfiles/py-tu/v1/py-tu.7z";
23 | public static readonly string pythonAmperePath = "flowframes/setupfiles/py-amp/v1/py-amp.7z";
24 |
25 | public static readonly string ncnnMdlDir = ".ncnn-models";
26 |
27 | public static void Init()
28 | {
29 | binPath = Path.Combine(GetDataPath(), "bin");
30 |
31 | defaultModelPath = Path.Combine(GetDataPath(), "models");
32 | Directory.CreateDirectory(defaultModelPath);
33 |
34 | previewPath = Path.Combine(GetDataPath(), "preview");
35 | Directory.CreateDirectory(previewPath);
36 |
37 | previewOutPath = Path.Combine(GetDataPath(), "preview-out");
38 | Directory.CreateDirectory(previewOutPath);
39 |
40 | imgInPath = Path.Combine(GetDataPath(), "img-in");
41 | Directory.CreateDirectory(imgInPath);
42 |
43 | imgOutPath = Path.Combine(GetDataPath(), "img-out");
44 | Directory.CreateDirectory(imgOutPath);
45 |
46 | tempImgPath = Path.Combine(GetDataPath(), "loaded-img", "temp.png");
47 | Directory.CreateDirectory(tempImgPath.GetParentDir());
48 |
49 | clipboardFolderPath = Path.Combine(GetDataPath(), "clipboard");
50 | Directory.CreateDirectory(clipboardFolderPath);
51 |
52 | presetsPath = Path.Combine(GetDataPath(), "model-presets");
53 | Directory.CreateDirectory(presetsPath);
54 |
55 | compositionOut = Path.Combine(GetDataPath(), "composition");
56 | Directory.CreateDirectory(compositionOut);
57 |
58 | framesOutPath = Path.Combine(GetDataPath(), "frames-out");
59 | Directory.CreateDirectory(framesOutPath);
60 | }
61 |
62 | public static string GetDataPath()
63 | {
64 | string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
65 | path = Path.Combine(path, "Cupscale");
66 |
67 | if (IoUtils.IsPortable())
68 | {
69 | if (!IoUtils.hasShownPortableInfo)
70 | {
71 | Logger.Log("Running in portable mode. Data folder: " + Path.Combine(GetExeDir(), "CupscaleData"), false);
72 | IoUtils.hasShownPortableInfo = true;
73 | }
74 | path = Path.Combine(GetExeDir(), "CupscaleData");
75 | }
76 |
77 | Directory.CreateDirectory(path);
78 | return path;
79 | }
80 |
81 | public static string GetExeDir()
82 | {
83 | return AppDomain.CurrentDomain.BaseDirectory;
84 | }
85 |
86 | public static string GetAiDir (Implementations.Implementation impl)
87 | {
88 | return Path.Combine(binPath, impl.dir);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Code/ImageUtils/Filters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Cupscale.ImageUtils
8 | {
9 | class Filters
10 | {
11 | public static Filter mitchell = new Filter { Name = "Mitchell", Alias = "Mitchell" };
12 | public static Filter bicubic = new Filter { Name = "Catrom", Alias = "Bicubic" };
13 | public static Filter nearest = new Filter { Name = "Point", Alias = "Nearest Neighbor" };
14 | public static Filter lanczos = new Filter { Name = "Lanczos", Alias = "Lanczos" };
15 | //public static Filter lanczos2 = new Filter { Name = "Lanczos2", Alias = "Lanczos 2" };
16 | //public static Filter lanczos2Sharp = new Filter { Name = "Lanczos2Sharp", Alias = "Lanczos 2 Sharp" };
17 |
18 | public static List allFilters = new List { mitchell, bicubic, nearest, lanczos };
19 | public static List previewFilters = new List { bicubic, nearest };
20 | public static List resizeFilters = new List { mitchell, bicubic, nearest, lanczos };
21 |
22 | public class Filter
23 | {
24 | public string Name = "";
25 | public string Alias = "";
26 | }
27 |
28 | public static Filter GetFilter(string alias)
29 | {
30 | foreach(Filter f in allFilters)
31 | {
32 | if (f.Alias == alias)
33 | return f;
34 | }
35 |
36 | return mitchell;
37 | }
38 |
39 | public static ImageMagick.FilterType GetMagickFilter(string alias)
40 | {
41 | return (ImageMagick.FilterType)Enum.Parse(typeof(ImageMagick.FilterType), GetFilter(alias).Name);
42 | }
43 |
44 | public static ImageMagick.FilterType GetMagickFilter(Filter filter)
45 | {
46 | return (ImageMagick.FilterType)Enum.Parse(typeof(ImageMagick.FilterType), filter.Name);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Code/ImageUtils/ImageOperations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Drawing2D;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace Cupscale.ImageUtils
10 | {
11 | class ImageOperations
12 | {
13 | public static Image Scale (Image img, float scale = 1f, InterpolationMode filtering = InterpolationMode.NearestNeighbor)
14 | {
15 | var destImage = new Bitmap((int)Math.Round(img.Width * scale), (int)Math.Round(img.Height * scale));
16 |
17 | using (var graphics = Graphics.FromImage(destImage))
18 | {
19 | graphics.CompositingMode = CompositingMode.SourceCopy;
20 | graphics.CompositingQuality = CompositingQuality.HighQuality;
21 | graphics.InterpolationMode = filtering;
22 | graphics.SmoothingMode = SmoothingMode.HighQuality;
23 | graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
24 |
25 | graphics.DrawImage(img, 0, 0, destImage.Width, destImage.Height); // Scale up
26 | }
27 |
28 | return destImage;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Code/ImageUtils/ImgUtils.cs:
--------------------------------------------------------------------------------
1 | using DdsFileTypePlus;
2 | using ImageMagick;
3 | using Microsoft.WindowsAPICodePack.Shell;
4 | using PaintDotNet;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.Drawing;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Text;
12 | using System.Threading.Tasks;
13 | using System.Windows.Forms;
14 | using System.Windows.Media.Imaging;
15 |
16 | namespace Cupscale.ImageUtils
17 | {
18 | class ImgUtils
19 | {
20 | public static Image GetImage(string path)
21 | {
22 | if (Logger.doLogIo) Logger.Log("[ImgUtils] Reading Image from " + path);
23 | using MemoryStream stream = new MemoryStream(File.ReadAllBytes(path));
24 | Image img = Image.FromStream(stream);
25 | if (Logger.doLogIo) Logger.Log("[OK]", true, true);
26 | return img;
27 | }
28 |
29 | public static MagickImage GetMagickImage(string path, bool allowTgaFlip = false)
30 | {
31 | if (Logger.doLogIo) Logger.Log("[ImgUtils] Reading MagickImage from " + path);
32 | MagickImage image;
33 | if (Path.GetExtension(path).ToLower() == ".dds")
34 | {
35 | try
36 | {
37 | image = new MagickImage(path); // Try reading DDS with IM, fall back to DdsFileTypePlusHack if it fails
38 | }
39 | catch (Exception magickEx)
40 | {
41 | Logger.Log($"[ImgUtils] Failed to read DDS using Magick.NET ({magickEx.Message}) - Trying DdsFileTypePlusHack");
42 | try
43 | {
44 | Surface surface = DdsFile.Load(path);
45 | image = ConvertToMagickImage(surface);
46 | image.HasAlpha = DdsFile.HasTransparency(surface);
47 | }
48 | catch (Exception ddsEx)
49 | {
50 | Logger.ErrorMessage("[ImgUtils] This DDS format appears to be incompatible.", ddsEx);
51 | return null;
52 | }
53 | }
54 | }
55 | else
56 | {
57 | image = new MagickImage(path);
58 | }
59 | if (allowTgaFlip && Path.GetExtension(path).ToLower() == ".tga" && Config.GetBool("flipTga"))
60 | {
61 | image.Flip();
62 | if (Logger.doLogIo) Logger.Log("[Flipped TGA]", true, true);
63 | }
64 | if (Logger.doLogIo) Logger.Log("[OK]", true, true);
65 | return image;
66 | }
67 |
68 | public static MagickImage ConvertToMagickImage(Surface surface)
69 | {
70 | MagickImage result;
71 | Bitmap bitmap = surface.CreateAliasedBitmap();
72 | using (MemoryStream memoryStream = new MemoryStream())
73 | {
74 | bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
75 | memoryStream.Position = 0;
76 | result = new MagickImage(memoryStream, new MagickReadSettings() { Format = MagickFormat.Png00 });
77 | }
78 | return result;
79 | }
80 |
81 | public static float GetScale(Image imgFrom, Image imgTo)
82 | {
83 | return (int)Math.Round(GetScaleFloat(imgFrom, imgTo));
84 | }
85 |
86 | public static float GetScaleFloat(Image imgFrom, Image imgTo)
87 | {
88 | return (float)imgTo.Width / (float)imgFrom.Width;
89 | }
90 |
91 | public static MagickImage FillAlphaWithBgColor(MagickImage img)
92 | {
93 | return FillAlphaWithColor(img, new MagickColor("#" + Config.Get("alphaBgColor")));
94 | }
95 |
96 | public static MagickImage FillAlphaWithColor(MagickImage img, MagickColor color)
97 | {
98 | MagickImage bg = new MagickImage(color, img.Width, img.Height);
99 | bg.BackgroundColor = color;
100 | bg.Composite(img, CompositeOperator.Over);
101 |
102 | return bg;
103 | }
104 |
105 | public static int GetColorDepth(string path)
106 | {
107 | try
108 | {
109 | ShellFile shellFile = ShellFile.FromFilePath(path);
110 | int depth = (int)shellFile.Properties.System.Image.BitDepth.Value;
111 | return depth;
112 | //MemoryStream stream = new MemoryStream(File.ReadAllBytes(path));
113 | //var source = BitmapFrame.Create(stream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnDemand);
114 | //return source.Format.BitsPerPixel;
115 | }
116 | catch (Exception e)
117 | {
118 | Logger.Log("[ImgUtils] Failed to read color depth: " + e.Message + " - Defaulting to 32.");
119 | return 32;
120 | }
121 | }
122 |
123 | public static MagickImage MergeImages(string[] imgs, bool vertically, bool deleteSourceImgs)
124 | {
125 | MagickImageCollection collection = new MagickImageCollection();
126 |
127 | foreach (string img in imgs)
128 | {
129 | collection.Add(img);
130 | if (deleteSourceImgs)
131 | File.Delete(img);
132 | }
133 |
134 | if (!vertically)
135 | return (MagickImage)collection.AppendHorizontally();
136 | else
137 | return (MagickImage)collection.AppendVertically();
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Code/ImageUtils/MozJpeg.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using MozJpegSharp;
6 |
7 | namespace Cupscale.ImageUtils
8 | {
9 | class MozJpeg
10 | {
11 | public static void Encode(string inPath, string outPath, int q, bool chromaSubSample = true)
12 | {
13 | try
14 | {
15 | Bitmap bmp = (Bitmap)ImgUtils.GetImage(inPath);
16 | var commpressor = new TJCompressor();
17 | byte[] compressed;
18 | TJSubsamplingOption subSample = TJSubsamplingOption.Chrominance420;
19 | if (!chromaSubSample)
20 | subSample = TJSubsamplingOption.Chrominance444;
21 | compressed = commpressor.Compress(bmp, subSample, q, TJFlags.None);
22 | File.WriteAllBytes(outPath, compressed);
23 | Logger.Log("[MozJpeg] Written image to " + outPath);
24 | }
25 | catch (TypeInitializationException e)
26 | {
27 | Logger.ErrorMessage($"MozJpeg Initialization Error: {e.InnerException.Message}\n", e);
28 | }
29 | catch (Exception e)
30 | {
31 | Logger.ErrorMessage("MozJpeg Error: ", e);
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Code/ImageUtils/NvCompress.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.UI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace Cupscale.ImageUtils
12 | {
13 | class NvCompress
14 | {
15 | static Process currentProcess;
16 |
17 | public static async Task PngToDds (string inputFile, string outputPath)
18 | {
19 | string dxtString = Config.Get("dxtMode").ToLower().Replace("argb", "rgb");
20 | if (dxtString.Contains(" "))
21 | dxtString = dxtString.Split(' ')[0];
22 | await Run(inputFile, outputPath, dxtString, Config.GetBool("alpha"), Config.GetBool("ddsEnableMips"));
23 |
24 | }
25 |
26 | public static async Task Run(string inpath, string outpath, string dxtMode, bool alpha, bool enableMips)
27 | {
28 | bool showWindow = Config.GetInt("cmdDebugMode") > 0;
29 | bool stayOpen = Config.GetInt("cmdDebugMode") == 2;
30 |
31 | if (Path.GetExtension(inpath).ToLower() != ".png")
32 | {
33 | string newPath = Path.ChangeExtension(inpath, "png");
34 | File.Move(inpath, newPath);
35 | inpath = newPath;
36 | }
37 |
38 | string alphaStr = "";
39 | if (alpha)
40 | alphaStr = "-alpha";
41 |
42 | string mipStr = "-nomips";
43 | if (enableMips)
44 | mipStr = "";
45 |
46 | string opt = "/C";
47 | if (stayOpen) opt = "/K";
48 |
49 | string args = $"{opt} cd /D {Paths.binPath.Wrap()} & ";
50 | args += $"nvcompress.exe -{dxtMode} {alphaStr} {mipStr} {inpath.Wrap()} {outpath.Wrap()}";
51 | Logger.Log("[CMD] " + args);
52 | Process nvCompress = new Process();
53 | nvCompress.StartInfo.UseShellExecute = showWindow;
54 | nvCompress.StartInfo.RedirectStandardOutput = !showWindow;
55 | nvCompress.StartInfo.RedirectStandardError = !showWindow;
56 | nvCompress.StartInfo.CreateNoWindow = !showWindow;
57 | nvCompress.StartInfo.FileName = "cmd.exe";
58 | nvCompress.StartInfo.Arguments = args;
59 | if (!showWindow)
60 | {
61 | nvCompress.OutputDataReceived += OutputHandler;
62 | nvCompress.ErrorDataReceived += OutputHandler;
63 | }
64 | currentProcess = nvCompress;
65 | nvCompress.Start();
66 | if (!showWindow)
67 | {
68 | nvCompress.BeginOutputReadLine();
69 | nvCompress.BeginErrorReadLine();
70 | }
71 |
72 | while (!nvCompress.HasExited)
73 | await Task.Delay(50);
74 |
75 | if (inpath.ToLower() != outpath.ToLower())
76 | File.Delete(inpath);
77 | }
78 |
79 | private static void OutputHandler(object sendingProcess, DataReceivedEventArgs output)
80 | {
81 | if (output == null || output.Data == null)
82 | return;
83 |
84 | string data = output.Data;
85 |
86 | if(data.Length >= 4)
87 | Logger.Log("[NvCompress] " + data.Replace("\n", " ").Replace("\r", " "));
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Code/Implementations/EsrganNcnn.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Cupscale;
2 | using Cupscale.IO;
3 | using Cupscale.Main;
4 | using Upscale = Cupscale.Main.Upscale;
5 | using Cupscale.UI;
6 | using System;
7 | using System.Diagnostics;
8 | using System.Drawing;
9 | using System.IO;
10 | using System.Threading.Tasks;
11 | using Paths = Cupscale.IO.Paths;
12 | using Cupscale.Implementations;
13 | using Cupscale.OS;
14 | using Cupscale.Data;
15 |
16 | namespace Cupscale.Implementations
17 | {
18 | class EsrganNcnn : ImplementationBase
19 | {
20 | static readonly string exeName = "esrgan-ncnn-vulkan.exe";
21 |
22 | public static async Task Run(string inpath, string outpath, ModelData mdl)
23 | {
24 | if (!CheckIfExeExists(Imps.esrganNcnn, exeName))
25 | return;
26 |
27 | string modelPath = mdl.model1Path;
28 | Program.lastModelName = mdl.model1Name;
29 |
30 | bool showWindow = Config.GetInt("cmdDebugMode") > 0;
31 | bool stayOpen = Config.GetInt("cmdDebugMode") == 2;
32 |
33 | Program.mainForm.SetProgress(1f, "Converting model...");
34 | await NcnnUtils.ConvertNcnnModel(modelPath, "x*");
35 | Logger.Log("[ESRGAN] NCNN Model is ready: " + NcnnUtils.currentNcnnModel);
36 | Program.mainForm.SetProgress(3f, "Loading ESRGAN (NCNN)...");
37 | int scale = NcnnUtils.GetNcnnModelScale(NcnnUtils.currentNcnnModel);
38 | string opt = stayOpen ? "/K" : "/C";
39 | string tta = Config.GetBool("esrganNcnnTta") ? "-x" : "";
40 | string ts = Config.GetInt("esrganNcnnTilesize") >= 32 ? $"-t {Config.GetInt("esrganNcnnTilesize")}" : "";
41 | string cmd = $"{opt} cd /D {Path.Combine(Paths.binPath, Imps.esrganNcnn.dir).Wrap()} & {exeName} -i {inpath.Wrap()} -o {outpath.Wrap()}" +
42 | $" -g {Config.GetInt("esrganNcnnGpu")} -m {NcnnUtils.currentNcnnModel.Wrap()} -s {scale} {tta} {ts}";
43 | Logger.Log("[CMD] " + cmd);
44 |
45 | Process proc = OsUtils.NewProcess(!showWindow);
46 | proc.StartInfo.Arguments = cmd;
47 |
48 | if (!showWindow)
49 | {
50 | proc.OutputDataReceived += (sender, outLine) => { OutputHandler(outLine.Data, false); };
51 | proc.ErrorDataReceived += (sender, outLine) => { OutputHandler(outLine.Data, true); };
52 | }
53 |
54 | Program.lastImpProcess = proc;
55 | proc.Start();
56 |
57 | if (!showWindow)
58 | {
59 | proc.BeginOutputReadLine();
60 | proc.BeginErrorReadLine();
61 | }
62 |
63 | while (!proc.HasExited)
64 | await Task.Delay(50);
65 |
66 | if (Upscale.currentMode == Upscale.UpscaleMode.Batch)
67 | {
68 | await Task.Delay(1000);
69 | Program.mainForm.SetProgress(100f, "Post-Processing...");
70 | PostProcessingQueue.Stop();
71 | }
72 | }
73 |
74 | private static void OutputHandler(string line, bool error)
75 | {
76 | if (string.IsNullOrWhiteSpace(line) || line.Length < 6)
77 | return;
78 |
79 | Logger.Log("[NCNN] " + line.Replace("\n", " ").Replace("\r", " "));
80 |
81 | if(error)
82 | GeneralOutputHandler.HandleImpErrorMsgs(line, GeneralOutputHandler.ProcessType.Ncnn);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Code/Implementations/Implementation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Cupscale.Implementations
8 | {
9 | public class Implementation
10 | {
11 | public string name = "";
12 | public string dir = "";
13 | public bool supportsModels = true;
14 | public bool supportsInterp = true;
15 | public bool supportsChain = true;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Code/Implementations/ImplementationBase.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace Cupscale.Implementations
10 | {
11 | public abstract class ImplementationBase
12 | {
13 | public static bool CheckIfExeExists (Implementation implementation, string exeName)
14 | {
15 | if (!File.Exists(Path.Combine(Paths.binPath, implementation.dir, exeName)))
16 | {
17 | Program.ShowMessage($"Error: The executable is missing:\n\n{exeName}\n\nPossibly your installation is incomplete?", "Error");
18 | return false;
19 | }
20 |
21 | return true;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Code/Implementations/Imps.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Cupscale.Implementations
8 | {
9 | class Imps
10 | {
11 | public static List impList = new List();
12 |
13 | public static Implementation esrganPytorch = new Implementation
14 | { name="ESRGAN (Pytorch)", dir = "esrgan-pytorch", supportsInterp = true, supportsChain = true };
15 |
16 | public static Implementation esrganNcnn = new Implementation
17 | { name = "ESRGAN (NCNN)", dir = "esrgan-ncnn", supportsInterp = false, supportsChain = false };
18 |
19 | public static Implementation realEsrganNcnn = new Implementation
20 | { name = "RealESRGAN (NCNN)", dir = "realesrgan-ncnn", supportsInterp = false, supportsChain = false };
21 |
22 | public static void Init()
23 | {
24 | impList.Clear();
25 | impList.Add(esrganPytorch);
26 | impList.Add(esrganNcnn);
27 | impList.Add(realEsrganNcnn);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Code/Implementations/RealEsrganNcnn.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Cupscale;
2 | using Cupscale.IO;
3 | using Cupscale.Main;
4 | using Upscale = Cupscale.Main.Upscale;
5 | using Cupscale.UI;
6 | using System;
7 | using System.Diagnostics;
8 | using System.IO;
9 | using System.Linq.Expressions;
10 | using System.Threading.Tasks;
11 | using Paths = Cupscale.IO.Paths;
12 | using Cupscale.Implementations;
13 | using Cupscale.OS;
14 | using Cupscale.Data;
15 |
16 | namespace Cupscale.Implementations
17 | {
18 | class RealEsrganNcnn : ImplementationBase
19 | {
20 | static readonly string exeName = "realesrgan-ncnn-vulkan.exe";
21 |
22 | public static async Task Run(string inpath, string outpath, ModelData mdl)
23 | {
24 | if (!CheckIfExeExists(Imps.realEsrganNcnn, exeName))
25 | return;
26 |
27 | string modelPath = mdl.model1Path;
28 | Program.lastModelName = mdl.model1Name;
29 |
30 | bool showWindow = Config.GetInt("cmdDebugMode") > 0;
31 | bool stayOpen = Config.GetInt("cmdDebugMode") == 2;
32 |
33 | Program.mainForm.SetProgress(1f, "Converting model...");
34 | await NcnnUtils.ConvertNcnnModel(modelPath, "esrgan-x*");
35 | Logger.Log("[ESRGAN] NCNN Model is ready: " + NcnnUtils.currentNcnnModel);
36 | Program.mainForm.SetProgress(3f, "Loading RealESRGAN (NCNN)...");
37 | int scale = NcnnUtils.GetNcnnModelScale(NcnnUtils.currentNcnnModel);
38 |
39 | if(scale != 4)
40 | {
41 | Program.ShowMessage($"Error: This implementation currently only supports 4x scale models.", "Error");
42 | return;
43 | }
44 |
45 | string opt = stayOpen ? "/K" : "/C";
46 | string tta = Config.GetBool("realEsrganNcnnTta") ? "-x" : "";
47 | string ts = Config.GetInt("realEsrganNcnnTilesize") >= 32 ? $"-t {Config.GetInt("realEsrganNcnnTilesize")}" : "";
48 | string cmd = $"{opt} cd /D {Path.Combine(Paths.binPath, Imps.realEsrganNcnn.dir).Wrap()} & {exeName} -i {inpath.Wrap()} -o {outpath.Wrap()}" +
49 | $" -g {Config.GetInt("realEsrganNcnnGpus")} -m {NcnnUtils.currentNcnnModel.Wrap()} -n esrgan-x4 -s {scale} {tta} {ts}";
50 | Logger.Log("[CMD] " + cmd);
51 |
52 | Process proc = OsUtils.NewProcess(!showWindow);
53 | proc.StartInfo.Arguments = cmd;
54 |
55 | if (!showWindow)
56 | {
57 | proc.OutputDataReceived += (sender, outLine) => { OutputHandler(outLine.Data, false); };
58 | proc.ErrorDataReceived += (sender, outLine) => { OutputHandler(outLine.Data, true); };
59 | }
60 |
61 | Program.lastImpProcess = proc;
62 | proc.Start();
63 |
64 | if (!showWindow)
65 | {
66 | proc.BeginOutputReadLine();
67 | proc.BeginErrorReadLine();
68 | }
69 |
70 | while (!proc.HasExited)
71 | await Task.Delay(50);
72 |
73 | if (Upscale.currentMode == Upscale.UpscaleMode.Batch)
74 | {
75 | await Task.Delay(1000);
76 | Program.mainForm.SetProgress(100f, "Post-Processing...");
77 | PostProcessingQueue.Stop();
78 | }
79 |
80 | }
81 |
82 | private static void OutputHandler(string line, bool error)
83 | {
84 | if (string.IsNullOrWhiteSpace(line) || line.Length < 6)
85 | return;
86 |
87 | Logger.Log("[NCNN] " + line.Replace("\n", " ").Replace("\r", " "));
88 |
89 | bool showTileProgress = Upscale.currentMode == Upscale.UpscaleMode.Preview || Upscale.currentMode == Upscale.UpscaleMode.Single;
90 |
91 | if (showTileProgress && line.Trim().EndsWith("%"))
92 | {
93 | float percent = float.Parse(line.Replace("%", "").Replace(",", ".")) / 100f;
94 | Program.mainForm.SetProgress(percent, $"Upscaling Tiles ({percent}%)");
95 | }
96 |
97 | if (error)
98 | GeneralOutputHandler.HandleImpErrorMsgs(line, GeneralOutputHandler.ProcessType.Ncnn);
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/Code/Main/AdvancedModelSelection.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.UI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Diagnostics.Contracts;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace Cupscale.Main
12 | {
13 | class AdvancedModelSelection
14 | {
15 | // Models
16 | public static string e1m1;
17 | public static string e1m2;
18 |
19 | public static string e2m1;
20 | public static string e2m2;
21 |
22 | public static string e3m1;
23 | public static string e3m2;
24 |
25 | // Interp values
26 | public static int e1m1i;
27 | public static int e1m2i;
28 |
29 | public static int e2m1i;
30 | public static int e2m2i;
31 |
32 | public static int e3m1i;
33 | public static int e3m2i;
34 |
35 | public static void SavePreset (string name)
36 | {
37 | string saveData = $"name|{name}" + Environment.NewLine
38 | + $"e1m1|{e1m1}" + Environment.NewLine
39 | + $"e1m1i|{e1m1i}" + Environment.NewLine
40 | + $"e1m2|{e1m2}" + Environment.NewLine
41 | + $"e1m2i|{e1m2i}" + Environment.NewLine
42 | + $"e2m1|{e2m1}" + Environment.NewLine
43 | + $"e2m1i|{e2m1i}" + Environment.NewLine
44 | + $"e2m2|{e2m2}" + Environment.NewLine
45 | + $"e2m2i|{e2m2i}" + Environment.NewLine
46 | + $"e3m1|{e3m1}" + Environment.NewLine
47 | + $"e3m1i|{e3m1i}" + Environment.NewLine
48 | + $"e3m2|{e3m2}" + Environment.NewLine
49 | + $"e3m2i|{e3m2i}";
50 |
51 | string path = Path.Combine(Paths.presetsPath, name);
52 | File.WriteAllText(path, saveData);
53 | Logger.Log("Saved model preset to " + path);
54 | }
55 |
56 | public static bool LoadPreset(string name)
57 | {
58 | string path = Path.Combine(Paths.presetsPath, name);
59 | if (!File.Exists(path))
60 | return false;
61 |
62 | string[] saveDataLines = IoUtils.ReadLines(path);
63 | foreach(string line in saveDataLines)
64 | {
65 | string[] keyValuePair = line.Split('|');
66 | switch (keyValuePair[0])
67 | {
68 | case "e1m1": e1m1 = keyValuePair[1]; break;
69 | case "e1m1i": e1m1i = keyValuePair[1].GetInt(); break;
70 | case "e1m2": e1m2 = keyValuePair[1]; break;
71 | case "e1m2i": e1m2i = keyValuePair[1].GetInt(); break;
72 |
73 | case "e2m1": e2m1 = keyValuePair[1]; break;
74 | case "e2m1i": e2m1i = keyValuePair[1].GetInt(); break;
75 | case "e2m2": e2m2 = keyValuePair[1]; break;
76 | case "e2m2i": e2m2i = keyValuePair[1].GetInt(); break;
77 |
78 | case "e3m1": e3m1 = keyValuePair[1]; break;
79 | case "e3m1i": e3m1i = keyValuePair[1].GetInt(); break;
80 | case "e3m2": e3m2 = keyValuePair[1]; break;
81 | case "e3m2i": e3m2i = keyValuePair[1].GetInt(); break;
82 | }
83 | }
84 |
85 | Logger.Log("Loaded model preset " + name);
86 | return true;
87 | }
88 |
89 | public static string GetArg ()
90 | {
91 | string arg = "";
92 |
93 | Logger.Log("e1m1i: " + e1m1i + " e1m2: " + e1m2 + " e1m2i: " + e1m2i);
94 | arg = e1m1;
95 |
96 | // Add Entry 1
97 | if (!string.IsNullOrWhiteSpace(e1m2)) // Check if entry 1 has a second model
98 | arg += $";{e1m1i}&{e1m2};{e1m2i}";
99 |
100 | // Add Entry 2
101 | if (!string.IsNullOrWhiteSpace(e2m1)) // Check if entry 2 is used
102 | {
103 | arg += $">{e2m1}";
104 |
105 | if (!string.IsNullOrWhiteSpace(e2m2)) // Check if entry 2 has a second model
106 | arg += $";{e2m1i}&{e2m2};{e2m2i}";
107 | }
108 |
109 | // Add Entry 3
110 | if (!string.IsNullOrWhiteSpace(e3m1)) // Check if entry 3 is used
111 | {
112 | arg += $">{e3m1}";
113 |
114 | if (!string.IsNullOrWhiteSpace(e3m2)) // Check if entry 3 has a second model
115 | arg += $";{e3m1i}&{e3m2};{e3m2i}";
116 | }
117 |
118 | arg = arg.Wrap(true, false);
119 |
120 | return arg;
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/Code/Main/Dependencies.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.OS;
2 | using Cupscale.UI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using System.Management;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace Cupscale.Main
11 | {
12 | class Dependencies
13 | {
14 | public static bool HasGpu()
15 | {
16 | ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DisplayConfiguration");
17 |
18 | string graphicsCard = string.Empty;
19 |
20 | foreach (ManagementObject mo in searcher.Get())
21 | {
22 | foreach (PropertyData property in mo.Properties)
23 | {
24 | if (property.Name == "Description")
25 | {
26 | graphicsCard = property.Value.ToString();
27 | if (string.IsNullOrWhiteSpace(graphicsCard) || graphicsCard.ToLower().Contains("microsoft"))
28 | return false;
29 | Logger.Log("[DepCheck] Found GPU: " + graphicsCard);
30 | return true;
31 | }
32 | }
33 | }
34 |
35 | Logger.Log("[DepCheck] No GPU found!");
36 | return false;
37 | }
38 |
39 | public static bool SysPyAvail ()
40 | {
41 | string sysPyVer = GetSysPyVersion();
42 |
43 | if (!string.IsNullOrWhiteSpace(sysPyVer) && !sysPyVer.ToLower().Contains("not found") && sysPyVer.Length <= 35)
44 | return true;
45 |
46 | return false;
47 | }
48 |
49 | public static string GetSysPyVersion()
50 | {
51 | string pythonOut = GetSysPythonOutput();
52 | Logger.Log("[DepCheck] System Python Check Output: " + pythonOut.Trim());
53 |
54 | try
55 | {
56 | string ver = pythonOut.Split('(')[0].Trim();
57 | Logger.Log("[DepCheck] Sys Python Ver: " + ver);
58 | return ver;
59 | }
60 | catch
61 | {
62 | return "";
63 | }
64 | }
65 |
66 | public static bool EmbedPyAvail()
67 | {
68 | string embedPyVer = GetEmbedPyVersion();
69 |
70 | if (!string.IsNullOrWhiteSpace(embedPyVer) && !embedPyVer.ToLower().Contains("not found") && embedPyVer.Length <= 35)
71 | return true;
72 |
73 | return false;
74 | }
75 |
76 | public static string GetEmbedPyVersion()
77 | {
78 | string pythonOut = GetEmbedPythonOutput();
79 | Logger.Log("[DepCheck] Embed Python Check Output: " + pythonOut.Trim());
80 |
81 | try
82 | {
83 | string ver = pythonOut.Split('(')[0].Trim();
84 | Logger.Log("[DepCheck] Embed Python Ver: " + ver);
85 | return ver;
86 | }
87 | catch
88 | {
89 | return "";
90 | }
91 | }
92 |
93 | public static string GetSysPythonOutput()
94 | {
95 | Process py = OsUtils.NewProcess(true);
96 | py.StartInfo.Arguments = "/C python -V";
97 | Logger.Log("[DepCheck] CMD: " + py.StartInfo.Arguments);
98 | py.Start();
99 | py.WaitForExit();
100 | string output = py.StandardOutput.ReadToEnd();
101 | string err = py.StandardError.ReadToEnd();
102 | return output + "\n" + err;
103 | }
104 |
105 | public static string GetEmbedPythonOutput()
106 | {
107 | Process py = OsUtils.NewProcess(true);
108 | py.StartInfo.Arguments = "/C " + EmbeddedPython.GetEmbedPyPath().Wrap() + " -V";
109 | Logger.Log("[DepCheck] CMD: " + py.StartInfo.Arguments);
110 | py.Start();
111 | py.WaitForExit();
112 | string output = py.StandardOutput.ReadToEnd();
113 | string err = py.StandardError.ReadToEnd();
114 | if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
115 | return output;
116 | }
117 |
118 | public static string GetPytorchVer()
119 | {
120 | try
121 | {
122 | Process py = OsUtils.NewProcess(true);
123 | py.StartInfo.Arguments = "\"/C\" " + EmbeddedPython.GetPyCmd() + " -c \"import torch; print(torch.__version__)\"";
124 | Logger.Log("[DepCheck] CMD: " + py.StartInfo.Arguments);
125 | py.Start();
126 | py.WaitForExit();
127 | string output = py.StandardOutput.ReadToEnd();
128 | string err = py.StandardError.ReadToEnd();
129 | if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
130 | Logger.Log("[DepCheck] Pytorch Check Output: " + output.Trim());
131 | return output;
132 | }
133 | catch
134 | {
135 | return "";
136 | }
137 | }
138 |
139 | public static string GetOpenCvVer()
140 | {
141 | try
142 | {
143 | Process py = OsUtils.NewProcess(true);
144 | py.StartInfo.Arguments = "\"/C\" " + EmbeddedPython.GetPyCmd() + " -c \"import cv2; print(cv2.__version__)\"";
145 | Logger.Log("[DepCheck] CMD: " + py.StartInfo.Arguments);
146 | py.Start();
147 | py.WaitForExit();
148 | string output = py.StandardOutput.ReadToEnd();
149 | string err = py.StandardError.ReadToEnd();
150 | if (!string.IsNullOrWhiteSpace(err)) output += "\n" + err;
151 | Logger.Log("[DepCheck] CV2 Check Output: " + output.Trim());
152 | return output;
153 | }
154 | catch
155 | {
156 | return "";
157 | }
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Code/Main/EsrganData.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Forms;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Windows.Forms;
5 |
6 | namespace Cupscale
7 | {
8 | internal class EsrganData
9 | {
10 | public static List models = new List();
11 | public static List modelsFullPath = new List();
12 |
13 | public static void CheckModelDir()
14 | {
15 | if (string.IsNullOrWhiteSpace(Config.Get("modelPath")))
16 | {
17 | Program.ShowMessage("Please set a model path in the settings.\nPoint it to the folder where you save your .pth model files.", "Notice");
18 | new SettingsForm().ShowDialog();
19 | }
20 | else if (!Directory.Exists(Config.Get("modelPath")))
21 | {
22 | Program.ShowMessage("The model path you entered isn't valid!", "Notice");
23 | new SettingsForm().ShowDialog();
24 | }
25 | }
26 |
27 | public static bool ModelExists (string modelName)
28 | {
29 | string[] files = Directory.GetFiles("*.pth", Config.Get("modelPath"), SearchOption.AllDirectories);
30 | foreach(string modelFile in files)
31 | {
32 | if (Path.GetFileNameWithoutExtension(modelFile) == modelName)
33 | return true;
34 | }
35 | return false;
36 | }
37 |
38 | public static void ReloadModelList()
39 | {
40 | string mdlPath = Config.Get("modelPath");
41 | if (!Directory.Exists(mdlPath))
42 | {
43 | Logger.Log("[EsrganData] Model dir doesn't exist!");
44 | return;
45 | }
46 | models.Clear();
47 | modelsFullPath.Clear();
48 | string[] files = Directory.GetFiles(mdlPath);
49 | string[] array = files;
50 | foreach (string path in array)
51 | {
52 | string fileName = Path.GetFileName(path);
53 | if (fileName.EndsWith(".pth"))
54 | {
55 | models.Add(fileName.Replace(".pth", ""));
56 | modelsFullPath.Add(path);
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Code/Main/GeneralOutputHandler.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.UI;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Cupscale.Main
9 | {
10 | class GeneralOutputHandler
11 | {
12 | public enum ProcessType { Generic, Python, Ncnn }
13 |
14 | public static void HandleImpErrorMsgs(string log, ProcessType processType = ProcessType.Generic)
15 | {
16 | bool errored = false;
17 |
18 | if (processType == ProcessType.Ncnn)
19 | {
20 | if (!errored && log.Contains("vkAllocateMemory"))
21 | {
22 | Program.Cancel("NCNN ran out of memory.\nTry reducing the tile size and avoid " +
23 | "running programs in the background (especially games) that take up your VRAM.");
24 | errored = true;
25 | }
26 |
27 | if (!errored && log.Contains("vkWaitForFences"))
28 | {
29 | Program.Cancel("NCNN crashed!\nMake sure your GPU drivers are up to date, try reducing the tile size and avoid " +
30 | "running programs in the background (especially games) that take up your VRAM.");
31 | errored = true;
32 | }
33 | }
34 |
35 | if (processType == ProcessType.Python)
36 | {
37 | if (log.ToLower().Contains("out of memory"))
38 | {
39 | Program.ShowMessage("ESRGAN ran out of memory. Try reducing the tile size and avoid running programs in the background (especially games) that take up your VRAM.", "Error");
40 | errored = true;
41 | }
42 |
43 | if (log.Contains("Python was not found"))
44 | {
45 | Program.Cancel("Python was not found. Make sure you have a working Python 3 installation, or use the embedded runtime.");
46 | errored = true;
47 | }
48 |
49 | if (log.Contains("ModuleNotFoundError"))
50 | {
51 | Program.Cancel("You are missing Python dependencies. Make sure Pytorch and cv2 (opencv-python) are installed.");
52 | errored = true;
53 | }
54 |
55 | if (log.Contains("RRDBNet"))
56 | {
57 | Program.Cancel("Model appears to be incompatible!");
58 | errored = true;
59 | }
60 |
61 | if (log.Contains("UnpicklingError"))
62 | {
63 | Program.Cancel("Failed to load model!\nPossibly it's corrupted or in an unknown format.");
64 | errored = true;
65 | }
66 |
67 | if (log.Contains("must match the size of tensor") || log.Contains("KeyError: 'model.") || log.Contains("KeyError: 'conv_first.weight'"))
68 | {
69 | Program.Cancel("It seems like you tried to load or interpolate incompatible models!");
70 | errored = true;
71 | }
72 |
73 | if (log.Contains("not implemented for 'Half'"))
74 | {
75 | Program.Cancel("A half-precision problem occured. Try to run this implementation without half-precision enabled.");
76 | errored = true;
77 | }
78 | }
79 |
80 | //if (!errored && log.Contains("failed"))
81 | //{
82 | // Program.Cancel($"Error occurred while running AI implementation: \n\n{log}\n\n");
83 | // errored = true;
84 | //}
85 |
86 | if (errored)
87 | Program.Cancel();
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Code/Main/Logger.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.Forms;
2 | using System;
3 | using System.IO;
4 | using System.Windows.Forms;
5 | using Cupscale.IO;
6 | using DT = System.DateTime;
7 |
8 | namespace Cupscale
9 | {
10 | internal class Logger
11 | {
12 | public static TextBox textbox;
13 |
14 | public static string sessionLog;
15 |
16 | public static string file;
17 |
18 | public static bool disable;
19 |
20 | public static bool doLogIo;
21 | public static bool doLogStatus;
22 |
23 | public static void Init ()
24 | {
25 | file = Path.Combine(Paths.GetDataPath(), "sessionlog.txt");
26 | doLogIo = Config.GetBool("logIo");
27 | doLogStatus = Config.GetBool("logStatus");
28 | PrintArgs();
29 | }
30 |
31 | public static void PrintArgs ()
32 | {
33 | foreach (string arg in Environment.GetCommandLineArgs())
34 | Log("Arg: " + arg);
35 | }
36 |
37 | public static void Log(string s, bool logToFile = true, bool noLineBreak = false, bool replaceLastLine = false)
38 | {
39 | if (disable) return;
40 |
41 | Console.WriteLine(s);
42 |
43 | if (replaceLastLine)
44 | {
45 | textbox.Text = textbox.Text.Remove(textbox.Text.LastIndexOf(Environment.NewLine));
46 | sessionLog = sessionLog.Remove(sessionLog.LastIndexOf(Environment.NewLine));
47 | }
48 |
49 | if(!noLineBreak)
50 | sessionLog += Environment.NewLine + s;
51 | else
52 | sessionLog += " " + s;
53 |
54 | if (logToFile)
55 | LogToFile(s, noLineBreak);
56 | }
57 |
58 | public static void LogToFile(string s, bool noLineBreak)
59 | {
60 | if (string.IsNullOrWhiteSpace(file))
61 | file = Path.Combine(Paths.GetDataPath(), "sessionlog.txt");
62 | string time = DT.Now.Month + "-" + DT.Now.Day + "-" + DT.Now.Year + " " + DT.Now.Hour + ":" + DT.Now.Minute + ":" + DT.Now.Second;
63 |
64 | try
65 | {
66 | if (!noLineBreak)
67 | File.AppendAllText(file, Environment.NewLine + time + ": " + s);
68 | else
69 | File.AppendAllText(file, " " + s);
70 | }
71 | catch
72 | {
73 | // idk how to deal with this race condition (?) but just ignoring it seems to work lol
74 | }
75 | }
76 |
77 | public static string GetSessionLog ()
78 | {
79 | return sessionLog;
80 | }
81 |
82 | public static MsgBox ErrorMessage (string msg, Exception e)
83 | {
84 | string text = $"{msg}\n\n{e.Message}\n\nStack Trace:\n{e.StackTrace}";
85 | Clipboard.SetText(text);
86 | Log(text);
87 | return Program.ShowMessage(text + "\n\nThe error message was copied to the clipboard.", "Error");
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Code/Main/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | Use "Tile" or "Mirror" for seamless/tiled textures.
125 | "Extend" will stretch the last pixel row on each side to avoid seams on the borders of the image.
126 | "Alpha" will surround the image with transparency to avoid pixels being squashed to the border of the image.
127 |
128 |
129 | 34
130 |
131 |
--------------------------------------------------------------------------------
/Code/Main/PostProcessing.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.UI;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows;
10 | using System.Windows.Forms;
11 |
12 | namespace Cupscale.Main
13 | {
14 | class PostProcessing
15 | {
16 | public static async Task PostprocessingSingle(string path, bool dontResize = false, int retryCount = 20, bool trimPngExt = true)
17 | {
18 | if (!IoUtils.IsFileValid(path))
19 | return;
20 |
21 | string newPath = "";
22 |
23 | if (trimPngExt)
24 | newPath = path.Substring(0, path.Length - 4);
25 |
26 | Logger.Log($"PostProc: Trimmed filename from '{Path.GetFileName(path)}' to '{Path.GetFileName(newPath)}'");
27 |
28 | try
29 | {
30 | File.Move(path, newPath);
31 | }
32 | catch (Exception e) // An I/O error can appear if the file is still locked by python (?)
33 | {
34 | Logger.Log($"Failed to move/rename! ('{path}' => '{newPath}') {e.Message}\n{e.StackTrace}");
35 |
36 | if (retryCount > 0)
37 | {
38 | await Task.Delay(500); // Wait and retry up to 20 times
39 | int newRetryCount = retryCount - 1;
40 | Logger.Log("Retrying - " + newRetryCount + " attempts left.");
41 | await PostprocessingSingle(path, dontResize, newRetryCount);
42 | }
43 | else
44 | {
45 | Logger.ErrorMessage($"Failed to move/rename '{Path.GetFileName(path)}' and ran out of retries!", e);
46 | }
47 |
48 | return;
49 | }
50 |
51 | path = newPath;
52 | string format = PreviewUi.outputFormat.Text;
53 |
54 | if (Program.lastUpscaleIsVideo || format == Upscale.ImgExportMode.PNG.ToStringTitleCase())
55 | {
56 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.Png50, dontResize);
57 | return;
58 | }
59 |
60 | if (format == Upscale.ImgExportMode.SameAsSource.ToStringTitleCase())
61 | await ImageProcessing.ConvertImageToOriginalFormat(path, true, false, dontResize);
62 |
63 | if (format == Upscale.ImgExportMode.JPEG.ToStringTitleCase())
64 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.Jpeg, dontResize);
65 |
66 | if (format == Upscale.ImgExportMode.WEBP.ToStringTitleCase())
67 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.Weppy, dontResize);
68 |
69 | if (format == Upscale.ImgExportMode.BMP.ToStringTitleCase())
70 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.BMP, dontResize);
71 |
72 | if (format == Upscale.ImgExportMode.TGA.ToStringTitleCase())
73 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.TGA, dontResize);
74 |
75 | if (format == Upscale.ImgExportMode.DDS.ToStringTitleCase())
76 | await ImageProcessing.PostProcessDDS(path);
77 |
78 | if (format == Upscale.ImgExportMode.GIF.ToStringTitleCase())
79 | await ImageProcessing.PostProcessImage(path, ImageProcessing.Format.GIF, dontResize);
80 |
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Code/Main/PostProcessingQueue.cs:
--------------------------------------------------------------------------------
1 | using Cupscale.IO;
2 | using Cupscale.Main;
3 | using Cupscale.UI;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 |
12 | namespace Cupscale.Cupscale
13 | {
14 | class PostProcessingQueue
15 | {
16 | public static Queue outputFileQueue = new Queue();
17 | public static List processedFiles = new List();
18 | public static List outputFiles = new List();
19 |
20 | public static bool run;
21 | public static string currentOutPath;
22 |
23 | //public static bool ncnn;
24 |
25 | public enum CopyMode { KeepStructure, CopyToRoot }
26 | public static CopyMode copyMode;
27 |
28 | public static void Start (string outpath)
29 | {
30 | Logger.Log("[Queue] Start()");
31 | currentOutPath = outpath;
32 | outputFileQueue.Clear();
33 | processedFiles.Clear();
34 | outputFiles.Clear();
35 | IoUtils.ClearDir(Paths.imgOutPath);
36 | run = true;
37 | }
38 |
39 | public static void Stop ()
40 | {
41 | Logger.Log("[Queue] Stop()");
42 | run = false;
43 | }
44 |
45 | public static async Task Update ()
46 | {
47 | while (run || AnyFilesLeft())
48 | {
49 | CheckNcnnOutput();
50 | string[] outFiles = Directory.GetFiles(Paths.imgOutPath, "*.tmp", SearchOption.AllDirectories);
51 |
52 | foreach (string file in outFiles)
53 | {
54 | if (!outputFileQueue.Contains(file) && !processedFiles.Contains(file) && !outputFiles.Contains(file))
55 | {
56 | //processedFiles.Add(file);
57 | outputFileQueue.Enqueue(file);
58 | Logger.Log("[Queue] Enqueued " + Path.GetFileName(file));
59 | }
60 | }
61 |
62 | await Task.Delay(1000);
63 | }
64 | }
65 |
66 | static bool AnyFilesLeft ()
67 | {
68 | if (IoUtils.GetAmountOfFiles(Paths.imgOutPath, true) > 0)
69 | return true;
70 |
71 | return false;
72 | }
73 |
74 | public static string lastOutfile;
75 |
76 | public static async Task ProcessQueue ()
77 | {
78 | Stopwatch sw = new Stopwatch();
79 |
80 | while (!Program.canceled && (run || AnyFilesLeft()))
81 | {
82 | if (outputFileQueue.Count > 0)
83 | {
84 | string file = outputFileQueue.Dequeue();
85 | Logger.Log("[Queue] Post-Processing " + Path.GetFileName(file));
86 | sw.Restart();
87 | await PostProcessing.PostprocessingSingle(file, false);
88 |
89 | while (IoUtils.IsFileLocked(lastOutfile))
90 | {
91 | Logger.Log($"{file} appears to be locked - waiting 500ms...");
92 | await Task.Delay(500);
93 | }
94 |
95 | string outFilename = Upscale.FilenamePostprocess(lastOutfile);
96 |
97 | if(outFilename == null)
98 | {
99 | Logger.Log($"[Queue] Error: Upscale.FilenamePostprocess({lastOutfile}) returned null!");
100 | return;
101 | }
102 |
103 | outputFiles.Add(outFilename);
104 | Logger.Log("[Queue] Done Post-Processing " + Path.GetFileName(file) + " in " + sw.ElapsedMilliseconds + "ms");
105 |
106 | try
107 | {
108 | if (Upscale.overwriteMode == Upscale.Overwrite.Yes)
109 | {
110 | string suffixToRemove = "-" + Program.lastModelName.Replace(":", ".").Replace(">>", "+");
111 |
112 | if (copyMode == CopyMode.KeepStructure)
113 | {
114 | string combinedPath = currentOutPath + outFilename.Replace(Paths.imgOutPath, "");
115 | Directory.CreateDirectory(combinedPath.GetParentDir());
116 | File.Copy(outFilename, combinedPath.ReplaceInFilename(suffixToRemove, "", true), true);
117 | }
118 | if (copyMode == CopyMode.CopyToRoot)
119 | {
120 | File.Copy(outFilename, Path.Combine(currentOutPath, Path.GetFileName(outFilename).Replace(suffixToRemove, "")), true);
121 | }
122 |
123 | File.Delete(outFilename);
124 | }
125 | else
126 | {
127 | if (copyMode == CopyMode.KeepStructure)
128 | {
129 | string combinedPath = currentOutPath + outFilename.Replace(Paths.imgOutPath, "");
130 | Directory.CreateDirectory(combinedPath.GetParentDir());
131 | File.Copy(outFilename, combinedPath, true);
132 | }
133 |
134 | if (copyMode == CopyMode.CopyToRoot)
135 | {
136 | File.Copy(outFilename, Path.Combine(currentOutPath, Path.GetFileName(outFilename)), true);
137 | }
138 |
139 | File.Delete(outFilename);
140 | }
141 | }
142 | catch (Exception e)
143 | {
144 | Logger.Log("Error trying to copy post-processed file back: " + e.Message + "\n" + e.StackTrace);
145 | }
146 |
147 | BatchUpscaleUI.upscaledImages++;
148 | }
149 |
150 | await Task.Delay(200);
151 | }
152 | }
153 |
154 | static void CheckNcnnOutput()
155 | {
156 | foreach (string file in Directory.GetFiles(Paths.imgOutPath, "*.*.png", SearchOption.AllDirectories)) // Rename to tmp
157 | {
158 | try
159 | {
160 | string newPath = file.Substring(0, file.Length - 8) + ".tmp";
161 | string movePath = Path.Combine(Paths.imgOutPath, Path.GetFileName(newPath));
162 | Logger.Log("[Queue] Renaming & moving " + file + " => " + movePath);
163 | File.Move(file, movePath);
164 | }
165 | catch { }
166 | }
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/Code/Main/PreviewState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace Cupscale.Cupscale
9 | {
10 | public struct PreviewState
11 | {
12 | public Image image;
13 | public int zoom;
14 | public Point autoScrollPosition;
15 |
16 | public PreviewState (Image img, int currentZoom, Point autoScrollPos)
17 | {
18 | image = img;
19 | zoom = currentZoom;
20 | autoScrollPosition = autoScrollPos;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Code/Main/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 | using Cupscale.Forms;
10 | using Cupscale.ImageUtils;
11 | using Cupscale.IO;
12 | using Cupscale.Main;
13 | using Cupscale.OS;
14 | using Cupscale.UI;
15 | using ImageMagick;
16 | using Win32Interop.Enums;
17 | using Paths = Cupscale.IO.Paths;
18 |
19 | [assembly: System.Windows.Media.DisableDpiAwareness] // Disable Dpi awareness in the application assembly.
20 |
21 | namespace Cupscale
22 | {
23 | internal static class Program
24 | {
25 | public static MainForm mainForm;
26 | public static string lastOutputDir;
27 | public static string lastImgPath; // Single Image
28 | public static string lastDirPath; // Batch
29 | public static string lastVidPath; // Video
30 | public static string lastModelName;
31 | public static string currentModel1;
32 | public static string currentModel2;
33 | public static FilterType currentFilter = FilterType.Point;
34 |
35 | public static List