├── .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