Update v5.0

This commit is contained in:
Iván Eduardo Chavez Ayub
2025-11-22 15:38:00 -06:00
parent 5ade26ca98
commit 9eb66b0cac
23 changed files with 3054 additions and 1312 deletions
@@ -1,2 +1,2 @@
Download the Assets_bin.zip file from the releases section, prioritizing the latest available version, and extract the ffmpeg and exiftool bins to this directory.
https://github.com/Ivan-Ayub97/Warlock-Studio/releases/download/v4.3/Assets.zip
https://github.com/Ivan-Ayub97/Warlock-Studio/releases/download/v4.2/Assets.zip
+116
View File
@@ -0,0 +1,116 @@
SOFTWARE LICENSE AGREEMENT AND TERMS OF USE FOR WARLOCK-STUDIO
---
PREAMBLE
This Software License Agreement ("Agreement") constitutes a legally binding
contract between you, either as an individual or on behalf of an entity
("USER"), and Iván Eduardo Chavez Ayub ("AUTHOR"), regarding the
Warlock-Studio software and all its associated files, documentation,
and materials (collectively, the "SOFTWARE").
By installing, copying, downloading, accessing, or otherwise using the
SOFTWARE, the USER expressly consents to and agrees to be bound by all
terms and conditions stipulated in this Agreement.
IF THE USER DOES NOT AGREE WITH ALL THE TERMS OF THIS AGREEMENT, THEY MUST
NOT INSTALL, USE, OR COPY THE SOFTWARE AND MUST IMMEDIATELY CANCEL THE
INSTALLATION PROCESS.
---
SECTION I: THE MIT LICENSE
The original and legally binding text of the MIT License is presented below.
This text governs the use of the core SOFTWARE.
MIT License
Copyright (c) 2025 Iván Eduardo Chavez Ayub
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---
SECTION II: ADDITIONAL TERMS, NOTICES, AND ACKNOWLEDGEMENTS
1. Project Description
Warlock-Studio is a software application developed by Iván Eduardo Chavez
Ayub (GitHub profile: @Ivan-Ayub97).
The project is based on open-source
tools such as QualityScaler, FluidFrames, and RealScaler, originally
developed by Djdefrag (GitHub profile: @Djdefrag).
The main objective of
Warlock-Studio is to provide an intuitive graphical interface for
enhancing and upscaling image resolution through the use of artificial
intelligence models.
2. 🧩 THIRD-PARTY COMPONENTS AND APPLICABLE LICENSES
The SOFTWARE integrates various third-party technologies and components.
The use of the SOFTWARE is conditioned not only on compliance with this
Agreement but also with the license terms of each of these components.
The following is a list of components and their respective licenses:
- QualityScaler, RealScaler, FluidFrames: MIT License (Djdefrag)
- RIFE: Apache 2.0 License (hzwer, Megvii Research)
- Real-ESRGAN, RealESRGAN-G, RealESR-Anime, RealESR-Net: BSD 3-Clause / Apache 2.0 License (Xintao Wang)
- GFPGAN: MIT License (TencentARC, Xintao Wang)
- BSRGAN: Apache 2.0 License (Kai Zhang)
- IRCNN: BSD / Mixed License (Kai Zhang)
- ONNX Runtime: MIT License (Microsoft)
- FFmpeg: LGPL-2.1 / GPL License (FFmpeg Team)
- ExifTool: Perl Artistic License (Phil Harvey)
- DirectML: MIT License (Microsoft)
- Python: PSF License (Python Software Foundation)
- Inno Setup: Custom Inno License (Jordan Russell)
3. ⚖️ LIMITATION OF LIABILITY CLAUSE (EXTENDED)
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL THE
AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES; INCLUDING, BUT NOT LIMITED
TO, LOSS OF DATA, BUSINESS INTERRUPTION, OR HARDWARE OR SYSTEM FAILURE
ARISING FROM THE USE, MISUSE, OR INABILITY TO USE THE SOFTWARE.
THIS SOFTWARE IS PROVIDED FOR EDUCATIONAL, CREATIVE, AND RESEARCH PURPOSES.
IT IS NOT CERTIFIED FOR IMPLEMENTATION IN CRITICAL OR COMMERCIAL
INFRASTRUCTURES WITHOUT PRIOR INDEPENDENT VALIDATION.
THE USER ASSUMES
ALL RISK ASSOCIATED WITH ITS USE.
4. 💼 INTELLECTUAL PROPERTY NOTICE
The brand, the name "Warlock-Studio" and its associated logos are the
exclusive intellectual property of Iván Eduardo Chavez Ayub.
The use of
these elements for commercial purposes is strictly prohibited without the
prior written consent of the AUTHOR.
Any redistribution or modification of
the source code must preserve the original copyright notices and all
references to the licenses contained herein.
5. ✍️ ACCEPTANCE OF TERMS
By proceeding with the installation and by using the SOFTWARE, the USER
acknowledges having read, understood, and accepted all the terms set forth
in the MIT License (Section I) and the Additional Terms (Section II) of
this Agreement.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📧 CONTACT INFORMATION
For any inquiries or communications related to this Agreement or the SOFTWARE,
you may contact the Author:
Name: Iván Eduardo Chavez Ayub
Email: negroayub97@gmail.com
GitHub: [https://github.com/Ivan-Ayub97](https://github.com/Ivan-Ayub97)
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

+265 -134
View File
@@ -1,48 +1,179 @@
# Warlock-Studio - Comprehensive Changelog History
---
## Version 5.0
**Release date:** November 22, 2025
**Kernel Version:** 5.0.0 (Codename: NEO-Refactor)
**Architecture:** Modular / Component-Based
### 1. Architectural Re-engineering & System Decoupling
The application core has undergone a foundational transformation, migrating from a legacy monolithic script architecture (v4.3) to a distributed, component-oriented modular system. This refactoring significantly reduces cyclomatic complexity, enforces Separation of Concerns (SoC), and isolates failure domains for improved fault tolerance.
#### 1.1. Component Atomization & Isolation
The legacy `Warlock-Studio (1).py` codebase has been segmented into specialized operational subsystems:
- **`Warlock-Studio.py` (Core Orchestrator):**
- Retains exclusive control over the application entry point, the `App` class instantiation, and the main GUI event loop (`mainloop`).
- Manages the high-level orchestration of `multiprocessing.Process` spawning for AI workloads, ensuring UI thread non-blocking behavior.
- **`warlock_preferences.py` (State & Hardware Abstraction Layer):**
- A newly isolated subsystem responsible for persistent state management via JSON serialization.
- Hosts the **"NEO Engine"**, a heuristic hardware diagnostic suite.
- Manages OTA (Over-The-Air) update logic via asynchronous polling of the GitHub Releases API.
- **`console.py` (I/O Stream Management):**
- Encapsulates the `IntegratedConsole` widget logic and the `StreamRedirector` class.
- Implements a thread-safe **Singleton Pattern** (`ConsoleManager`) to intercept standard output (`sys.stdout`) and error streams (`sys.stderr`) at the interpreter level, redirecting them to the GUI buffer in real-time.
- **`drag_drop.py` (OS Event Wrapper):**
- Provides an abstraction layer over `tkinterdnd2`.
- Implements the `DnDCTk` class, which inherits from `CTk` and `TkinterDnD.DnDWrapper`, injecting native OS file drag-and-drop event listeners into the custom UI toolkit.
### 2. "NEO Engine": Telemetry, Heuristics & Persistence
#### 2.1. Advanced Hardware Introspection (`HardwareScanner` Class)
Implemented a robust Hardware Abstraction Layer (HAL) within `warlock_preferences.py`, utilizing `wmi`, `psutil`, and `GPUtil` libraries for deep system profiling:
- **CPU Topology Analysis:** Differentiates between physical and logical cores to optimize `cpu_count` allocation for FFmpeg encoding and frame extraction threads.
- **Memory Mapping:** Performs real-time analysis of total vs. available RAM to preemptively throttle batch sizes and prevent page file thrashing (swapping).
- **GPU Heuristic Detection:** Implements a deterministic priority chain for VRAM detection:
1. **Priority A:** `GPUtil` (Direct NVIDIA API access).
2. **Priority B:** `WMI` (Win32_VideoController query for AMD/Intel).
3. **Fallback:** Synthetic estimation based on system heuristics.
- **Algorithmic Optimization (`get_smart_recommendations`):** A logic engine that accepts hardware telemetry and computes the **"Safe VRAM Limit"** via the formula `max(0.5, vram_gb - 1.5)`. It dynamically prescribes Tile Resolutions and Thread Concurrency based on hardware tiers (Low-End vs. High-End).
#### 2.2. Serialized Configuration Management (`ConfigManager`)
- **JSON State Persistence:** Deprecated hardcoded global variables in favor of a structured `warlock_config.json` file.
- **Robust Serialization:** The `ConfigManager` handles the marshaling and unmarshaling of user preferences (UI scaling factors, window opacity, process priority).
- **Integrity Validation:** The `load_config` method implements schema validation, automatically injecting default key-value pairs if the configuration file is corrupted or missing fields during boot.
### 3. AI Inference Engine Stabilization (ONNX Runtime Backend)
#### 3.1. Deterministic Session Initialization
- **Strict Type Enforcement:** The `create_onnx_session` factory was hardened to enforce strict integer typing (`int`) for the `device_id` parameter.
- _Correction:_ In v4.3, passing device IDs as string literals (e.g., `"0"`) caused silent initialization failures on strict `DirectML` backends. The new logic creates an explicit mapping table (`'GPU 1' -> 0`).
- **Hierarchical Execution Priority:** Implemented a failover chain for `ExecutionProviders` to maximize hardware acceleration compatibility:
1. **Primary:** `CUDAExecutionProvider` (NVIDIA Optimized via cuDNN).
2. **Secondary:** `DmlExecutionProvider` (DirectX 12 Abstraction Layer).
3. **Failover:** `CPUExecutionProvider` (Universal x64 instruction set).
#### 3.2. Precision Standardization in Face Restoration (`AI_face_restoration`)
- **Mandatory Float32 Inference:** The experimental `fp16` (half-precision) auto-detection logic used in v4.3 was deprecated.
- _Rationale:_ It caused `NaN` (Not a Number) tensor propagation on older GPUs lacking dedicated Tensor Cores. The engine now defaults to **`float32`** unless the ONNX model metadata explicitly mandates a lower precision dtype.
- **"Split-Merge" Channel Strategy:** A sophisticated pipeline was developed to handle RGBA (Transparency) artifacts:
1. **Channel Splitting:** The Alpha channel is isolated from the RGB tensor.
2. **Hybrid Scaling:** RGB channels are processed via the Neural Network; the Alpha channel is scaled using **Bicubic Interpolation** (`INTER_CUBIC`) to preserve edge fidelity without introducing GAN-generated noise into the transparency mask.
3. **Tensor Reconstruction:** Post-inference concatenation (`numpy.concatenate`) reassembles the final image tensor.
#### 3.3. Heuristic OOM (Out-Of-Memory) Recovery
- **Recursive Dynamic Tiling:** The `upscale_video_frames_async` pipeline now wraps inference calls within a specialized `try...except` block listening for specific `cuda`, `memory`, or `allocation` exceptions.
- **Recovery Algorithm:** Upon trapping a VRAM overflow event, the orchestrator intercepts the crash, dynamically downscales the `max_resolution` (Tile Size) by a factor of 2 (e.g., `100% -> 50%`), and triggers a recursive retry of the failed frame. This ensures batch job completion even during transient memory spikes.
### 4. Video Processing Pipeline & FFmpeg Orchestration
#### 4.1. Redundant Encoding Pipeline (Codec Fallback Loop)
The `video_encoding` function has been refactored into a transactional state machine with automatic rollback and retry capabilities:
- **Attempt 0 (Hardware Acceleration):** Initiates encoding using the user-selected hardware codec (e.g., `hevc_nvenc`, `h264_amf`, `hevc_qsv`).
- **Failure Handling:** Captures `subprocess.CalledProcessError` or non-zero exit codes (indicative of driver timeouts or resource locking).
- **Attempt 1 (Software Failover):** Automatically switches context to the CPU-based `libx264` encoder. This guarantees output file delivery even in catastrophic GPU driver failure scenarios.
#### 4.2. Lossless Intermediate Serialization
- **PNG Standardization:** The `extract_video_frames` function has strictly deprecated the use of `.jpg` (v4.3) for temporary frame storage. The pipeline now mandates **`.png`** containers, eliminating compression artifacts (generation loss) before the pixel data enters the neural network input layer.
#### 4.3. Temporal Frame Synchronization
- **FPS Multiplier Logic:** An explicit `fps_multiplier` argument was injected into the `video_encoding` signature.
- _Functionality:_ This allows the orchestrator to mathematically calculate the target framerate (`source_fps * multiplier`) specifically for **RIFE Interpolation** tasks (x2, x4, x8), ensuring frame-perfect Audio/Video synchronization in the final container muxing.
### 5. UI/UX & Advanced Diagnostic Tools
#### 5.1. Integrated Debugging Console (`IntegratedConsole`)
- **Stream Interception:** The `StreamRedirector` class hooks into the Python interpreter's I/O layer to capture `sys.stdout` and `sys.stderr`.
- **Real-Time Visualization:** A dedicated `CTkTextbox` widget renders logs with Regex-based syntax highlighting (INFO=Blue, ERROR=Red, WARNING=Yellow, SUCCESS=Green), empowering end-users to diagnose underlying FFmpeg or ONNX runtime issues without external CLI tools.
#### 5.2. Dynamic DOM Adaptability (FluidFrames Integration)
- **Contextual Widget Injection:** Implemented the `clear_dynamic_menus` routine to manipulate the widget tree (DOM) at runtime.
- _Behavior:_ Upon selecting a **RIFE** model, "Blending" controls are destroyed and "Frame Generation" selectors (Slowmotion factors) are dynamically injected into the layout. This prevents invalid configuration states at the UI level.
#### 5.3. Window Management & Responsive Layout
- **Reactive Geometry Engine:** The `window.resizable(True, True)` flag was enabled, and the initial viewport geometry was increased to **85%** of screen height. The `grid` and `place` geometry managers were recalibrated to respond dynamically to window resizing events, accommodating the new bottom-docked console.
### 6. Deployment & System Integration Strategy
#### 6.1. Relocation of Default Installation Directory
- **Privilege Escalation Mitigation:** The default installation target within the Inno Setup script (`.iss`) has been migrated from `%ProgramFiles%` to **`%userprofile%\Documents\Warlock-Studio`**.
- **Write-Access Assurance:** This critical deployment change addresses `PermissionDenied` (WinError 5) exceptions encountered in v4.3 on systems with strict UAC (User Account Control) policies. By deploying to the user space, the application guarantees atomic read/write access for:
- Serialization of the **`warlock_config.json`** file.
- Real-time log appending to the **`Warlock_Logs`** directory.
- Execution of the internal **PDF Manual** without invoking elevated Administrator privileges.
- Unimpeded execution of the **NEO Engine** hardware probes without file system virtualization or sandbox interference.
---
## Version 4.3
**Release date:** November 15, 2025
### **1. Critical Stability & Process Synchronization**
### 1. Critical Stability & Process Synchronization
#### **1.1. Forced Writer Thread Synchronization (Critical Stability Fix)**
#### 1.1. Forced Writer Thread Synchronization (Critical Stability Fix)
- Implemented explicit and mandatory synchronization using the `t.join()` function for **all frame writing threads** (`writer_threads`) within the main video orchestrator (`upscale_orchestrator`).
- This change is **critical for workflow integrity**, ensuring that all AI-upscaled frames are completely written and closed on disk before initiating the FFmpeg video encoding process.
- **Technical Impact:** Resolves intermittent encoding failures (`File Not Found` or `Input/Output error`) that could occur when FFmpeg attempted to read files still being written by concurrent threads.
#### **1.2. Graceful Termination for Process Monitoring Thread**
#### 1.2. Graceful Termination for Process Monitoring Thread
- The status monitoring thread (`upscale_monitor_thread`) has been enhanced to handle unexpected failures or abrupt terminations of the main upscaling process.
- An explicit `break` statement was added to the `except Exception` block that manages errors reading from the status queue (`process_status_q`).
- **Technical Impact:** If the main upscaling process (`Process`) fails or hangs, the monitoring thread now **terminates its execution gracefully and immediately** instead of becoming a "zombie thread," allowing the user interface to correctly reset global status controls.
#### **1.3. Reinforced Frame Sequence Integrity Validation**
#### 1.3. Reinforced Frame Sequence Integrity Validation
- A robust verification function was introduced to validate the integrity of the frame sequence on disk before starting the AI upscaling.
- This measure is vital for `Resume` operations and now explicitly validates:
- The **physical existence** of every frame path (`os_path_exists`).
- The **readability** of the image file (`image_read`), preventing segmentation faults or memory errors if the file is corrupted or incomplete.
### **2. Performance Improvements and Technical Refinements**
### 2. Performance Improvements and Technical Refinements
#### **2.1. Aggressive Post-Process Memory Optimization**
#### 2.1. Aggressive Post-Process Memory Optimization
- A memory optimization step (`optimize_memory_usage`) with calls to `gc.collect()` was implemented after the last upscaled frames are saved to disk and before video encoding starts.
- **Purpose:** To reduce peak RAM usage by aggressively freeing any residual NumPy arrays and image references held in memory, ensuring the system has maximum memory available for the FFmpeg encoding subprocess.
#### **2.2. Clarification of Tiling and VRAM Logic**
#### 2.2. Clarification of Tiling and VRAM Logic
- Detailed internal documentation (`# comments`) was added to the validation function (`check_upscale_settings`) to **explain the calculation logic for tile size** based on the user's VRAM limiter and the AI model's usage factor.
- **Clarified Formula:** `tiles_resolution = (ModelUsageFactor * VRAM_GB) * 100`. This is a technical refinement ensuring transparency and justification for the internal calculation.
#### **2.3. Robustness and Clarification in Video Encoding (FFmpeg Command Line) 🎬**
#### 2.3. Robustness and Clarification in Video Encoding (FFmpeg Command Line) 🎬
- **Explicit Stream Mapping:** Within `create_video_with_ffmpeg`, the FFmpeg command line now uses **more explicit and safer stream mapping** (`-map 0:v:0 -map 0:a:0?`). This ensures that the first video stream is selected obligatorily, and the first audio stream is selected optionally, resolving ambiguity issues in inputs containing multiple video or audio streams.
- **Data Stream Exclusion:** The **`-dn`** (Disable Data stream) argument was introduced into the base FFmpeg command line. This instructs the encoder to ignore unnecessary _data streams_ (such as subtitles or complex metadata) that are not relevant to the video or audio, **simplifying the muxing process and improving compatibility** across various players.
### **3. Aesthetic and UI/UX Refinements**
### 3. Aesthetic and UI/UX Refinements
#### **3.1. Complete Aesthetic Overhaul: Crimson Gold Dark Theme 🌑**
#### 3.1. Complete Aesthetic Overhaul: Crimson Gold Dark Theme 🌑
- The application's entire color scheme was replaced (migrating from a v4.2.1 red/yellow palette) with a high-contrast **"Crimson Gold Dark Theme"**:
- **Background:** Deep Black (`#121212`).
@@ -50,71 +181,67 @@
- **Primary Accent:** Pure Gold (`#FFD700`).
- Dropdown menus (`CTkOptionMenu`) were styled with explicit **`corner_radius=0`** for a more modern, defined, and flat aesthetic.
#### **3.2. Detailed Visualization of File Information in Queue**
#### 3.2. Detailed Visualization of File Information in Queue
- Clarity of information in the queue widget (`FileWidget.add_file_information`) was improved by breaking down the complete resolution transformation sequence into three lines, eliminating ambiguity about intermediate dimensions:
- **AI Input:** Shows the final input resolution.
- **AI Output:** Shows the native resolution after upscaling by the AI model factor.
- **Video Output:** Shows the final resolution of the encoded video.
#### **3.3. Visual Consistency and Updated Menu Separators**
#### 3.3. Visual Consistency and Updated Menu Separators
- The visual separator in all dropdown menus has been updated from the string `"<------------------>"` (v4.2.1) to a cleaner, more discreet sequence of dots: **`• • • • • • • • • • • •`**.
#### **3.4. Refined Dynamic Menu Logic**
#### 3.4. Refined Dynamic Menu Logic
- The conditional visibility logic for menus in `select_AI_from_menu` was refined for a smoother user experience:
- The **Frame Interpolation** control is only visible for RIFE models.
- The **Blending** control is only visible for Upscaling/Facial Restoration models (with automatic disabling logic for GFPGAN).
---
---
## Version 4.2.1
**Release date:** 27 October 2025
### **1. Critical Bug Fixes & Core Functionality**
### 1. Critical Bug Fixes & Core Functionality
#### **1.1. Resolved Critical Audio Passthrough Failure in Video Encoding**
#### 1.1. Resolved Critical Audio Passthrough Failure in Video Encoding
- Addressed a major bug introduced in v4.2 where all generated videos were encoded without audio. This was caused by the accidental omission of the `ffprobe.exe` executable (a key component of the FFmpeg suite) from the application's `Assets` directory and the final build package.
- The `video_encoding` pipeline relies on media analysis (performed by `ffmpeg` or `ffprobe`) to detect the presence of audio streams in the source video. Due to the missing executable, the `audio_info_command` subprocess would fail, causing the application to incorrectly assume all input videos had no audio.
- By restoring the `ffprobe.exe` binary to the application bundle, the audio detection step now executes successfully, enabling the proper copying (`-c:a copy`) or re-encoding (`-c:a aac`) of the original audio track into the final processed video.
#### **1.2. Fixed Invalid UI State Persistence**
#### 1.2. Fixed Invalid UI State Persistence
- Addressed a critical UI logic bug where AI model settings could persist incorrectly when switching between model types. The `select_AI_from_menu` function now properly resets conflicting global variables:
- **RIFE Selection:** When an interpolation model (e.g., RIFE, RIFE_Lite) is selected, the **`selected_blending_factor`** is now automatically reset to `0` (OFF), as blending is not a valid operation for this model.
- **Upscaling/Face Selection:** Conversely, when any upscaling or face restoration model (e.g., BSRGAN, GFPGAN) is selected, the **`selected_frame_generation_option`** is automatically reset to `OFF`.
- This prevents users from applying invalid or non-functional setting combinations, ensuring a more intuitive and error-free workflow.
#### **1.3. Fixed File Thumbnail Generation Crash**
#### 1.3. Fixed File Thumbnail Generation Crash
- Reworked the `FileWidget.extract_file_icon` method to be more robust during the conversion of an OpenCV (NumPy) image to a `CTkImage` for file previews.
- The process no longer relies on the `mode='RGB'` parameter within `pillow_image_fromarray`, which could fail with certain `numpy` array layouts.
- It now uses an explicit, two-step conversion (`pil_img = pillow_image_fromarray(source_icon)` followed by `pil_img = pil_img.convert("RGB")`), ensuring correct channel order and preventing potential `Pillow`/`numpy` compatibility crashes when loading file thumbnails.
---
### 2. UI Corrections & Usability Enhancements
### **2. UI Corrections & Usability Enhancements**
#### **2.1. Corrected Supported File Extension List**
#### 2.1. Corrected Supported File Extension List
- The helper text on the file selection screen has been corrected to more accurately list the supported file extensions. It now properly includes `jpeg` and `tiff` and removes incorrect entries (`heic`, `gif`, `mpg`, `qt`, `3gp`) to align with the application's actual processing capabilities.
#### **2.2. Implemented Fixed Application Window**
#### 2.2. Implemented Fixed Application Window
- The main application window is now non-resizable (`window.resizable(False, False)`). This change was implemented to ensure a stable and predictable UI layout, preventing the relative-coordinate-based widget placement (`relx`, `rely`) from breaking, overlapping, or scaling improperly when the window is resized.
#### **2.3. Improved Dialog Window Behavior**
#### 2.3. Improved Dialog Window Behavior
- Removed the `self.attributes("-topmost", True)` flag from the `MessageBox` class (which handles error and info dialogs). This stops popup windows from aggressively forcing themselves to be the top-most window on the entire desktop. Dialogs now behave as standard application-modal windows, resolving a key usability issue where they could "steal focus" or obstruct other programs.
---
### 3. Thematic & Visual Redesign
### **3. Thematic & Visual Redesign**
#### **3.1. New "Inferno" Thematic Redesign**
#### 3.1. New "Inferno" Thematic Redesign
- Version 4.2.1 introduces a significant visual overhaul, moving away from the previous gold-and-grey theme to a high-contrast, dark-mode "inferno" theme. This new palette uses a deep red background with bright yellow and white text, designed to improve readability and reduce eye strain.
@@ -131,11 +258,11 @@ The color scheme has been updated as follows:
| **Warning Color** | `#E02CDA` (Magenta) | `#FF8C00` (Orange) |
| **Error Color** | `#070087` (Dark Blue) | `#DC143C` (Crimson) |
#### **3.2. Monospaced Typography Shift**
#### 3.2. Monospaced Typography Shift
- The application's global font has been changed from `"Segoe UI"` to `"Consola"`. This provides a more uniform, technical aesthetic across all UI elements, enhancing readability for file names, numeric values, and status messages.
#### **3.3. Dropdown Menu Readability**
#### 3.3. Dropdown Menu Readability
- Updated the visual separators in dropdown menus from `----` to `<------------------>` for clearer, more pronounced grouping of model categories.
@@ -145,49 +272,37 @@ The color scheme has been updated as follows:
**Release date:** 6 October 2025
### **1. Core Architecture & Performance Engineering**
### 1. Core Architecture & Performance Engineering
#### **1.1. Advanced ONNX Runtime Integration & Execution Provider Strategy**
#### 1.1. Advanced ONNX Runtime Integration & Execution Provider Strategy
- **Intelligent Provider Prioritization & Fallback Mechanism**: The core AI model loading architecture has been fundamentally re-engineered for superior performance and resilience. The new implementation leverages a prioritized provider list (`['CUDAExecutionProvider', 'DmlExecutionProvider', 'CPUExecutionProvider']`) within the `onnxruntime.InferenceSession` constructor. It first attempts to initialize a session using the **`CUDAExecutionProvider`**, which offers the highest performance by interfacing directly with NVIDIA's CUDA cores and Tensor Cores. If this fails (due to lack of an NVIDIA GPU, driver issues, or CUDA toolkit incompatibility), the system gracefully falls back and attempts initialization with the **`DmlExecutionProvider`**, utilizing Windows' DirectML API for broader hardware acceleration across various GPU vendors (NVIDIA, AMD, Intel). As a final failsafe, if no GPU acceleration provider can be initialized, it defaults to the **`CPUExecutionProvider`**, ensuring the application remains functional on any machine, albeit with reduced performance.
- **Centralized Session Management & Code Refactoring**: A new, unified function, `create_onnx_session`, has been introduced to abstract and centralize all ONNX session creation logic. This eliminates the redundant and error-prone boilerplate code that was previously duplicated within the `_load_inferenceSession` method of each individual AI class (`AI_upscale`, `AI_interpolation`, `AI_face_restoration`). This refactoring adheres to the **Don't Repeat Yourself (DRY)** principle, significantly improving code maintainability, reducing the surface area for bugs, and ensuring a consistent and robust model loading strategy across the entire application.
- **Enhanced Error Handling & Diagnostics**: The `try...except` block encapsulating the session creation loop is now more sophisticated. It logs specific warnings when a provider fails to initialize and clearly indicates which provider it is falling back to. This provides transparent diagnostics that are critical for troubleshooting performance issues related to hardware acceleration.
#### **1.2. PyInstaller Packaging & Distribution Overhaul**
#### 1.2. PyInstaller Packaging & Distribution Overhaul
- **Aggressive Dependency Pruning for Size Optimization**: The PyInstaller `.spec` file has been meticulously optimized to drastically reduce the final distribution size. An extensive `excludes` list has been implemented to explicitly instruct PyInstaller's analysis engine to ignore and not bundle large, non-essential packages. This prevents the recursive inclusion of entire scientific and machine learning ecosystems like `torch`, `transformers`, `matplotlib`, `pandas`, `scipy`, and `PyQt5`, which are often pulled in as sub-dependencies but are not required for this application's runtime. This strategic pruning reduces the package size by hundreds of megabytes.
- **Robust Hidden Import Declaration for Runtime Stability**: The `.spec` file now includes a `hiddenimports` list containing `onnxruntime.capi._pybind_state`, `onnxruntime.providers`, and `moviepy.editor`. This is critical for ensuring runtime stability, as these modules are often loaded dynamically (e.g., via `__import__` or C extensions) in a way that PyInstaller's static analysis cannot detect. Explicitly declaring them forces their inclusion, preventing `ModuleNotFoundError` crashes when the packaged application attempts to access these components.
- **Strategic Shift to "One-Folder" Distribution**: The build strategy has been transitioned from a "one-file" mode to a more robust and efficient "one-folder" mode. This is achieved by using the `COLLECT` block in the `.spec` file. Instead of bundling all dependencies into a single large executable that must be decompressed to a temporary directory (`_MEIPASS`) on every launch, the "one-folder" approach places the executable alongside its required `.dll`, `.pyd`, and data files. This results in significantly faster application startup times and avoids potential conflicts with antivirus software or system permissions related to executing from temporary locations.
---
### 2. Installer & Distribution Strategy Refinement
### **2. Installer & Distribution Strategy Refinement**
#### **2.1. Transition to a Full Offline Installer Model**
#### 2.1. Transition to a Full Offline Installer Model
- **Self-Contained & Hermetic Package**: The application's distribution model has been fundamentally shifted from a lightweight online/web installer to a comprehensive **offline installer**. All required runtime assets, most notably the large AI model files (`.onnx`), are now bundled directly within the Inno Setup executable. This creates a fully self-contained package that guarantees a successful installation without any external dependencies.
- **Elimination of Network Dependencies & Points of Failure**: This architectural change enhances installation reliability exponentially. It completely removes the dependency on an active internet connection during setup and eliminates critical points of failure, such as GitHub/SourceForge server downtime, network interruptions, firewalls, or changes in download URLs. The user is assured of a complete, atomic installation from a single authoritative file.
- **Radical Simplification of Installer Logic**: As a direct result of bundling all assets, the entire Pascal Script `[Code]` section in `Setup.iss` has been **completely removed**. This eliminates dozens of lines of complex logic responsible for creating custom download pages, handling HTTP requests, managing user cancellations, and, most critically, invoking external processes like PowerShell for archive extraction (`Expand-Archive`). This simplification makes the installer script significantly more robust, predictable, and easier to maintain.
- **Streamlined User Experience**: The installer's UI has been simplified by removing the "Download AI Models" task from the `[Tasks]` section. This avoids user confusion and streamlines the setup process, as the action is no longer necessary. The output filename is also now explicitly suffixed with `-Full-Installer` to clearly communicate its offline nature.
---
### 3. UI, UX & Developer Experience Enhancements
### **3. UI, UX & Developer Experience Enhancements**
#### **3.1. Enhanced Application Startup & Initial Feedback**
#### 3.1. Enhanced Application Startup & Initial Feedback
- **Professional Splash Screen Implementation**: A new `SplashScreen` class provides immediate visual feedback upon application launch. This improves the _perceived performance_ by displaying a branded loading screen with status messages while core components and AI models are being initialized in the background. It prevents the appearance of a hung or unresponsive application during the initial loading phase.
- **Runtime Environment Diagnostics**: At startup, the application now programmatically queries and prints the available ONNX Runtime providers by calling `onnxruntime.get_available_providers()`. This information is outputted to the console, serving as an invaluable, zero-effort diagnostic tool. It allows both end-users and developers to instantly verify which hardware acceleration backends are detected and available to the application, aiding in performance tuning and troubleshooting.
#### **3.2. Improved Debugging and Diagnosability**
#### 3.2. Improved Debugging and Diagnosability
- **Persistent Console for Runtime Output**: The PyInstaller build configuration was modified to set `console=True`. This forces the application to run with an attached console window that captures the `stdout` and `stderr` streams. This is a critical enhancement for diagnostics, as it makes all print statements, logging output, warnings, and unhandled exception tracebacks immediately visible, providing a clear and persistent record of the application's runtime behavior for effective bug reporting and debugging.
@@ -197,51 +312,51 @@ The color scheme has been updated as follows:
**Release date:** 1 August 2025
### Model Enhancement and Utilization
### 1. Model Enhancement and Utilization
#### 1.1 **Enhanced GPU Utilization and Error Handling**
#### 1.1. Enhanced GPU Utilization and Error Handling
- **Robust Provider Configuration**: Added a private method `_select_providers` to intelligently select ONNX runtime providers based on the chosen GPU and improve model execution efficiency.
- **Dynamic Fall-back Mechanism**: Enhanced `_load_inferenceSession` to prioritize loading models on GPU providers and gracefully fallback to CPU providers if GPU initialization fails, coupled with detailed logging.
- **Improved Model Initialization**: Ensured comprehensive validation and error handling during model loading to enhance stability across various hardware environments.
### Compatibility and Runtime Improvements
### 2. Compatibility and Runtime Improvements
#### 2.1 **Addressed NumPy and OpenCV Compatibility**
#### 2.1. Addressed NumPy and OpenCV Compatibility
- **Resolved Import Errors**: Fixed critical compatibility issues between NumPy 2.x and OpenCV by downgrading to NumPy 1.26.4, preventing `_ARRAY_API not found` and `numpy.core.multiarray failed to import` errors.
- **Critical Module Validation**: Ensured that all critical libraries (OpenCV, ONNX Runtime, CustomTkinter) load successfully without compatibility warnings, enhancing overall application reliability.
- **Runtime Environment Stability**: Resolved module loading conflicts that previously caused application crashes during startup.
### Performance Optimization
### 3. Performance Optimization
#### 3.1 **Memory and Resource Management**
#### 3.1. Memory and Resource Management
- **Contiguous Memory Utilization**: Enhanced use of `numpy.ascontiguousarray` throughout image processing pipelines to optimize memory usage during intensive AI processing tasks.
- **GPU Memory Error Recovery**: Improved handling of GPU memory allocation failures with automatic fallback to CPU processing when DirectML providers are unavailable.
- **Processing Pipeline Optimization**: Streamlined AI model loading and inference execution for better resource utilization across different hardware configurations.
### Code Quality and Error Handling
### 4. Code Quality and Error Handling
#### 4.1 **Enhanced Error Resilience**
#### 4.1. Enhanced Error Resilience
- **Syntax Error Resolution**: Fixed critical syntax error in `_load_inferenceSession` method that prevented proper AI model initialization.
- **Improved Error Messaging**: Enhanced logging capabilities with more informative error messages and warnings for better user diagnostics and troubleshooting.
- **Graceful Degradation**: Implemented improved fallback strategies for GPU resource issues, effectively preventing application crashes by dynamically adjusting processing pathways.
- **Provider Validation**: Added comprehensive validation for ONNX runtime providers with automatic fallback from GPU to CPU execution when hardware acceleration is unavailable.
### UI and User Experience
### 5. UI and User Experience
#### 5.1 **Application Stability and Feedback**
#### 5.1. Application Stability and Feedback
- **Startup Reliability**: Resolved critical startup issues that prevented the application from launching due to module compatibility problems.
- **Processing Status Updates**: Enhanced real-time feedback during AI model loading and image/video processing operations.
- **Error Notification**: Improved error dialogs and status messages to provide clearer information about processing states and potential issues.
- **Hardware Compatibility**: Better detection and handling of different GPU configurations, with informative warnings when falling back to CPU processing.
### Technical Improvements
### 6. Technical Improvements
#### 6.1 **Model Loading Architecture**
#### 6.1. Model Loading Architecture
- **Modular Provider Selection**: Separated provider selection logic into dedicated methods for better code organization and maintainability.
- **Robust Model Validation**: Enhanced file existence checking and model integrity validation before attempting to load AI models.
@@ -253,9 +368,9 @@ The color scheme has been updated as follows:
**Release date:** 27 July 2025
### Model Cleanup and Optimization
### 1. Model Cleanup and Optimization
#### 1.1 **SuperResolution-10 Model Removal**
#### 1.1. SuperResolution-10 Model Removal
- **Model Deprecation**: Removed the SuperResolution-10 model from the application due to performance and compatibility issues.
- **Code Cleanup**: Eliminated the dedicated `AI_super_resolution` class and all related processing pipelines.
@@ -264,7 +379,7 @@ The color scheme has been updated as follows:
- **Streamlined Processing**: Simplified the upscaling orchestrator by removing SuperResolution-specific routing logic.
- **Model List Cleanup**: Removed `SuperResolution_models_list` from the main AI models collection.
#### 1.2 **Performance Improvements**
#### 1.2. Performance Improvements
- **Reduced Memory Footprint**: Application now uses less memory without the SuperResolution-10 model overhead.
- **Simplified Code Paths**: Cleaner processing logic with fewer conditional branches for model selection.
@@ -278,57 +393,57 @@ The color scheme has been updated as follows:
### 1. AI Model Integration & Enhancement
#### 1.1 **SuperResolution-10 Model Implementation**
#### 1.1. SuperResolution-10 Model Implementation
- **New AI Model Integration**: Added support for the SuperResolution-10 model, providing advanced super-resolution capabilities with 10x upscaling factor. This model is specifically designed for very low-resolution images and excels at significant resolution increases.
- **Specialized Processing Pipeline**: Created a dedicated `AI_super_resolution` class that inherits from the new `AI_model_base` class, implementing proper preprocessing (CHW format conversion, normalization) and postprocessing (HWC format conversion, value clipping) for optimal results.
- **Model Information Integration**: Added comprehensive model information in the AI model selector dialog, including year (2023), function (high-resolution image enhancement), and specialized use cases.
#### 1.2 **AI Architecture Improvements**
#### 1.2. AI Architecture Improvements
- **Base Class Implementation**: Created the missing `AI_model_base` class that provides common functionality for all AI models, including ONNX model loading with GPU acceleration support and proper error handling.
- **Enhanced Model Loading**: Implemented robust model loading with provider selection (DML, CPU) and comprehensive error handling for missing model files.
- **VRAM Management**: Added VRAM usage information for SuperResolution-10 (0.8 GB) to help users optimize their GPU memory usage.
#### 2. Code Quality & Stability
### 2. Code Quality & Stability
##### 2.1 **Import System Optimization**
#### 2.1. Import System Optimization
- **Fixed Import Errors**: Resolved critical `NameError: name 'numpy_ndarray' is not defined` by properly organizing imports at the top of the file.
- **Consolidated Imports**: Removed duplicate import sections and properly structured the import hierarchy for better maintainability.
- **Type Annotation Fixes**: Corrected type annotations throughout the codebase to use the proper imported numpy types.
##### 2.2 **Enhanced Error Handling**
#### 2.2. Enhanced Error Handling
- **Model Loading Resilience**: Implemented try-catch blocks for model loading operations with meaningful error messages.
- **Graceful Degradation**: Added fallback mechanisms that return the original image if super-resolution enhancement fails, ensuring the application never crashes.
- **Debug Information**: Enhanced logging with model loading status and error reporting for better troubleshooting.
#### 3. User Interface Updates
### 3. User Interface Updates
##### 3.1 **Model Selection Enhancement**
#### 3.1. Model Selection Enhancement
- **Updated Model List**: SuperResolution-10 is now properly integrated into the AI model dropdown menu and categorized appropriately.
- **Information Dialog Updates**: Added detailed information about the SuperResolution-10 model in the help dialog, including its capabilities and recommended use cases.
- **Model Orchestration**: Enhanced the upscaling orchestrator to properly detect and route SuperResolution model tasks to the appropriate processing pipeline.
#### 4. Technical Improvements
### 4. Technical Improvements
##### 4.1 **Processing Pipeline Optimization**
#### 4.1. Processing Pipeline Optimization
- **Specialized Image Processing**: Implemented dedicated image processing functions for super-resolution models that handle the unique requirements of the SuperResolution-10 model.
- **Memory Efficiency**: Optimized image preprocessing and postprocessing to minimize memory usage during super-resolution operations.
- **Performance Monitoring**: Added processing time tracking for super-resolution operations to help users understand processing performance.
#### 4.2 **Integration Completeness**
#### 4.2. Integration Completeness
- **Full Model Integration**: SuperResolution-10 is now fully integrated into all aspects of the application, from model selection to processing to output generation.
- **Consistent User Experience**: The super-resolution workflow follows the same patterns as other AI models, ensuring a consistent user experience.
- **Quality Assurance**: Implemented comprehensive testing to ensure the SuperResolution-10 model works correctly with both individual images and batch processing.
### 5. **Smart AI Model Distribution System**
### 5. Smart AI Model Distribution System
#### 5.1 **Automatic Model Download**
#### 5.1. Automatic Model Download
- **Lightweight Installer**: Significantly reduced installer size from 1.4GB to approximately 300MB by removing AI models from the installation package.
- **On-Demand Download**: Implemented intelligent model downloading system that automatically fetches required AI models (327MB) when the application is first launched.
@@ -336,13 +451,13 @@ The color scheme has been updated as follows:
- **Fallback URLs**: Integrated multiple download sources (GitHub Releases, SourceForge) to ensure reliable model availability.
- **Resume Capability**: Download system supports resuming interrupted downloads and validates file integrity.
#### 5.2 **PyInstaller Optimization**
#### 5.2. PyInstaller Optimization
- **Optimized Packaging**: Updated `.spec` file to exclude AI model directory from executable packaging, reducing final executable size by over 1GB.
- **Enhanced Dependencies**: Added model downloader module to the build process with proper hidden imports for requests, threading, and file handling libraries.
- **Improved Compression**: Increased optimization level and added module exclusions to further reduce executable size.
#### 5.3 **Installation Experience**
#### 5.3. Installation Experience
- **Smart Setup Script**: Created enhanced Inno Setup configuration that can optionally download models during installation or defer to first-run.
- **User Choice**: Users can choose between offline installation (models downloaded on first run) or full installation with models included.
@@ -357,7 +472,7 @@ The color scheme has been updated as follows:
### 1. Major Features & Core Capabilities
#### 1.1 **AI-Powered Face Restoration (GFPGAN)**
#### 1.1. AI-Powered Face Restoration (GFPGAN)
- **New `AI_face_restoration` Class**: A new, specialized class has been implemented to handle face restoration models. This class is architected to manage the unique preprocessing and post-processing requirements of models like GFPGAN, distinct from standard upscaling models.
- **GFPGAN Model Integration**: The GFPGAN v1.4 model has been added to the AI model repository and is now selectable from the UI. It is listed under a new `Face_restoration_models_list` category. The main orchestrator (`upscale_orchestrator`) now detects when a face restoration model is selected and routes the task to the appropriate `AI_face_restoration` instance.
@@ -365,7 +480,7 @@ The color scheme has been updated as follows:
### 2. UI/UX Modernisation
#### 2.1 **Complete Thematic Redesign**
#### 2.1. Complete Thematic Redesign
- The application has undergone a significant visual overhaul with a new, professionally designed color scheme to improve aesthetics and user comfort during long sessions. The new theme provides better contrast and a more modern look.
@@ -378,104 +493,104 @@ The color scheme has been updated as follows:
| Button Hover | `#FF6666` (Light Red) | `background_color` |
| Info Button | `#B22222` (Dark Red) | `widget_background_color` |
#### 2.2 **Enhanced Splash Screen**
#### 2.2. Enhanced Splash Screen
- **Dynamic Progress Bar**: The splash screen now features a `CTkProgressBar` to provide visual feedback on the application's loading status, enhancing the startup experience.
- **Smooth Fade-Out Animation**: A new `fade_out` method using a cosine function has been implemented for a smooth, animated exit transition instead of an abrupt disappearance.
- **Improved Information Display**: The splash screen now prominently displays the application version number.
#### 2.3 **Redesigned and Resizable Message Boxes**
#### 2.3. Redesigned and Resizable Message Boxes
- The `MessageBox` class was significantly improved to handle large blocks of text, such as detailed error messages. It now implements a `CTkScrollableFrame`, ensuring that content is always accessible without forcing the dialog to an unmanageable size.
- The dialogs now have defined `minsize` and `maxsize` properties for better window management.
#### 2.4 **Improved UI Readability**
#### 2.4. Improved UI Readability
- The main AI model dropdown menu is now logically grouped by model type (Upscaling, Denoising, Face Restoration, Interpolation), with a `MENU_LIST_SEPARATOR` between categories. This makes it easier for users to find and select the appropriate AI model for their task.
### 3. Performance and Code Optimisation
#### 4.0 **Memory Optimisation with Contiguous Arrays**
#### 3.1. Memory Optimisation with Contiguous Arrays
- Widespread use of `numpy.ascontiguousarray` has been implemented across the codebase. This is applied during critical image handling steps in `AI_upscale.preprocess_image`, `AI_interpolation.concatenate_images`, and the new `AI_face_restoration.preprocess_face_image` class. This ensures data is aligned in memory, which can significantly speed up operations in backend libraries like OpenCV and ONNX Runtime.
#### 3.2 **Refined Data Type Handling**
#### 3.2. Refined Data Type Handling
- The `AI_upscale` class now explicitly ensures input images are converted to `float32` before normalization, improving precision and preventing potential data type mismatches during inference.
- The `AI_face_restoration` class is configured to intelligently select between `float16` and `float32` based on the specific model's requirements (`fp16: True` in config), further optimizing performance and VRAM usage for compatible models.
### 4. Codebase Health and Maintainability
#### 4.1 **Specialised Class for Face Restoration**
#### 4.1. Specialised Class for Face Restoration
- The logic for face restoration has been fully encapsulated within the new `AI_face_restoration` class, separating it from the general-purpose `AI_upscale` class. This object-oriented approach makes the code more modular, readable, and easier to extend with different face enhancement models in the future.
#### 4.2 **Robust BGRA to BGR Conversion**
#### 4.2. Robust BGRA to BGR Conversion
- The application now explicitly handles images with an alpha channel (4-channel BGRA) when using face restoration models. A new import for `COLOR_BGRA2BGR` was added, and it is used within `preprocess_face_image` to convert images to the 3-channel BGR format expected by the GFPGAN model. This prevents runtime errors and ensures correct processing of PNGs or other images with transparency.
---
## Version2.2
## Version 2.2
**Release date:** 7July2025
**Release date:** 7 July 2025
### 1. Major Enhancements and Stability Overhaul
1.1 **Comprehensive Logging System**
#### 1.1. Comprehensive Logging System
- Implemented a full-featured `logging` system that writes to files in the user's `Documents` folder (`warlock_studio.log` and `error_log.txt`). This provides detailed diagnostics for debugging without relying solely on console output.
- A unified `log_and_report_error` function centralizes error handling, ensuring all critical issues are both logged and displayed to the user.
1.2 **Proactive Environment Validation**
#### 1.2. Proactive Environment Validation
- The application now performs pre-flight checks before processing begins to prevent common failures.
- Includes validation for Python version, required modules (`validate_environment`), FFmpeg availability, disk space, and available RAM (`validate_system_requirements`).
- Verifies that all input file paths exist and are accessible (`validate_file_paths`) and that the output directory is writable (`validate_output_path`).
1.3 **Resilient Video Encoding Pipeline**
#### 1.3. Resilient Video Encoding Pipeline
- The entire `video_encoding` function was overhauled for maximum reliability.
- **Codec Fallback:** The system now tests for hardware codec availability (NVENC, AMF, QSV) before encoding. If a selected hardware encoder is not functional, it automatically falls back to the highly compatible `libx264` software encoder.
- **Robust Audio Handling:** Implements a fallback chain for audio processing. It first attempts to directly copy the audio stream; if that fails, it attempts to re-encode it; if that also fails, it finalizes the video without audio, ensuring a video file is always produced.
1.4 **Graceful Shutdown and Cleanup**
#### 1.4. Graceful Shutdown and Cleanup
- Implemented `atexit` and `signal` handlers to ensure that temporary files are cleaned up and child processes are terminated safely, even on unexpected exits.
- Replaced abrupt `process.kill()` calls with the more graceful `process.terminate()` to allow for cleaner process shutdown.
### 2. Performance and Memory Optimization
2.1 **Aggressive Memory Management**
#### 2.1. Aggressive Memory Management
- Video frame processing (`upscale_video_frames_async`) no longer holds large numbers of frames in RAM. It now writes small batches to disk and immediately calls the garbage collector (`gc.collect()`) to free memory, dramatically reducing the risk of crashes on long videos.
2.2 **Dynamic GPU VRAM Error Recovery**
#### 2.2. Dynamic GPU VRAM Error Recovery
- The AI orchestration logic can now recover from GPU "out of memory" errors during tiling. If an error is detected, it automatically reduces the tile resolution and retries the operation on that specific frame, preventing a total process failure.
### 3. Critical Bug Fixes
4.0 **Resolved Video Encoding Race Condition**
#### 3.1. Resolved Video Encoding Race Condition
- Fixed a critical bug where video encoding could start before all frame-writing threads were complete. The system now tracks all writer threads and explicitly waits for them to finish (`thread.join()`) before beginning the final video encoding, preventing corrupted or incomplete videos.
3.2 **Corrected Persistent Stop Flag**
#### 3.2. Corrected Persistent Stop Flag
- The `stop_thread_flag` is now reset (`.clear()`) at the start of each "Make Magic" execution, fixing a bug where a previously stopped job would prevent a new one from running.
3.3 **Eliminated Status Update Race Condition**
#### 3.3. Eliminated Status Update Race Condition
- Implemented a `threading.Lock` (`global_status_lock`) to protect shared flags that update the GUI. This prevents race conditions where multiple threads could attempt to modify the status simultaneously.
### 4. UI / UX Refinements
4.1 **Updated Splash Screen**
#### 4.1. Updated Splash Screen
- Reduced splash screen duration to 10 seconds for a faster application start-up.
- Corrected asset path to `Assets/banner.png` for proper display.
4.2 **New Application Theme**
#### 4.2. New Application Theme
| Element | New Value | Old Value (v2.1) |
| :---------------- | :--------------- | :------------------- |
@@ -485,40 +600,40 @@ The color scheme has been updated as follows:
### 5. Codebase Health and Maintainability
5.1 **Enhanced Checkpointing and Recovery**
#### 5.1. Enhanced Checkpointing and Recovery
- Added functions (`create_checkpoint`, `load_checkpoint`) to save and resume the progress of video frame processing, allowing recovery from interruptions.
5.2 **Hardened Core Methods**
#### 5.2. Hardened Core Methods
- Core methods in AI classes now include checks for `None` inputs and feature default fallbacks (`case _:`) in `match` statements to prevent unexpected errors with unsupported data.
---
## Version2.1
## Version 2.1
**Release date:** 23June2025
**Release date:** 23 June 2025
### 1. Major Enhancements and Stability Overhaul
1.1 **Robust Error Handling**
#### 1.1. Robust Error Handling
- Model loading (`AI_upscale`, `AI_interpolation`) wrapped in `try…except FileNotFoundError, OSError`; meaningful error messages propagate to GUI.
- `extract_video_frames()` validates file existence, `cv2.VideoCapture.isOpened()`, and frame count >0.
- `extract_video_frames()` validates file existence, `cv2.VideoCapture.isOpened()`, and frame count > 0.
- `video_encoding()` captures `subprocess.CalledProcessError`, logs `stderr`, and continues with fallback strategies.
- Audio passthrough failures now trigger a silent audioless encode instead of total job abort.
1.2 **Safe Thread and Process Management**
#### 1.2. Safe Thread and Process Management
- Deprecated errorraising thread stop replaced with `threading.Event` (`stop_thread_flag`) polled at defined checkpoints.
1.3 **Resilient Core Processing**
#### 1.3. Resilient Core Processing
- `copy_file_metadata()` now verifies `exiftool.exe` availability and the existence of source/target before execution.
### 2. UI / UX Refinements
2.1 **Refined Colour Palette**
#### 2.1. Refined Colour Palette
| Element | New Value |
| ----------------- | ------------------------------- |
@@ -528,94 +643,110 @@ The color scheme has been updated as follows:
### 3. Codebase Maintainability
4.0 **Improved Code Organisation**
#### 3.1. Improved Code Organisation
- Fileextension lists extracted to `filetypes.py` as `SUPPORTED_IMAGE_EXTENSIONS`, `SUPPORTED_VIDEO_EXTENSIONS`.
3.2 **Dependency and Initialisation**
#### 3.2. Dependency and Initialisation
- Added imports: `shutil.move`, `subprocess.CalledProcessError`, `threading.Event`.
- Global variables initialised in `init_globals()` for deterministic startup.
---
## Version2.0
## Version 2.0
**Release date:** 6June2025
**Release date:** 6 June 2025
### 1. Major Features
1.1 **AI Frame Interpolation Support** (`AI_interpolation` class)
#### 1.1. AI Frame Interpolation Support (`AI_interpolation` class)
- Supports RIFEbased ONNX models; generates 1 (×2), 3 (×4), or 7 (×8) intermediate frames.
- Provides both realtime preview and batch processing modes.
- Integrates with `FrameScheduler` for temporal upscaling pipelines.
1.2 **RIFE Models Integration**
#### 1.2. RIFE Models Integration
- Added **RIFE** and **RIFE_Lite** to model repository.
- `RIFE_models_list` enumerates available checkpoints; `AI_models_list` now merges SRVGGNetCompact, BSRGAN, IRCNN, and RIFE families.
### 2. Enhancements
2.1 **Visual/UI Redesign**
#### 2.1. Visual/UI Redesign
- Application renamed to **“WarlockStudio”** (with hyphen).
- New dark palette (`#121212`, `#454242`) with bright white text (`#FFFFFF`) and accent red (`#FF0E0E`).
2.2 **VersionSpecific User Preferences**
#### 2.2. VersionSpecific User Preferences
- User configuration stored as `Warlock-Studio_<major>.<minor>_UserPreference.json` to avoid backwardcompatibility clashes.
2.3 **Modular and Scalable Layout System**
#### 2.3. Modular and Scalable Layout System
- Added GUI constants defined in `layout_constants.py` (e.g., `OFFSET_Y_OPTIONS`, `COLUMN_1_5`).
2.4 **Extended FileType Compatibility**
#### 2.4. Extended FileType Compatibility
- Updated `SUPPORTED_FILE_EXTENSIONS` and `SUPPORTED_VIDEO_EXTENSIONS` to include modern codecs (e.g., HEIC, AVIF, WebM).
2.5 **Improved GPU Execution Support**
#### 2.5. Improved GPU Execution Support
- `provider_options` enumerates up to four DirectML devices (Auto, GPU1 GPU4); selection persists across sessions.
- `provider_options` enumerates up to four DirectML devices (Auto, GPU 1 GPU 4); selection persists across sessions.
### 3. Technical Refinements
4.0 **Model List Structure**
#### 3.1. Model List Structure
- Menu dropdowns now grouped by category separated by `MENU_LIST_SEPARATOR` for readability.
3.2 **Advanced Interpolation Logic**
#### 3.2. Advanced Interpolation Logic
- Implements treebased frame generation (e.g., D→ABC) with dependency tracking to avoid redundant inference passes.
3.3 **Improved Numeric Precision and PostProcessing**
#### 3.3. Improved Numeric Precision and PostProcessing
- Normalisation uses 32bit floats with epsilon guarding; RGBA conversion paths optimised using `numexpr`.
### 4. UI / UX Refinements
4.1 **Resizable Message Dialogs** (`MessageBox`; Tk `resizable(True, True)`).
4.2 **Improved Dialog Formatting** uniform spacing, font hierarchy, and defaultvalue display.
#### 4.1. Resizable Message Dialogs
- `MessageBox`; Tk `resizable(True, True)`.
#### 4.2. Improved Dialog Formatting
- Uniform spacing, font hierarchy, and defaultvalue display.
### 5. Minor Fixes
#### 5.1. Code Corrections
- Corrected typo `ttext_color``text_color`.
- Expanded inline comments and reorganised sections for clarity.
---
## Version1.1
## Version 1.1
**Release date:** 20May2025
**Release date:** 20 May 2025
### 1. Major Improvements
1.1 **Program Startup Optimisation** launch time reduced via lazy module loading.
1.2 **Model Loading Improvements** parallel prefetch and checksum verification.
1.3 **General Performance Optimisation** core refactor, improved I/O scheduling, and smarter resource allocation.
#### 1.1. Program Startup Optimisation
- Launch time reduced via lazy module loading.
#### 1.2. Model Loading Improvements
- Parallel prefetch and checksum verification.
#### 1.3. General Performance Optimisation
- Core refactor, improved I/O scheduling, and smarter resource allocation.
### 2. Minor Fixes
- Userinterface tweaks for better accessibility (focus indicators, tab order).
#### 2.1. Accessibility
- Userinterface tweaks for better accessibility (focus indicators, tab order).
Binary file not shown.
+165 -267
View File
@@ -56,7 +56,7 @@
% --- CORPORATE COLOR PALETTE ---
\definecolor{WarlockRed}{HTML}{C11919}
\definecolor{WarlockGold}{HTML}{ECD125}
\definecolor{WarlockDark}{HTML}{1A1C1E}
\definecolor{WarlockDark}{HTML}{1B1818} % Updated to match v5.0 Theme
\definecolor{WarlockGray}{HTML}{333333}
\definecolor{WarlockLightGray}{HTML}{F0F0F0}
\definecolor{WarlockWhite}{HTML}{FFFFFF}
@@ -79,6 +79,9 @@
\definecolor{WarnBorder}{HTML}{FFBE0B}
\definecolor{QuickStartFill}{HTML}{E6FFFA}
\definecolor{QuickStartBorder}{HTML}{00796B}
% New Palette for NEO Engine
\definecolor{NeoFill}{HTML}{F3E5F5}
\definecolor{NeoBorder}{HTML}{8E44AD}
% --- DEFAULT TEXT COLOR APPLICATION ---
\color{WarlockGray}
@@ -93,11 +96,11 @@
linkcolor=WarlockRed,
filecolor=WarlockRed,
urlcolor=WarlockRed,
pdftitle={Warlock-Studio | Technical Documentation and User Manual},
pdftitle={Warlock-Studio v5.0 | Technical Documentation and User Manual},
pdfauthor={Iván Eduardo Chavez Ayub}
}
% --- SECTION & SUBSECTION TITLES (CORRECTED) ---
% --- SECTION & SUBSECTION TITLES ---
\newcommand{\SectionColor}{WarlockGray} % Default color
\newcommand{\setsectioncolor}[1]{\renewcommand{\SectionColor}{#1}}
@@ -162,15 +165,26 @@
shadow={2mm}{-1mm}{0mm}{black!20!white},
#1
}
% New box for NEO Engine / Hardware features
\newtcolorbox{neobox}[2][]{
enhanced, breakable,
colback=NeoFill, colframe=NeoBorder,
fonttitle=\bfseries, coltitle=NeoBorder!80!black,
title=\faMicrochip\hspace{0.5em}#2,
attach boxed title to top left={yshift=-2mm, xshift=3mm},
boxed title style={colback=NeoBorder, sharp corners},
coltext=WarlockDark,
shadow={2mm}{-1mm}{0mm}{black!20!white},
#1
}
% --- INLINE CODE COMMAND ---
% Use detokenize to preserve special characters and avoid problematic hyphenation
\newcommand{\inlinecode}[1]{\colorbox{WarlockLightGray}{\small\texttt{\detokenize{#1}}}}
% --- HEADER & FOOTER ---
\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{\textit{Warlock-Studio v4.3}}
\fancyhead[L]{\textit{Warlock-Studio v5.0}}
\fancyhead[R]{\leftmark}
\fancyfoot[L]{\includegraphics[height=0.8cm]{logo.png}}
\fancyfoot[C]{\thepage}
@@ -184,7 +198,7 @@
% =======================================================================================
\begin{document}
% --- REDESIGNED TITLE PAGE (KEEPING ORIGINAL STYLE FROM YOUR BASE CODE) ---
% --- REDESIGNED TITLE PAGE ---
\begin{titlepage}
\begin{tcolorbox}[
enhanced, sharp corners,
@@ -205,7 +219,7 @@
\color{WarlockWhite}
{\Large\bfseries Technical Documentation and User Guide\par}
\vspace{0.2cm}
{\large Software Version: 4.3\par}
{\large Software Version: 5.0 (NEO-Refactor)\par}
\vspace{0.4cm}
\color{WarlockGold}
\rule{0.6\textwidth}{1pt}\par
@@ -226,9 +240,12 @@
% SECTION 1: INTRODUCTION
% =======================================================================================
\setsectioncolor{IntroColor}
\section{Introduction to Warlock-Studio}
Welcome to Warlock-Studio — an AI-powered suite for digital media enhancement.
It provides advanced tools for super-resolution, artifact removal, and frame generation through an intuitive interface that delivers professional-quality results with minimal effort.
\section{Introduction to Warlock-Studio v5.0}
Welcome to Warlock-Studio v5.0 — a major evolutionary leap in AI-powered media enhancement.
This version introduces a robust \textbf{Modular Architecture} and the new \textbf{NEO Engine}, optimizing
stability, hardware diagnostics, and processing efficiency. It provides advanced tools for super-resolution,
artifact removal, and frame generation through an intuitive interface that now includes an \textbf{Integrated Console}
and native \textbf{Drag \& Drop} support.
% =======================================================================================
% SECTION 2: QUICK START GUIDE
@@ -236,18 +253,19 @@ It provides advanced tools for super-resolution, artifact removal, and frame gen
\setsectioncolor{QuickStartColor}
\section{Quick Start Guide}
\begin{quickstartbox}{Accelerated Media Enhancement Procedure}
Follow these 5 steps to process your first media file in less than a minute.
Follow these steps to process your media using the new v5.0 workflow.
\begin{enumerate}
\item \textbf{Load Files:} Click the \textbf{"SELECT FILES"} button and choose one or more image or video files for processing.
\item \textbf{Load Files (Drag \& Drop):} You can now simply \textbf{drag and drop} your image or video files directly onto the application window. Alternatively, click the \textbf{"Select Files"} button.
\item \textbf{AI Model Selection:} In the \textbf{"AI model"} dropdown menu, select an inference model.
\begin{itemize}
\item For photorealistic images, \inlinecode{BSRGANx4} is recommended for its ability to reconstruct fine textures.
\item For animation or illustrated content, \inlinecode{RealESR_Animex4} is the optimal choice for preserving sharp edges.
\item For video sequences, \inlinecode{RealESR_Gx4} offers an excellent balance between computational performance and perceptual quality.
\item For photorealistic images, \inlinecode{BSRGANx4} is recommended for texture reconstruction.
\item For animation/cartoons, \inlinecode{RealESR_Animex4} preserves sharp edges.
\item For video, \inlinecode{RealESR_Gx4} balances speed and quality.
\item For increasing framerate, use \inlinecode{RIFE} models (note: Blending controls will hide automatically).
\end{itemize}
\item \textbf{Adjust Input Resolution:} For a quick first pass, set \textbf{"Input resolution"} to \texttt{75}\%. This significantly reduces the computational load with an often imperceptible loss in final quality.
\item \textbf{Verify VRAM Limit:} Ensure the value in \textbf{"GPU VRAM (GB)"} is equal to or less than your graphics card's dedicated video memory. An initial value of \texttt{4} GB is a safe setting for most modern hardware.
\item \textbf{Start Processing:} Click \textbf{"Make Magic"} to initiate the processing pipeline. The output files will be generated in the specified directory or, by default, in the same location as the source files.
\item \textbf{Verify Hardware (NEO Engine):} Click the \textbf{Gear Icon} (\faCog) to open Preferences. Check the \textbf{Hardware Diagnostics} to see the "Recommended Tiles" and "Safe VRAM Limit" calculated specifically for your PC.
\item \textbf{Adjust Settings:} Set the \textbf{"GPU VRAM (GB)"} based on the recommendation. For a quick test, set \textbf{"Input resolution"} to \texttt{75}\%.
\item \textbf{Start Processing:} Click \textbf{"Make Magic"}. You can now monitor real-time progress and logs via the new \textbf{Integrated Console} at the bottom of the window.
\end{enumerate}
\end{quickstartbox}
@@ -255,14 +273,22 @@ Follow these 5 steps to process your first media file in less than a minute.
% SECTION 3: INSTALLATION & ARCHITECTURE
% =======================================================================================
\setsectioncolor{InstallColor}
\section{Installation and System Architecture}
\subsection{\faDownload\ Installation Process}
Warlock-Studio uses a self-contained offline installer, simplifying deployment.
\section{Installation and Modular Architecture}
\subsection{\faDownload\ Installation Process \& Path Change}
Warlock-Studio uses a self-contained offline installer.
\begin{warnbox}{Critical: Installation Directory Change}
In version 5.0, the default installation directory has been migrated from \texttt{Program Files} to:
\begin{center}
\inlinecode{\%userprofile\%\\Documents\\Warlock-Studio}
\end{center}
\textbf{Reason:} This change prevents "Permission Denied" errors on Windows systems with strict UAC. It ensures the application has full read/write access to generate the \inlinecode{warlock_config.json}, write real-time logs, and manage video checkpoints without requiring constant Administrator privileges.
\end{warnbox}
\begin{enumerate}[leftmargin=*]
\item \textbf{Obtaining the Executable:} Download the `Warlock-Studio-Setup.exe` file from the official repositories on GitHub or SourceForge.
\item \textbf{Run with Elevated Privileges:} Right-click the installer and select "Run as administrator." This step is crucial to ensure the application has the necessary permissions to interact with low-level GPU drivers.
\item \textbf{Installation Wizard:} Follow the on-screen instructions. The inclusion of all AI models and dependencies eliminates the need for additional downloads during this process.
\item \textbf{Launch the Application:} Once the installation is complete, Warlock-Studio can be launched from the Start Menu or the desktop shortcut.
\item \textbf{Obtaining the Executable:} Download the `Warlock-Studio-Setup.exe` (Full Installer) from the official repositories.
\item \textbf{Run the Installer:} Run the setup. It will automatically default to your Documents folder.
\item \textbf{Launch:} Open Warlock-Studio via the Desktop shortcut.
\end{enumerate}
\subsection{\faMicrochip\ System Requirements}
@@ -273,39 +299,33 @@ Warlock-Studio uses a self-contained offline installer, simplifying deployment.
\textbf{Component} & \textbf{Technical Specification} \\
\midrule
Operating System & Windows 11 or Windows 10 (64-bit architecture required). \\
RAM & 8 GB (minimum), 16 GB (recommended for high-resolution video processing). \\
Graphics Card (GPU) & \textbf{Mandatory Requirement:} GPU with support for the \textbf{DirectX 12} API. \\
& \textbf{NVIDIA (for CUDA):} Maxwell architecture (GTX 900 Series) or newer. Studio drivers are recommended for stability. \\
& \textbf{AMD/Intel (for DirectML):} Any modern GPU with updated drivers that support DirectX 12 Feature Level 12.0+. \\
& \textbf{4+ GB of VRAM} is recommended to avoid memory bottlenecks. \\
Storage & 2 GB of free disk space. Using a Solid State Drive (SSD) drastically improves I/O performance during video sequence processing. \\
RAM & 8 GB (minimum), 16 GB (recommended). \\
Graphics Card (GPU) & \textbf{Mandatory Requirement:} GPU with \textbf{DirectX 12} support. \\
& \textbf{NVIDIA:} CUDA support (Maxwell or newer). \\
& \textbf{AMD/Intel:} DirectML support. \\
& \textbf{4+ GB of VRAM} is recommended. \\
Storage & 2 GB of free disk space. SSD strongly recommended for video I/O. \\
\bottomrule
\end{tabularx}
\caption{Hardware and software specifications for optimal performance of Warlock-Studio.}
\caption{Requirements for v5.0. The NEO Engine will verify these upon launch.}
\end{table}
\subsection{\faFolderOpen\ File Structure and Dependencies}
\begin{infobox}{Self-Contained Components}
Warlock-Studio operates as a fully self-contained environment.
All critical assets, dependencies, and user data are automatically managed by the application, requiring no manual configuration from the user.
\subsection{\faPuzzlePiece\ Modular File Architecture (v5.0)}
\begin{infobox}{From Monolithic to Modular}
Version 5.0 abandons the single-script structure. The application is now composed of specialized modules to improve stability and maintainability.
\end{infobox}
\begin{itemize}[leftmargin=*]
\item \textbf{Core Assets:}
The executables \inlinecode{ffmpeg.exe} (for video encoding/decoding) and \inlinecode{exiftool.exe} (for metadata preservation) are stored in the \texttt{Assets} directory.
Their paths are dynamically resolved through the \inlinecode{find_by_relative_path} function, which accurately locates resources in both development and bundled environments (using the \inlinecode{_MEIPASS} directory created by PyInstaller).
\item \textbf{AI Models:}
All AI inference models are provided in interoperable \texttt{.onnx} format and stored within the \texttt{AI-onnx} directory.
This ensures cross-platform compatibility and seamless hardware acceleration through ONNX Runtime.
\item \textbf{User Preferences:}
The configuration file \inlinecode{USER_PREFERENCE_PATH} is automatically generated in the users \textbf{Documents} folder (\inlinecode{os_path_expanduser('~')}).
It stores GUI layout, last-used settings, and model selections between sessions.
\item \textbf{Diagnostic Logs:}
Log files (\inlinecode{MAIN_LOG_FILENAME} and \inlinecode{ERROR_LOG_FILENAME}) are created in a dedicated subfolder inside \textbf{Documents}.
These serve as vital diagnostic resources, recording operational events, system validation reports, and runtime exceptions for troubleshooting.
\item \textbf{\inlinecode{Warlock-Studio.py} (Core Orchestrator):}
Manages the main GUI event loop and spawns multiprocessing tasks for AI inference.
\item \textbf{\inlinecode{warlock_preferences.py} (State Manager):}
Houses the \textbf{NEO Engine} for hardware telemetry, the \inlinecode{ConfigManager} for JSON persistence, and the OTA Update Manager.
\item \textbf{\inlinecode{console.py} (I/O Manager):}
Controls the new \textbf{Integrated Console}, redirecting \texttt{stdout} and \texttt{stderr} streams to the GUI for real-time debugging.
\item \textbf{\inlinecode{drag_drop.py} (Event Wrapper):}
Implements the \inlinecode{DnDCTk} class to handle native OS Drag \& Drop events.
\item \textbf{Assets:}
Includes \inlinecode{ffmpeg.exe}, \inlinecode{exiftool.exe}, and the AI Models (`.onnx`) in the \texttt{AI-onnx} directory.
\end{itemize}
@@ -315,300 +335,178 @@ All critical assets, dependencies, and user data are automatically managed by th
\setsectioncolor{ModelsColor}
\section{Detailed Analysis of Inference Models}
\begin{infobox}{Model Selection Overview}
Selecting the appropriate AI inference model is the most critical decision
in Warlock-Studios enhancement pipeline. It directly determines the balance
between visual quality, computational efficiency, and hardware resource usage.
Each model implements distinct neural architectures and loss functions, optimized
for different types of input data and output fidelity targets.
The following section provides a comprehensive technical breakdown and comparative
analysis to support informed model selection.
\begin{infobox}{Dynamic Interface Adaptation}
In v5.0, the interface adapts to your model selection. Selecting a \textbf{RIFE} model will automatically hide "Blending" controls and reveal "Frame Generation" options. Selecting an \textbf{Upscaling} model does the reverse.
\end{infobox}
\subsection{\faTable\ Model Comparison Matrix}
\begin{longtable}{p{2.8cm} p{1.8cm} p{1.2cm} p{1.5cm} p{7.2cm}}
\toprule
\textbf{Model} & \textbf{Primary Function} & \textbf{Scale} & \textbf{VRAM (GB)} & \textbf{Use Case and Technical Considerations} \\
\textbf{Model} & \textbf{Function} & \textbf{Scale} & \textbf{VRAM} & \textbf{Use Case} \\
\midrule
\endhead
\multicolumn{5}{c}{\textit{\textbf{\faEraser\ Denoising Models}}} \\
\multicolumn{5}{c}{\textit{\textbf{\faEraser\ Denoising}}} \\
\midrule
\texttt{IRCNN\_Mx1} & Denoise & x1 & 4.0 & Moderate-level noise reduction. Ideal for suppressing JPEG compression artifacts and low-ISO sensor noise in old photographs. \\
\texttt{IRCNN\_Lx1} & Denoise & x1 & 4.0 & Intensive noise reduction algorithm. Optimal for severely degraded images with pronounced luminance and chrominance noise. \\
\texttt{IRCNN\_Mx1} & Denoise & x1 & 4.0 & Moderate noise reduction (JPEG artifacts). \\
\texttt{IRCNN\_Lx1} & Denoise & x1 & 4.0 & Intensive noise reduction for degraded images. \\
\midrule
\multicolumn{5}{c}{\textit{\textbf{\faTachometerAlt\ High-Fidelity Upscaling Models (Computationally Intensive)}}} \\
\multicolumn{5}{c}{\textit{\textbf{\faTachometerAlt\ High-Fidelity Upscaling}}} \\
\midrule
\texttt{BSRGANx4} & Upscale & x4 & 0.6 & Generative Adversarial Network optimized for realistic texture synthesis. It is the model of choice for portraits, nature photography, and where the preservation of fine details is paramount. \\
\texttt{BSRGANx2} & Upscale & x2 & 0.7 & A variant with a reduced scaling factor. It offers a perceptual quality similar to the x4 version but with lower computational cost, ideal for moderate upscaling needs. \\
\texttt{RealESRGANx4} & Upscale & x4 & 0.6 & A robust general-purpose model. It excels in reconstructing a wide variety of content, including textures, landscapes, and architectural elements. \\
\texttt{RealESRNetx4} & Upscale & x4 & 2.2 & An alternative to RealESRGAN, often producing results with fewer "hallucinatory" artifacts. It can offer a better balance between speed and fidelity on certain GPU architectures. \\
\texttt{BSRGANx4} & Upscale & x4 & 0.6 & Photorealistic texture synthesis. Best for portraits/nature. \\
\texttt{RealESRGANx4} & Upscale & x4 & 0.6 & General-purpose robust reconstruction. \\
\midrule
\multicolumn{5}{c}{\textit{\textbf{\faBolt\ High-Speed Upscaling Models (Lightweight)}}} \\
\multicolumn{5}{c}{\textit{\textbf{\faBolt\ High-Speed Upscaling}}} \\
\midrule
\texttt{RealESR\_Gx4} & Upscale & x4 & 2.2 & A lightweight and fast model, optimized for real-time or near-real-time video processing. It offers an excellent compromise between performance and visual quality. \\
\texttt{RealESR\_Animex4} & Upscale & x4 & 2.2 & Specialized for non-photorealistic content. It preserves sharp lines and flat colors, avoiding the smoothing artifacts common in models trained on natural data. \\
\texttt{RealESR\_Gx4} & Upscale & x4 & 2.2 & Fastest model. Optimized for video. \\
\texttt{RealESR\_Animex4} & Upscale & x4 & 2.2 & Optimized for Anime/Cartoons (clean lines). \\
\midrule
\multicolumn{5}{c}{\textit{\textbf{\faUserCircle\ Facial Restoration Models}}} \\
\multicolumn{5}{c}{\textit{\textbf{\faUserCircle\ Facial Restoration}}} \\
\midrule
\texttt{GFPGAN} & Restore & x1 & 1.8 & Generative Adversarial Network with a facial prior. It not only upscales but also reconstructs and enhances damaged or low-resolution facial features in photographs. \\
\texttt{GFPGAN} & Restore & x1 & 1.8 & Face reconstruction. v5.0 enforces \textbf{Float32} precision for stability. \\
\midrule
\multicolumn{5}{c}{\textit{\textbf{\faFilm\ Frame Interpolation Models (Video Only)}}} \\
\multicolumn{5}{c}{\textit{\textbf{\faFilm\ Frame Interpolation (FluidFrames)}}} \\
\midrule
\texttt{RIFE} & Interpolate & N/A & \textasciitilde{}1.5 & High-quality algorithm for motion interpolation. It generates intermediate frames to increase the fluidity of a video (e.g., from 30 to 60 FPS). \\
\texttt{RIFE\_Lite} & Interpolate & N/A & \textasciitilde{}1.2 & An optimized variant of RIFE, designed for GPUs with limited VRAM. It offers faster processing at the cost of a slight reduction in interpolation accuracy. \\
\texttt{RIFE} & Interpolate & N/A & \textasciitilde{}1.5 & Generates intermediate frames (x2, x4, x8). \\
\texttt{RIFE\_Lite} & Interpolate & N/A & \textasciitilde{}1.2 & Faster variant for lower-end GPUs. \\
\midrule
\bottomrule
\caption{Technical guide for the selection of AI models. VRAM values are base estimates derived from the \inlinecode{VRAM_model_usage} dictionary in the source code and may vary.}
\caption{Technical guide for AI models. VRAM values are base estimates.}
\label{tab:modelos}
\end{longtable}
% =======================================================================================
% SECTION 5: BEST PRACTICES & OPTIMIZATION
% SECTION 5: OPTIMIZATION & NEO ENGINE
% =======================================================================================
\setsectioncolor{OptimizeColor}
\section{Performance Optimization and Best Practices}
\section{Performance Optimization and NEO Engine}
\subsection{\faMagic\ The NEO Engine}
\begin{neobox}{Automatic Hardware Heuristics}
Warlock-Studio v5.0 introduces the \textbf{NEO Engine} (located in \inlinecode{warlock_preferences.py}). This system scans your CPU, RAM, and GPU capabilities in real-time to generate \textbf{Smart Recommendations}.
\end{neobox}
\subsection{\faSlidersH\ Critical Performance Parameters}
\begin{itemize}[leftmargin=*, itemsep=2pt]
\item \textbf{Input Resolution \%:} This is the most influential parameter on processing speed. A value between \textbf{50\% and 75\%} implements an initial downsampling before upscaling, drastically reducing the computational load with minimal impact on the final perceptual quality.
\item \textbf{GPU VRAM Limiter (GB):} Defines the video memory budget.
This value (from \inlinecode{selected_VRAM_limiter.get()}) is used in a precise formula
to calculate the internal \inlinecode{tiles_resolution} parameter:
\begin{center}
\begin{tcolorbox}[
enhanced,
colback=WarlockLightGray!30,
colframe=OptimizeColor!80!black,
boxrule=0.6pt,
arc=2pt,
left=4pt,right=4pt,top=2pt,bottom=2pt,
width=0.9\linewidth
]
\small
\texttt{vram\_factor = VRAM\_model\_usage[model] * VRAM\_GB\_input}\\
\texttt{tiles\_resolution = int(vram\_factor * 100)}
\end{tcolorbox}
\end{center}
This \inlinecode{tiles_resolution} (e.g., \texttt{880px} for a 4~GB card using
\inlinecode{RealESR_Gx4}) is then used as the maximum tile dimension for image processing,
ensuring full stability and preventing \textbf{Out Of Memory (OOM)} errors during inference.
\item \textbf{AI Multithreading:} (Video only) Allows for the parallel processing of multiple frames via a \inlinecode{ThreadPool}. It significantly increases performance on systems with multi-core CPUs, but at the cost of higher VRAM and CPU consumption.
\item \textbf{AI Blending:} Mitigates visual artifacts. This value (from \inlinecode{selected_blending_factor}) is passed to the \inlinecode{blend_images_and_save} function, which uses OpenCV's \inlinecode{addWeighted} to perform an alpha blend between the original upscaled image and the AI-processed image.
\item \textbf{System Validation:} Before starting, the \inlinecode{validate_system_requirements} function automatically checks for the presence of \inlinecode{ffmpeg.exe}, available disk space, and available system RAM (using the \inlinecode{psutil} library).
\item \textbf{Safe VRAM Limit:} The engine calculates a safe buffer using the formula: $\max(0.5, \text{Physical VRAM} - 1.5 \text{ GB})$.
\item \textbf{Recommended Tiles:} It suggests the optimal \inlinecode{tiles_resolution} to maximize speed while preventing Out-Of-Memory (OOM) crashes.
\item \textbf{Thread Concurrency:} It analyzes your CPU topology (physical vs. logical cores) to suggest safe multithreading levels for video processing.
\end{itemize}
\subsection{\faTrophy\ Tips for Maximum Quality Results}
\begin{tcolorbox}[
enhanced, breakable,
colback=QuickStartFill,
colframe=QuickStartBorder,
coltitle=QuickStartBorder!80!black,
title=\faStar\hspace{0.5em}\textbf{Expert Recommendations for Optimal Output},
fonttitle=\bfseries,
sharp corners,
boxrule=0.6pt,
shadow={1mm}{-1mm}{0mm}{black!10!white}
]
\begin{description}[leftmargin=*, style=nextline, itemsep=1em]
\item[\textbf{Maximizing Visual Fidelity}]
To achieve the highest possible perceptual quality, use the \inlinecode{BSRGANx4} or \inlinecode{RealESRGANx4} models with an \textbf{Input Resolution} of \textbf{100\%}.
Although computationally demanding, this configuration ensures maximum reconstruction of micro-textures and reduces information loss, especially on portrait or landscape imagery.
\item[\textbf{Workflow for Video Restoration}]
A robust two-stage restoration pipeline for archival or degraded footage involves:
\begin{enumerate}[nosep, leftmargin=*]
\item \textbf{Stage 1 — Denoising:} Apply a denoising model such as \inlinecode{IRCNN\_Mx1} to clean sensor noise and compression artifacts.
\item \textbf{Stage 2 — Upscaling:} Use an upscaling model such as \inlinecode{RealESR\_Gx4} on the cleaned output to reconstruct fine detail while maintaining temporal coherence.
\end{enumerate}
\item[\textbf{Impact of SSD Storage}]
A Solid State Drive (SSD) significantly improves throughput during video restoration.
The extraction (\inlinecode{extract\_video\_frames}), writing (\inlinecode{save\_frames\_on\_disk}), and reassembly (\inlinecode{video\_encoding}) of thousands of frames represent the main I/O bottlenecks; SSDs mitigate these delays and improve system responsiveness.
\item[\textbf{Frame Persistence for Experimentation}]
For testing different encoding settings (e.g., codecs or bitrates), enable the \textbf{"Keep frames"} option (\inlinecode{selected\_keep\_frames = True}).
This preserves the processed frames on disk, allowing video re-encoding without repeating the AI inference phase — saving time and extending the experimental workflow.
\end{description}
\end{tcolorbox}
\subsection{\faSlidersH\ Critical Parameters}
\begin{itemize}[leftmargin=*, itemsep=2pt]
\item \textbf{Input Resolution \%:} Setting this to \textbf{75\%} drastically reduces load with minimal quality loss.
\item \textbf{AI Multithreading:} (Video only) Processes multiple frames in parallel. Use the NEO Engine's recommendation to avoid system freezing.
\item \textbf{Keep Frames:} Enable this (\inlinecode{selected_keep_frames = True}) if you plan to experiment with different video encoding codecs later.
\end{itemize}
% =======================================================================================
% SECTION 6: TROUBLESHOOTING
% =======================================================================================
\setsectioncolor{TroubleColor}
\section{Diagnostics and Troubleshooting}
\begin{warnbox}{Primary Cause of Errors}
The \textbf{\#1 cause} of processing failures is \textbf{non-standard characters} in file paths and filenames. Avoid using: \texttt{', ", @, \#, \$, \%, \&, *, [, ], ?, etc.}.
\begin{warnbox}{Integrated Console}
Use the new **Integrated Console** at the bottom of the app window to view real-time error logs, warnings, and processing status. You can search, copy, and save these logs.
\end{warnbox}
\begin{description}[leftmargin=*, style=nextline, itemsep=0.8em]
\item[\faBan\ Error: "FFmpeg encoding failed..."]
\textbf{Diagnosis:} The \inlinecode{video_encoding} function, which uses \inlinecode{subprocess_run}, has failed. The code specifically checks for several causes:
\begin{itemize}[nosep, leftmargin=*]
\item \textbf{"Invalid argument"}: Most commonly caused by special characters in file paths.
\item \textbf{"Unknown encoder"}: The selected video codec (e.g., \inlinecode{hevc_nvenc}) is not supported by your FFmpeg build or hardware.
\item \textbf{"Device or resource busy"}: Your GPU's hardware encoder is being used by another application (e.g., OBS, ShadowPlay).
\end{itemize}
\textbf{Solution:} Rename files to remove special characters. For encoder errors, select a different codec (e.g., \inlinecode{x264} or \inlinecode{x265}).
\item[\faBan\ Error: "FFmpeg encoding failed..." / Fallback Active]
\textbf{Diagnosis:} The selected hardware codec (e.g., \inlinecode{hevc_nvenc}) failed due to driver issues or resource locking.
\textbf{v5.0 Solution:} The system now features an \textbf{Automatic Fallback}. If the GPU encoder fails, it automatically switches to the CPU-based \inlinecode{libx264} encoder to ensure the video is finished. Check the console for yellow warnings indicating this switch.
\item[\faRocket\ Error: "Failed to load model" or Execution Provider Failure]
\textbf{Diagnosis:} Failure in the initialization of the selected hardware backend, caught within the \inlinecode{create_onnx_session} function.
\textbf{Solution:} The system is designed to automatically fall back to a functional provider in the hierarchy (CUDA -> DirectML -> CPU). To resolve the root cause:
\begin{enumerate}[nosep, leftmargin=*]
\item \textbf{For CUDA errors:} Verify the installation of the latest NVIDIA drivers (Game Ready or Studio).
\item \textbf{For DirectML errors:} Ensure that the Windows operating system is fully updated and that you have the latest drivers for your GPU (NVIDIA, AMD, or Intel).
\end{enumerate}
\item[\faMemory\ Error: "Out of memory" / OOM Recovery]
\textbf{Diagnosis:} VRAM exhaustion during tiling.
\textbf{v5.0 Solution:} The application detects this exception and triggers \textbf{Recursive Dynamic Tiling}. It automatically halves the tile resolution (e.g., 100\% $\to$ 50\%) and retries the frame. You do not need to restart the process manually.
\item[\faMemory\ Error: "out of memory" (OOM) or "allocation" failure]
\textbf{Diagnosis:} The GPU's VRAM has been exhausted. This error is caught within the \inlinecode{upscale_video_frames_async} function.
\textbf{Solution:}
\begin{enumerate}[nosep, leftmargin=*]
\item Lower the \textbf{VRAM Limiter} to a value equal to or less than your GPU's physical VRAM.
\item Decrease the \textbf{Input Resolution \%} to 75\% or less.
\item \textbf{Automatic Recovery:} The code will attempt an automatic recovery. It progressively reduces the processing tile size (by lowering the \inlinecode{AI_instance.max_resolution} variable) and retries the failed frame.
\end{enumerate}
\item[\faRocket\ Error: "Failed to load model" (ONNX)]
\textbf{Diagnosis:} Issue initializing the execution provider.
\textbf{Solution:} v5.0 implements a strict priority chain: CUDA $\to$ DirectML $\to$ CPU. Ensure your GPU drivers are up to date. If using an older NVIDIA card, the system may default to DirectML or CPU.
\item[\faTachometerAlt\ Error: "cannot convert float NaN to integer"]
\textbf{Diagnosis:} This specific error is caught in the main \inlinecode{upscale_orchestrator}. It indicates a GPU driver timeout (TDR - Timeout Detection and Recovery), often caused by hardware overload or overheating, which returns a "Not a Number" (NaN) value instead of pixel data.
\textbf{Solution:} Restart the process \textbf{without deleting the generated frames folder}. The application will detect the existing frames and resume the task from the point of failure.
\item[\faTachometerAlt\ Error: "NaN" (Not a Number)]
\textbf{Diagnosis:} GPU Driver Timeout (TDR).
\textbf{Solution:} Restart the process without deleting the temp frames folder. The app will resume from the last successful frame.
\end{description}
% =======================================================================================
% SECTION 7: ADVANCED TECHNICAL ARCHITECTURE
% =======================================================================================
\setsectioncolor{ArchColor}
\section{Software Architecture Analysis}
\section{Software Architecture Analysis (v5.0)}
\subsection{\faCogs\ Inference Engine and Hardware Abstraction}
Warlock-Studio is built upon a multi-layered inference engine powered by \textbf{ONNX Runtime}. The \inlinecode{create_onnx_session} function abstracts the underlying hardware and prioritizes Execution Providers to maximize performance:
\begin{enumerate}[leftmargin=*]
\item \textbf{CUDA (\texttt{CUDAExecutionProvider}):} The highest performance option, leveraging the parallel computing architecture of NVIDIA GPUs.
\item \textbf{DirectML (\texttt{DmlExecutionProvider}):} If CUDA is not available, the system falls back to DirectML. This Microsoft API translates neural network operations into native \textbf{DirectX 12} calls, ensuring broad hardware compatibility (NVIDIA, AMD, Intel).
\item \textbf{CPU (\texttt{CPUExecutionProvider}):} This is the last resort provider. If no GPU acceleration is viable, the application runs the model on the CPU, guaranteeing universal functionality at the cost of significantly lower performance.
\end{enumerate}
\subsection{\faCogs\ Modular Inference Engine}
Warlock-Studio v5.0 utilizes a robust \textbf{ONNX Runtime} backend managed by the \inlinecode{create_onnx_session} factory in the core orchestrator. It enforces strict integer typing for device IDs to ensure compatibility with rigid DirectML backends.
\subsection{\faThLarge\ Dynamic Tiling and Memory Management}
To process high-resolution media, the \inlinecode{AI_upscale_with_tilling} function is invoked. It programmatically subdivides a large frame into smaller "tiles" based on the \inlinecode{max_resolution} variable. This \inlinecode{max_resolution} (confusingly named \inlinecode{tiles_resolution} in the GUI logic) is the pixel dimension calculated directly from the user's \textbf{VRAM Limiter} input, ensuring that no single tile exceeds the GPU's memory budget.
\subsection{\faSyncAlt\ Lossless Intermediate Pipeline}
In v5.0, the video extraction pipeline (\inlinecode{extract_video_frames}) strictly enforces the use of \textbf{.PNG} containers for temporary frames. This eliminates the generation loss previously caused by JPEG artifacts before the image entered the neural network.
\subsection{\faSyncAlt\ Resume and Checkpointing Functionality}
If a video process is interrupted, the frames already processed and written to disk are preserved. Upon restarting the same task, the \inlinecode{check_video_upscaling_resume} function detects these partial files by checking for their existence. It then returns a list of only the *original* frames that still need processing, allowing the \inlinecode{upscale_video} orchestrator to resume the task from the point of failure.
\subsection{\faBolt\ Asynchronous Frame Writing}
During video upscaling, the main processing loop in \inlinecode{upscale_video_frames_async} does not write to disk directly. Instead, it batches processed frames in memory. Once a batch is ready (defaulting to \inlinecode{MULTIPLE_FRAMES_TO_SAVE = 8}), it calls \inlinecode{save_frames_on_disk}, which spawns a new \inlinecode{Thread} from the `threading` module to run \inlinecode{save_multiple_upscaled_frame_async}. This decouples the GPU-bound inference from the I/O-bound disk writing, maximizing GPU utilization.
% =======================================================================================
% SECTION 8: PROCESSING PIPELINE DIAGRAM (FIXED TO PAGE WIDTH)
% =======================================================================================
\section{Processing Pipeline (Diagram)}
\subsection{\faThLarge\ Architecture Diagram (Modular)}
\noindent
The following diagram illustrates the high-level processing pipeline.
\begin{figure}[H]
\centering
% Resize to text width to avoid overflow
\resizebox{\textwidth}{!}{%
\begin{tikzpicture}[node distance=12mm, every node/.style={font=\small}, >=Stealth]
\tikzset{
box/.style={rectangle, rounded corners=4pt, draw=WarlockDark!80!black, fill=WarlockDark!6, minimum width=48mm, minimum height=9mm, align=center, drop shadow},
proc/.style={rectangle, rounded corners=3pt, draw=WarlockGold!70!black, fill=WarlockGold!12, minimum width=48mm, minimum height=9mm, align=center},
disk/.style={cylinder, shape border rotate=90, draw=WarlockGray!70!black, fill=WarlockLightGray, minimum width=10mm, minimum height=10mm, align=center},
arrow/.style={->, thick, draw=WarlockDark!80!black}
}
\node[box] (ingest) {\textbf{Input Ingest}\\(images \& video)};
\node[proc, right=28mm of ingest] (analysis) {\textbf{Preprocessing}\\format, resize, color space};
\node[proc, right=28mm of analysis] (model) {\textbf{AI Inference}\\selected model(s)};
\node[box, right=28mm of model] (post) {\textbf{Postprocess}\\blend, alpha, denoise};
\node[disk, below=8mm of model] (cache) {\textbf{Frame Cache}};
\node[proc, right=28mm of post] (encode) {\textbf{Encoding}\\ffmpeg reassembly};
\draw[arrow] (ingest) -- (analysis);
\draw[arrow] (analysis) -- (model);
\draw[arrow] (model) -- (post);
\draw[arrow] (post) -- (encode);
\draw[arrow] (model) -- (cache);
\draw[arrow] (cache) -- (post);
% Decorative bracket and label under pipeline
\draw[decorate, decoration={brace, amplitude=6pt}, thick, WarlockGold] ($(analysis.south west)+(0,-6mm)$) -- ($(post.south east)+(0,-6mm)$) node[midway, below=9mm]{\small \textbf{GPU-Accelerated AI Pipeline}};
\end{tikzpicture}
}
\caption{High-level processing pipeline (ingest $\rightarrow$ inference $\rightarrow$ encode).}
\end{figure}
% =======================================================================================
% SECTION 10: ARCHITECTURE DIAGRAM (FIXED)
% =======================================================================================
\section{Software Architecture (Diagram)}
\noindent
Component-level architecture showing logical components and their relationship to hardware.
Updated component-level architecture illustrating the new modular design and the interaction between the GUI, the NEO Engine, and the Core Orchestrator.
\begin{figure}[H]
\centering
\resizebox{\textwidth}{!}{%
\begin{tikzpicture}[node distance=12mm, every node/.style={font=\small}]
\tikzset{
comp/.style={rectangle, rounded corners=3pt, draw=WarlockDark!70!black, fill=WarlockDark!6, minimum width=42mm, minimum height=9mm, align=center, drop shadow},
hw/.style={rectangle, rounded corners=3pt, draw=WarlockGold!70!black, fill=WarlockGold!10, minimum width=42mm, minimum height=9mm, align=center},
line/.style={-Latex, thick, color=WarlockGray!80!black}
module/.style={rectangle, rounded corners=3pt, draw=WarlockDark!70!black, fill=WarlockDark!6, minimum width=42mm, minimum height=10mm, align=center, drop shadow},
core/.style={rectangle, rounded corners=3pt, draw=WarlockGold!80!black, fill=WarlockGold!15, minimum width=42mm, minimum height=10mm, align=center, drop shadow},
hw/.style={rectangle, rounded corners=3pt, draw=WarlockGray!80!black, fill=WarlockLightGray, minimum width=42mm, minimum height=10mm, align=center},
line/.style={-Latex, thick, color=WarlockGray!90!black}
}
\node[comp] (gui) {GUI / Preferences};
\node[comp, right=28mm of gui] (orchestrator) {Orchestrator / Job Queue};
\node[comp, right=28mm of orchestrator] (ai) {AI Core / ONNX Wrapper};
\node[comp, right=28mm of ai] (io) {I/O \& Encoding (FFmpeg)};
\node[hw, below=12mm of ai] (gpu) {GPU (CUDA / DirectML)};
\node[hw, below=12mm of io] (disk) {Disk / SSD};
\draw[line] (gui) -- (orchestrator);
\draw[line] (orchestrator) -- (ai);
\draw[line] (ai) -- (io);
\draw[line, dashed] (ai) -- (gpu) node[midway, right]{\small Inference};
% Nodes
\node[module] (gui) {\textbf{GUI Frontend}\\(Main Window +\\Drag\&Drop Wrapper)};
\node[module, left=15mm of gui] (prefs) {\textbf{Warlock Prefs}\\(NEO Engine +\\Update Manager)};
\node[module, right=15mm of gui] (console) {\textbf{Console Manager}\\(Stream Redirection)};
\node[core, below=15mm of gui] (orch) {\textbf{Core Orchestrator}\\(Multiprocessing)};
\node[module, below=15mm of orch] (ai) {\textbf{AI Engine}\\(ONNX Runtime)};
\node[module, right=15mm of ai] (io) {\textbf{I/O \& Encoding}\\(FFmpeg / Fallback)};
\node[hw, below=12mm of ai] (gpu) {\textbf{Hardware}\\(CUDA / DirectML)};
\node[hw, below=12mm of io] (disk) {\textbf{Storage}\\(Logs/Config/Frames)};
% Connections
\draw[line] (prefs) -- (gui);
\draw[line] (console) -- (gui);
\draw[line] (gui) -- (orch);
\draw[line] (orch) -- (ai);
\draw[line] (orch) -- (io);
\draw[line] (ai) -- (gpu);
\draw[line] (io) -- (disk);
\draw[line, dashed] (orchestrator) -- (disk) node[midway, right]{\small Checkpoints / Frames};
\draw[line, dashed] (prefs) |- (disk);
\end{tikzpicture}
}
\caption{Component-level architecture (logical components and hardware).}
\caption{Warlock-Studio v5.0 Modular Component Architecture.}
\end{figure}
% =======================================================================================
% SECTION 9: TECHNICAL GLOSSARY
% SECTION 8: GLOSSARY
% =======================================================================================
\setsectioncolor{GlossaryColor}
\section{Glossary}
\begin{description}[leftmargin=*, style=nextline, itemsep=0.8em]
\item[ONNX Runtime] (Open Neural Network Exchange) A high-performance, cross-platform inference engine for AI models. It allows Warlock-Studio to run models in a hardware-agnostic manner.
\item[CUDA] (Compute Unified Device Architecture) A parallel computing platform and programming model API created by NVIDIA. It enables general-purpose acceleration on NVIDIA GPUs.
\item[DirectML] (Direct Machine Learning) A low-level Microsoft API that uses DirectX 12 to provide GPU-accelerated AI on a wide range of DX12-compatible hardware.
\item[VRAM] (Video RAM) High-speed random-access memory dedicated to a graphics card, used to store textures, framebuffers, and other data critical for rendering and computation on the GPU.
\item[Tiling] A technique of dividing a large image into smaller "tiles" to be processed individually. It is an essential mechanism for handling resolutions that exceed available VRAM.
\item[Codec] (Coder-Decoder) A software or hardware algorithm/device that compresses and decompresses digital video data. Examples of software codecs are x264 (H.264) and x265 (HEVC). Hardware codecs (NVENC, AMF, QSV) use dedicated encoders on the GPU to accelerate this process.
\item[NEO Engine] The new heuristic subsystem in v5.0 responsible for hardware scanning, diagnostics, and configuration recommendation.
\item[Modular Architecture] A software design technique that splits the code into separate, independent modules (`console`, `preferences`, `core`) to improve maintainability.
\item[ONNX Runtime] The cross-platform engine used to run the AI models. v5.0 enforces strict device ID typing.
\item[OOM Recovery] (Out Of Memory) An automatic mechanism that reduces tile size when VRAM is exhausted to prevent crashes.
\item[DirectML] (Direct Machine Learning) API used for GPU acceleration on AMD and Intel cards.
\end{description}
% =======================================================================================
% SECTION 11: SUPPORT & CONTRIBUTIONS
% SECTION 9: SUPPORT & CONTRIBUTIONS
% =======================================================================================
\setsectioncolor{SupportColor}
\section{Support and Community}
\begin{itemize}[leftmargin=*]
\item \textbf{\faBug\ Reporting Issues:} If you encounter a reproducible bug, please open an "Issue" on the GitHub repository. It is essential to attach the \inlinecode{error_log.txt} file (located in your \textbf{Documents} folder) for effective diagnosis.
\item \textbf{\faCodeBranch\ Code Contributions:} Contributions to the source code are welcome. It is recommended to follow the standard workflow: fork the repository, create a new branch for the feature or fix, and submit a "Pull Request" for review.
\item \textbf{\faEnvelope\ Direct Contact:} For general inquiries or technical support that does not constitute a software bug, you can contact the author at \href{mailto:negroayub97@gmail.com}{\texttt{negroayub97@gmail.com}}.
\item \textbf{\faBook\ Manual:} Click the \textbf{Book Icon} in the app header to open this PDF document.
\item \textbf{\faBug\ Reporting Issues:} Report bugs on GitHub. Please attach the \inlinecode{error_log.txt} file located in your \textbf{Documents} folder.
\item \textbf{\faSync\ Updates:} Use the internal \textbf{Update Manager} (Gear Icon $\to$ Check Updates) to download the latest version directly.
\item \textbf{\faEnvelope\ Contact:} For non-bug related inquiries: \href{mailto:negroayub97@gmail.com}{\texttt{negroayub97@gmail.com}}.
\end{itemize}
\vspace{1cm}
\centering
\textbf{Thank you for using Warlock-Studio.}
\textbf{Thank you for using Warlock-Studio v5.0.}
% =======================================================================================
% END OF DOCUMENT
+26 -135
View File
@@ -1,7 +1,7 @@
![Warlock-Studio banner](Assets/banner.png)
<div align="center">
[![Version](https://img.shields.io/badge/Version-4.3-FF4500?style=for-the-badge&logo=git&logoColor=white)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases/tag/4.3)
[![License](https://img.shields.io/badge/License-MIT-6A0DAD?style=for-the-badge&logo=open-source-initiative&logoColor=white)](LICENSE)
[![Last Commit](https://img.shields.io/github/last-commit/Ivan-Ayub97/Warlock-Studio?style=for-the-badge&color=2E8B57&logo=git&logoColor=white)](https://github.com/Ivan-Ayub97/Warlock-Studio/commits/main)
@@ -10,36 +10,27 @@
[![Python](https://img.shields.io/badge/Python-3.10+-3776AB?style=for-the-badge&logo=python&logoColor=FFD700)](https://www.python.org/)
[![Downloads](https://img.shields.io/github/downloads/Ivan-Ayub97/Warlock-Studio/total.svg?style=for-the-badge&color=FFD700&logo=download&logoColor=black)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases)
Inspired by [Djdefrag](https://github.com/Djdefrag) tools such as **QualityScaler** and **FluidFrames**, Warlock-Studio provides a unified, high-performance platform for **upscaling, restoration, denoising, and frame interpolation**.
Inspired by [Djdefrag](https://github.com/Djdefrag) tools such as **QualityScaler** and **FluidFrames**, **Warlock-Studio** provides a unified, high-performance platform for **upscaling, restoration, denoising, and frame interpolation**.
---
`Fixed missing audio in generated videos.`
`Corrected dark output issue in GFPGAN face restoration.`
`Improved overall stability and synchronization.`
See CHANGELOG.md for full details.
---
## 📥 <span style="color:#00ffcc;">Download Installer</span>
<div style="color:#ccc; font-size:14px; margin-top:-6px;">
You can download the installer from either option below:
</div>
<table style="width:100%; border-collapse:collapse;">
<tr>
<td align="center" style="vertical-align:top; padding:px;">
<a href="https://sourceforge.net/projects/warlock-studio/" target="_blank">
<img src="https://sourceforge.net/cdn/syndication/badge_img/3880091/oss-rising-star-black"
alt="Warlock-Studio on SourceForge"
width="230" style="display:block; margin:auto; margin-bottom:1px;" />
width="190" style="display:block; margin:auto; margin-bottom:1px;" />
</a>
</td>
<td align="center" style="vertical-align:top; padding:10px;">
<a href="https://github.com/Ivan-Ayub97/Warlock-Studio/releases/download/v4.3/Warlock-Studio-v4.3-Setup.zip" target="_blank">
<a href="https://github.com/Ivan-Ayub97/Warlock-Studio/releases/download/v5.0/Warlock-Studio-5.0-Full-Installer.exe" target="_blank">
<img src="rsc/GitHub_Logo_WS.png" alt="Download from GitHub"
width="300" style="display:block; margin:auto; margin-bottom:10px;" />
</a>
@@ -47,12 +38,11 @@ See CHANGELOG.md for full details.
</tr>
</table>
---
## 🖼️ Interface Previews
![Main interface](rsc/Capture.png)
![interface](rsc/Capture.png)
---
@@ -80,84 +70,11 @@ See CHANGELOG.md for full details.
## 🖥️ System Requirements
- **OS:** Windows 11 or higher (64-bit)
- **RAM:** 8GB+ recommended
- **GPU:** NVIDIA (for CUDA), AMD, or Intel GPU with up-to-date drivers recommended
- **Storage:** Sufficient free space for input and processed media
---
## 📊 Model Comparison
| Model File | Use Case | Speed | Quality | Notes |
| :----------------- | :--------------------------- | :-------- | :-------- | :---------------------------------- |
| **GFPGANv1.4** | Face restoration | High | High | Optimal for portraits |
| **BSRGANx2** | 2× upscale + denoising | Medium | Very High | Suitable for lightly degraded media |
| **BSRGANx4** | 4× upscale + denoising | Low | Very High | For heavily degraded content |
| **RIFE** | Frame interpolation | High | High | Smooth motion, slow-motion support |
| **RIFE-Lite** | Lightweight interpolation | Very High | Medium | Faster, lower resource usage |
| **RealESRGANx4** | General 4× upscaling | Medium | High | Balanced performance |
| **RealESRNetx4** | Subtle restoration | Medium | High | Preserves natural image texture |
| **RealSRx4_Anime** | Anime / line-art enhancement | Medium | High | Sharp edges for 2D art |
| **IRCNN_L** | Light denoising | High | Medium | Mild artifact removal |
| **IRCNN_M** | Medium denoising | High | Medium | Stronger artifact cleanup |
---
## 📂 Project Structure
</div>
```
Warlock-Studio/
├── AI-onnx/ # Pre-trained ONNX models for AI processing
│ ├── BSRGANx2_fp16.onnx
│ ├── BSRGANx4_fp16.onnx
│ ├── GFPGANv1.4.fp16.onnx
│ ├── IRCNN_Lx1_fp16.onnx
│ ├── IRCNN_Mx1_fp16.onnx
│ ├── RealESR_Animex4_fp16.onnx
│ ├── RealESR_Gx4_fp16.onnx
│ ├── RealESRGANx4_fp16.onnx
│ ├── RealESRNetx4_fp16.onnx
│ ├── RealSRx4_Anime_fp16.onnx
│ ├── RIFE_fp32.onnx
│ └── RIFE_Lite_fp32.onnx
├── Assets/ # Application assets and third-party binaries
│ ├── banner.png
│ ├── clear_icon.png
│ ├── exiftool.exe
│ ├── ffmpeg.exe
│ ├── ffmprobe.exe
│ ├── ffmplay.exe
│ ├── info_icon.png
│ ├── logo.ico
│ ├── logo.png
│ ├── stop_icon.png
│ ├── upscale_icon.png
│ ├── wizard-image.bmp
│ └── wizard-small.bmp
├── rsc/ # UI previews and branding resources
│ ├── Capture.png
│ ├── image_comparison.png
│ ├── CaptureCONSOLE.png
│ └── GitHub_Logo_WS.png
├── Warlock-Studio.py # Main application script
├── Warlock-Studio.spec # PyInstaller specification file
├── Setup.iss # Inno Setup installer script
├── README.md # Project overview
├── CHANGELOG.md # Version history and updates
├── LICENSE # MIT License information
├── NOTICE.md # Legal notices and attributions
├── CODE_OF_CONDUCT.md # Contributor guidelines
├── CONTRIBUTING.md # Contribution guide
└── SECURITY.md # Security reporting policies
```
<div align="center">
- **OS:** Windows 11 or Windows 10 (64-bit)
- **RAM:** 8GB (minimum) / 16GB+ (recommended for 4K Video)
- **GPU:** DirectX 12 compatible graphics card. NVIDIA (for CUDA), AMD, or Intel GPU with up-to-date drivers.
- **VRAM:** 4GB+ recommended. The **NEO Engine** automatically tunes limits on startup.
- **Storage:** Sufficient free space for input and processed media. SSD highly recommended for video I/O.
---
@@ -176,50 +93,24 @@ We welcome contributions from the community:
## 📜 License
© 2025 Iván Eduardo Chavez Ayub
Licensed under **MIT**. Additional terms and attributions are provided in `NOTICE.md`.
Licensed under **MIT**. Additional terms and attributions are provided in **NOTICE.md**.
### 📊 Integrated Technologies & Licenses
| Technology | License | Author / Maintainer | Source |
| ------------- | --------------------- | --------------------------------------- | ---------------------------------------------------------- |
| QualityScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler) |
| FluidFrames | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames) |
| Real-ESRGAN | BSD 3-Clause / Apache | Xintao Wang | [GitHub](https://github.com/xinntao/Real-ESRGAN) |
| GFPGAN | Apache 2.0 | TencentARC / Xintao Wang | [GitHub](https://github.com/TencentARC/GFPGAN) |
| RIFE | Apache 2.0 | hzwer | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) |
| BSRGAN | Apache 2.0 | Kai Zhang | [GitHub](https://github.com/cszn/BSRGAN) |
| IRCNN | BSD / Mixed | Kai Zhang | [GitHub](https://github.com/cszn/IRCNN) |
| ONNX Runtime | MIT | Microsoft | [GitHub](https://github.com/microsoft/onnxruntime) |
| FFmpeg | LGPL / GPL | FFmpeg Team | [Official Site](https://ffmpeg.org) |
| ExifTool | Artistic License | Phil Harvey | [Official Site](https://exiftool.org/) |
| Python | PSF License | Python Software Foundation | [Official Site](https://www.python.org) |
| PyInstaller | GPLv2+ | PyInstaller Team | [GitHub](https://github.com/pyinstaller/pyinstaller) |
| Inno Setup | Custom | Jordan Russell | [Official Site](http://www.jrsoftware.org/isinfo.php) |
| Technology    | License                | Author / Maintainer                      | Source                                                      |
| -------------- | ---------------------- | ---------------------------------------- | ----------------------------------------------------------- |
| QualityScaler | MIT                    | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler)        |
| FluidFrames    | MIT                    | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames)          |
| Real-ESRGAN    | BSD 3-Clause / Apache | Xintao Wang                              | [GitHub](https://github.com/xinntao/Real-ESRGAN)            |
| GFPGAN        | Apache 2.0            | TencentARC / Xintao Wang                | [GitHub](https://github.com/TencentARC/GFPGAN)              |
| RIFE          | Apache 2.0            | hzwer                                    | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) |
| BSRGAN        | Apache 2.0            | Kai Zhang                                | [GitHub](https://github.com/cszn/BSRGAN)                    |
| IRCNN          | BSD / Mixed            | Kai Zhang                                | [GitHub](https://github.com/cszn/IRCNN)                    |
| ONNX Runtime  | MIT                    | Microsoft                                | [GitHub](https://github.com/microsoft/onnxruntime)          |
| FFmpeg        | LGPL / GPL            | FFmpeg Team                              | [Official Site](https://ffmpeg.org)                        |
| ExifTool      | Artistic License      | Phil Harvey                              | [Official Site](https://exiftool.org/)                      |
| Python        | PSF License            | Python Software Foundation              | [Official Site](https://www.python.org)                    |
| PyInstaller    | GPLv2+                | PyInstaller Team                        | [GitHub](https://github.com/pyinstaller/pyinstaller)        |
| Inno Setup    | Custom                | Jordan Russell                          | [Official Site](http://www.jrsoftware.org/isinfo.php)      |
</div>
+4 -9
View File
@@ -1,10 +1,6 @@
; ===================================================================
; Warlock-Studio 4.3 - Inno Setup Script (Full Offline Installer)
; ===================================================================
#define AppName "Warlock-Studio"
#define AppVersion "4.3"
#define AppPublisher "Iván Eduardo Chavez Ayub"
#define AppVersion "5.0"
#define AppPublisher "Ivan-Ayub97|Ivanayub1997"
#define AppURL "https://github.com/Ivan-Ayub97/Warlock-Studio"
#define AppExeName "Warlock-Studio.exe"
@@ -15,11 +11,10 @@ AppVersion={#AppVersion}
AppPublisher={#AppPublisher}
AppSupportURL={#AppURL}
AppUpdatesURL={#AppURL}
DefaultDirName={autopf}\{#AppName}
DefaultDirName={userdocs}\{#AppName}
DefaultGroupName={#AppName}
AllowNoIcons=yes
PrivilegesRequired=admin
ArchitecturesInstallIn64BitMode=x64
PrivilegesRequired=none
; --- Configuración del Instalador ---
OutputDir=Output
+1246 -753
View File
File diff suppressed because it is too large Load Diff
+73
View File
@@ -0,0 +1,73 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
# 1. Aquí agregamos los dos archivos nuevos a la lista de scripts
['Warlock-Studio.py', 'drag_drop.py', 'console.py', 'warlock_preferences.py'],
pathex=[],
binaries=[],
datas=[
('AI-onnx', 'AI-onnx'),
('Assets', 'Assets')
],
hiddenimports=[
'onnxruntime.capi._pybind_state',
'onnxruntime.providers',
'moviepy.editor'
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
# Frameworks de Machine Learning pesados
'torch', 'torchaudio', 'torchvision', 'transformers', 'accelerate', 'diffusers',
'lightning', 'pytorch-lightning',
# Librerías de Ciencia de Datos y Gráficos
'matplotlib', 'pandas', 'scipy', 'scikit-learn', 'scikit-image',
# Otros Toolkits de GUI
'PyQt5', 'PyQt5-Qt5', 'PyQt5_sip', 'dearpygui', 'QtAwesome', 'QtPy',
# Herramientas de desarrollo y testing
'pytest', 'unittest', 'poetry', 'virtualenv',
# Compiladores y librerías de bajo nivel que no se usan
'numba', 'llvmlite',
# Otros paquetes grandes no relacionados
'pygame', 'PyMuPDF', 'aiohttp', 'httpx', 'GitPython', 'musicbrainzngs', 'mido', 'rtmidi', 'simpleaudio', 'vulkan', 'vgamepad'
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='Warlock-Studio',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
icon='logo.ico',
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='Warlock-Studio',
)
+310
View File
@@ -0,0 +1,310 @@
import sys
import threading
import tkinter as tk
from datetime import datetime
from tkinter import filedialog
import customtkinter as ctk
class ConsoleColors:
"""Definición de paleta de colores para los logs."""
TEXT_DEFAULT = "#E0E0E0"
TIMESTAMP = "#808080"
DEBUG = "#A0A0A0"
INFO = "#61AFEF" # Azul claro
SUCCESS = "#98C379" # Verde pastel
WARNING = "#E5C07B" # Amarillo/Naranja
ERROR = "#E06C75" # Rojo suave
CRITICAL = "#FF0000" # Rojo intenso
HIGHLIGHT = "#D19A66" # Color para resaltar búsquedas
class IntegratedConsole(ctk.CTkFrame):
"""
Un widget de consola completo con barra de herramientas,
búsqueda y visualización de logs coloreados.
"""
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
# Configuración del Grid
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(1, weight=1) # El textbox se expande
# --- 1. BARRA DE HERRAMIENTAS (Toolbar) ---
self.toolbar = ctk.CTkFrame(self, height=30, fg_color="transparent")
self.toolbar.grid(row=0, column=0, sticky="ew", padx=2, pady=(2, 5))
# Botón Limpiar
self.btn_clear = ctk.CTkButton(
self.toolbar, text="🗑 Clear", width=60, height=24,
font=("Segoe UI", 11), fg_color="#3E3E3E", hover_color="#505050",
command=self.clear_console
)
self.btn_clear.pack(side="left", padx=2)
# Botón Copiar
self.btn_copy = ctk.CTkButton(
self.toolbar, text="📋 Copy", width=60, height=24,
font=("Segoe UI", 11), fg_color="#3E3E3E", hover_color="#505050",
command=self.copy_all
)
self.btn_copy.pack(side="left", padx=2)
# Botón Guardar
self.btn_save = ctk.CTkButton(
self.toolbar, text="💾 Save", width=60, height=24,
font=("Segoe UI", 11), fg_color="#3E3E3E", hover_color="#505050",
command=self.save_to_file
)
self.btn_save.pack(side="left", padx=2)
# Separador visual (Spacer)
ctk.CTkLabel(self.toolbar, text="|", text_color="gray").pack(
side="left", padx=5)
# Checkbox Auto-Scroll
self.auto_scroll_var = ctk.BooleanVar(value=True)
self.chk_autoscroll = ctk.CTkCheckBox(
self.toolbar, text="Auto-scroll", variable=self.auto_scroll_var,
font=("Segoe UI", 11), width=80, height=20, checkbox_width=18, checkbox_height=18
)
self.chk_autoscroll.pack(side="left", padx=5)
# Barra de Búsqueda
self.entry_search = ctk.CTkEntry(
self.toolbar, placeholder_text="🔍 Search...", width=120, height=24,
font=("Segoe UI", 11)
)
self.entry_search.pack(side="right", padx=2)
self.entry_search.bind("<KeyRelease>", self.on_search)
# --- 2. ÁREA DE TEXTO (Logs) ---
self.textbox = ctk.CTkTextbox(
self,
font=("Consolas", 13), # Fuente monoespaciada para mejor lectura
fg_color="#1E1E1E", # Fondo oscuro tipo editor
text_color=ConsoleColors.TEXT_DEFAULT,
wrap="word",
state="disabled"
)
self.textbox.grid(row=1, column=0, sticky="nsew", padx=2, pady=2)
# Configuración de Tags (Colores)
self.textbox.tag_config(
"TIMESTAMP", foreground=ConsoleColors.TIMESTAMP)
self.textbox.tag_config("DEBUG", foreground=ConsoleColors.DEBUG)
self.textbox.tag_config("INFO", foreground=ConsoleColors.INFO)
self.textbox.tag_config("SUCCESS", foreground=ConsoleColors.SUCCESS)
self.textbox.tag_config("WARNING", foreground=ConsoleColors.WARNING)
self.textbox.tag_config("ERROR", foreground=ConsoleColors.ERROR)
self.textbox.tag_config("CRITICAL", foreground=ConsoleColors.CRITICAL)
self.textbox.tag_config(
"SEARCH_HIGHLIGHT", background="#444400", foreground="#FFFFFF")
# Menú contextual (Click derecho)
self.context_menu = tk.Menu(self, tearoff=0, bg="#2b2b2b", fg="white")
self.context_menu.add_command(label="Copy All", command=self.copy_all)
self.context_menu.add_command(
label="Clear Console", command=self.clear_console)
self.textbox.bind("<Button-3>", self.show_context_menu)
def write_log(self, text, level="INFO"):
"""Método principal para escribir en la consola."""
try:
self.textbox.configure(state="normal")
# Timestamp
timestamp = datetime.now().strftime("[%H:%M:%S]")
self.textbox.insert("end", f"{timestamp} ", "TIMESTAMP")
# Etiqueta de Nivel (opcional, visualmente ayuda)
self.textbox.insert("end", f"[{level.upper()}] ", level.upper())
# Mensaje
# Aseguramos que termine en nueva línea
if not text.endswith("\n"):
text += "\n"
self.textbox.insert("end", text, level.upper())
# Auto-scroll
if self.auto_scroll_var.get():
self.textbox.see("end")
self.textbox.configure(state="disabled")
except Exception as e:
print(f"Error writing to console widget: {e}")
# --- Funcionalidades de la Barra de Herramientas ---
def clear_console(self):
self.textbox.configure(state="normal")
self.textbox.delete("0.0", "end")
self.textbox.configure(state="disabled")
def copy_all(self):
try:
all_text = self.textbox.get("0.0", "end")
self.clipboard_clear()
self.clipboard_append(all_text)
self.update() # Necesario para finalizar la operación de portapapeles
except Exception:
pass
def save_to_file(self):
try:
filename = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("Text Files", "*.txt"),
("Log Files", "*.log"), ("All Files", "*.*")],
title="Save Log File"
)
if filename:
with open(filename, "w", encoding="utf-8") as f:
f.write(self.textbox.get("0.0", "end"))
except Exception as e:
self.write_log(f"Error saving file: {e}", "ERROR")
def on_search(self, event=None):
"""Resalta texto en tiempo real."""
search_str = self.entry_search.get()
# Limpiar tags anteriores de búsqueda
self.textbox.tag_remove("SEARCH_HIGHLIGHT", "1.0", "end")
if not search_str:
return
# Buscar y resaltar
start_pos = "1.0"
while True:
start_pos = self.textbox.search(
search_str, start_pos, stopindex="end", nocase=True)
if not start_pos:
break
end_pos = f"{start_pos}+{len(search_str)}c"
self.textbox.tag_add("SEARCH_HIGHLIGHT", start_pos, end_pos)
start_pos = end_pos
def show_context_menu(self, event):
try:
self.context_menu.tk_popup(event.x_root, event.y_root)
finally:
self.context_menu.grab_release()
class StreamRedirector:
"""Redirige stdout/stderr hacia el ConsoleManager."""
def __init__(self, console_manager, stream_type):
self.console_manager = console_manager
self.stream_type = stream_type
self.original_stream = getattr(sys, stream_type)
def write(self, message):
if message.strip(): # Ignorar líneas vacías
self.console_manager.enqueue_message(message, self.stream_type)
# Mantener salida en terminal real por seguridad
try:
self.original_stream.write(message)
self.original_stream.flush()
except Exception:
pass
def flush(self):
try:
self.original_stream.flush()
except Exception:
pass
class ConsoleManager:
"""
Singleton que gestiona la lógica de logs y la conexión con la GUI.
Thread-safe.
"""
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(ConsoleManager, cls).__new__(cls)
cls._instance.buffer = []
cls._instance.widget_frame = None # Referencia al Frame contenedor
cls._instance.lock = threading.Lock()
cls._instance.is_setup = False
return cls._instance
def setup_redirection(self):
"""Configura la redirección de sys.stdout y sys.stderr."""
if not self.is_setup:
sys.stdout = StreamRedirector(self, "stdout")
sys.stderr = StreamRedirector(self, "stderr")
self.is_setup = True
print("[SYSTEM] Output redirected to Warlock Integrated Console.")
def set_widget(self, widget_frame: IntegratedConsole):
"""Vincula el widget gráfico (IntegratedConsole) y vuelca el buffer."""
with self.lock:
self.widget_frame = widget_frame
# Volcar buffer acumulado
for msg, stream_type in self.buffer:
self._process_and_dispatch(msg, stream_type)
self.buffer = []
def enqueue_message(self, message, stream_type):
"""Punto de entrada desde stdout/stderr."""
with self.lock:
if self.widget_frame:
self._process_and_dispatch(message, stream_type)
else:
self.buffer.append((message, stream_type))
def _process_and_dispatch(self, message, stream_type="info"):
"""Determina el nivel del log y lo envía a la GUI."""
try:
tag = "INFO"
msg_lower = message.lower()
# Lógica de detección de nivel automática
if stream_type == "stderr":
tag = "ERROR"
elif "error" in msg_lower or "exception" in msg_lower or "failed" in msg_lower:
tag = "ERROR"
elif "warning" in msg_lower:
tag = "WARNING"
elif "success" in msg_lower or "completed" in msg_lower:
tag = "SUCCESS"
elif "debug" in msg_lower:
tag = "DEBUG"
elif "critical" in msg_lower:
tag = "CRITICAL"
# Enviar al hilo principal
self.widget_frame.after(
0, lambda m=message, t=tag: self.widget_frame.write_log(m, t))
except Exception:
pass
def write_log(self, message, tag="INFO"):
"""
Método público para logs manuales.
Uso: console.write_log("Proceso terminado", "SUCCESS")
"""
with self.lock:
if self.widget_frame:
try:
self.widget_frame.after(
0, lambda m=message, t=tag: self.widget_frame.write_log(m, t))
except Exception:
print(f"[{tag}] {message}")
else:
print(f"[{tag}] {message}")
# Instancia global
console = ConsoleManager()
+37
View File
@@ -0,0 +1,37 @@
# drag_drop.py
from customtkinter import CTk
from tkinterdnd2 import DND_ALL, TkinterDnD
# 1. Clase envoltorio que combina CustomTkinter con TkinterDnD
class DnDCTk(CTk, TkinterDnD.DnDWrapper):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.TkdndVersion = TkinterDnD._require(self)
# 2. Función para registrar widgets y conectar tu lógica
def enable_drag_and_drop(window, target_widgets, callback_function):
"""
Activa Drag & Drop en los widgets especificados.
:param window: La ventana principal (debe ser instancia de DnDCTk)
:param target_widgets: Lista de widgets (botones, labels) donde se pueden soltar archivos.
:param callback_function: La función de tu app principal que recibe la lista de archivos.
"""
def _internal_drop_event(event):
# TkinterDnD a veces devuelve las rutas con llaves {} si tienen espacios
# window.tk.splitlist se encarga de limpiarlas correctamente
if event.data:
files = window.tk.splitlist(event.data)
# Llamamos a tu función principal pasando la lista limpia
callback_function(files)
for widget in target_widgets:
# Registramos el widget para aceptar cualquier cosa (archivos)
widget.drop_target_register(DND_ALL)
# Conectamos el evento 'Drop' con nuestra función interna
widget.dnd_bind('<<Drop>>', _internal_drop_event)
-13
View File
@@ -1,13 +0,0 @@
onnxruntime>=1.18.0
numpy>=1.24.0
customtkinter>=5.2.0
Pillow>=10.0.0
opencv-python>=4.8.0
moviepy>=1.0.3
natsort>=8.4.0
tk>=0.1.0
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 49 KiB

+811
View File
@@ -0,0 +1,811 @@
import ctypes
import glob
import json
import os
import platform
import shutil
import socket
import subprocess
import sys
import threading
import tkinter as tk
import webbrowser
import zipfile
from datetime import datetime
from tkinter import filedialog, messagebox
from typing import Any, Dict, List, Optional
import customtkinter as ctk
# --- IMPORTACIONES DEL MOTOR NEO (Hardware Info) ---
import psutil
import requests
from packaging import version as pkg_version
try:
import wmi
except ImportError:
wmi = None
try:
import GPUtil
except ImportError:
GPUtil = None
# -----------------------------------------------------------------------------
# CONSTANTES DE ESTILO & TEMAS
# -----------------------------------------------------------------------------
THEME = {
"bg": "#1B1818",
"widget_bg": "#2A2727",
"card_bg": "#212121",
"text": "#FFFFFF",
"text_sec": "#CAC9C9",
"accent": "#FDEF2F", # Amarillo Dorado (Warlock)
"accent_hover": "#D4C428",
"title": "#FF3232", # Rojo Warlock
"hover": "#D41C1C", # Rojo oscuro
"border": "#E2340D",
"success": "#00E676",
"error": "#B00020",
"warning": "#FFA000",
"info_bg": "#1E3A8A",
"scroll_bg": "#181818"
}
CONFIG_FILE = "warlock_config.json"
# -----------------------------------------------------------------------------
# UTILIDADES DE UI
# -----------------------------------------------------------------------------
def get_font(size: int, weight: str = "normal", family: str = "Segoe UI") -> tuple:
"""Genera una fuente base."""
return (family, size, weight)
# -----------------------------------------------------------------------------
# GESTOR DE CONFIGURACIÓN
# -----------------------------------------------------------------------------
class ConfigManager:
DEFAULT_CONFIG = {
"check_updates_on_startup": True,
"keep_window_on_top": False,
"ui_scaling": 1.0,
"font_scale": 1.0,
"window_opacity": 1.0,
"app_theme": "Dark",
"process_priority": "Normal",
"auto_close_on_finish": False,
"auto_clean_temp": False,
"notifications_enabled": True,
"last_gpu_index": "Auto"
}
@staticmethod
def get_config_path():
if getattr(sys, 'frozen', False):
base_dir = os.path.dirname(sys.executable)
else:
base_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(base_dir, CONFIG_FILE)
@staticmethod
def load_config() -> Dict[str, Any]:
path = ConfigManager.get_config_path()
config = ConfigManager.DEFAULT_CONFIG.copy()
if os.path.exists(path):
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
for k, v in data.items():
if k in config:
if isinstance(v, type(config[k])) or (isinstance(config[k], float) and isinstance(v, int)):
config[k] = v
except Exception as e:
print(f"[Config] Error loading/validating config: {e}")
return config
@staticmethod
def save_config(config_data: Dict[str, Any]):
try:
path = ConfigManager.get_config_path()
with open(path, "w", encoding="utf-8") as f:
json.dump(config_data, f, indent=4)
except Exception as e:
print(f"[Config] Error saving config: {e}")
@staticmethod
def reset_config():
ConfigManager.save_config(ConfigManager.DEFAULT_CONFIG)
return ConfigManager.DEFAULT_CONFIG.copy()
# -----------------------------------------------------------------------------
# ESCÁNER DE HARDWARE (INTEGRACIÓN MOTOR NEO)
# -----------------------------------------------------------------------------
class HardwareScanner:
@staticmethod
def get_specs_detailed() -> Dict[str, Any]:
"""
Utiliza el motor de detección de NEO (WMI/PSUTIL/GPUTIL)
adaptado para devolver el diccionario que espera Warlock.
"""
specs = {
"os": f"{platform.system()} {platform.release()} ({platform.architecture()[0]})",
"cpu_name": platform.processor(),
"cpu_cores": os.cpu_count() or 4,
"ram_total": 0.0,
"ram_used": 0.0,
"gpu_name": "Integrated / Unknown",
"gpu_vram": 0,
"disk_free": 0.0,
}
try:
# 1. CPU y SO (Motor NEO: WMI Processor)
if wmi:
try:
c = wmi.WMI()
# SO Info detallada
specs["os"] = f"{platform.system()} {platform.release()} {platform.machine()}"
# CPU Info detallada
proc_obj = c.Win32_Processor()[0]
specs["cpu_name"] = proc_obj.Name.strip()
specs["cpu_cores"] = proc_obj.NumberOfLogicalProcessors
except Exception:
pass # Fallback a los valores por defecto de platform
# 2. RAM (Motor NEO: Psutil + WMI logic adaptation)
mem = psutil.virtual_memory()
specs["ram_total"] = round(mem.total / (1024**3), 2)
specs["ram_used"] = round(mem.used / (1024**3), 2)
# 3. Almacenamiento (Motor NEO logic)
total_free_space = 0
for p in psutil.disk_partitions():
try:
usage = psutil.disk_usage(p.mountpoint)
total_free_space += usage.free
except PermissionError:
continue
specs["disk_free"] = round(total_free_space / (1024**3), 2)
# 4. GPU (Motor NEO: GPUtil Priority -> WMI Fallback)
gpu_found = False
# Intento A: GPUtil (NVIDIA)
if GPUtil:
try:
gpus = GPUtil.getGPUs()
if gpus:
best_gpu = gpus[0]
specs["gpu_name"] = f"[NVIDIA] {best_gpu.name}"
specs["gpu_vram"] = round(
best_gpu.memoryTotal / 1024, 2) # GPUtil returns MB
gpu_found = True
except Exception:
pass
# Intento B: WMI (AMD / Intel / Fallback)
if not gpu_found and wmi:
try:
c = wmi.WMI()
for gpu in c.Win32_VideoController():
# Lógica simple para elegir la GPU dedicada si hay varias
name = gpu.Name
vram_bytes = 0
try:
# AdapterRAM suele devolver bytes, pero a veces es negativo en int32 overflow
vram_bytes = int(gpu.AdapterRAM)
if vram_bytes < 0:
vram_bytes += 2**32
except:
vram_bytes = 0
vram_gb = round(vram_bytes / (1024**3), 2)
# Preferir GPU con más VRAM o que no sea "Intel" si ya tenemos una integrada
current_best = specs["gpu_vram"]
# Si encontramos una con más VRAM o es la primera dedicada que vemos
if vram_gb > current_best or (vram_gb > 0 and "Intel" not in name and specs["gpu_name"] == "Integrated / Unknown"):
specs["gpu_name"] = name
specs["gpu_vram"] = vram_gb
except Exception:
pass
except Exception as e:
print(f"[HardwareScanner] Error using NEO Engine: {e}")
return specs
@staticmethod
def get_smart_recommendations(specs: Dict) -> Dict:
rec = {}
vram = specs.get("gpu_vram", 0)
ram = specs.get("ram_total", 0)
# Cálculo de seguridad Warlock
safe_vram = max(0.5, vram - 1.5)
rec_tiles = int(safe_vram * 3.5)
if rec_tiles < 2:
rec_tiles = 2
rec["Recommended Tiles"] = f"{rec_tiles}"
rec["Safe VRAM Limit"] = f"{safe_vram:.1f} GB"
if vram >= 8 and ram >= 16:
rec["AI Model Class"] = "High End (RealESRGANx4 / BSRGANx4)"
rec["Multithreading"] = "2 - 4 Threads"
elif vram >= 4:
rec["AI Model Class"] = "Mid Range (RealESR_Animex4)"
rec["Multithreading"] = "2 Threads"
else:
rec["AI Model Class"] = "Low End (RealESR_Gx4 / RIFE Lite)"
rec["Multithreading"] = "OFF (1 Thread)"
return rec
# -----------------------------------------------------------------------------
# UPDATE MANAGER
# -----------------------------------------------------------------------------
class UpdateManager:
def __init__(self, owner, repo, version):
self.api_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
self.current_ver = version
def check_update(self):
try:
r = requests.get(self.api_url, timeout=10)
if r.status_code == 200:
data = r.json()
tag = data.get("tag_name", "v0.0").lstrip("v")
if pkg_version.parse(tag) > pkg_version.parse(self.current_ver):
return True, tag, data.get("assets", []), data.get("body", "No changelog provided.")
return False, self.current_ver, None, None
except Exception as e:
return None, str(e), None, None
def download(self, url, path, progress_callback):
try:
with requests.get(url, stream=True, timeout=30) as r:
r.raise_for_status()
total = int(r.headers.get('content-length', 0))
downloaded = 0
with open(path, 'wb') as f:
for chunk in r.iter_content(8192):
f.write(chunk)
downloaded += len(chunk)
if progress_callback and total > 0:
progress_callback(downloaded / total)
return path
except Exception as e:
raise e
# -----------------------------------------------------------------------------
# COMPONENTES UI PERSONALIZADOS (Blender Style)
# -----------------------------------------------------------------------------
class SettingCard(ctk.CTkFrame):
def __init__(self, master, title, **kwargs):
super().__init__(master, fg_color="transparent", **kwargs)
self.pack(fill="x", pady=(5, 0), padx=5)
h = ctk.CTkFrame(self, fg_color="transparent")
h.pack(fill="x", pady=(5, 5))
ctk.CTkLabel(h, text="", text_color=THEME["border"], font=(
"Arial", 12, "bold")).pack(side="left", padx=(0, 5))
ctk.CTkLabel(h, text=title.upper(), text_color=THEME["text_sec"], font=get_font(
11, "bold")).pack(side="left")
ctk.CTkFrame(self, height=1, fg_color=THEME["widget_bg"]).pack(
fill="x", padx=0, pady=(0, 5))
class CollapsibleMenu(ctk.CTkFrame):
def __init__(self, master, title, **kwargs):
super().__init__(master,
fg_color=THEME["card_bg"], border_color=THEME["border"], border_width=1, **kwargs)
self.pack(fill="x", pady=8, padx=15)
self.grid_columnconfigure(0, weight=1)
self.header_frame = ctk.CTkFrame(
self, fg_color=THEME["widget_bg"], height=40, corner_radius=0)
self.header_frame.grid(row=0, column=0, sticky="ew")
self.header_frame.grid_columnconfigure(0, weight=1)
ctk.CTkLabel(self.header_frame, text=title.upper(), font=get_font(
13, "bold"), text_color=THEME["accent"], padx=15, anchor="w").grid(row=0, column=0, sticky="ew", pady=5)
self.is_expanded = True
self.toggle_button = ctk.CTkButton(self.header_frame, text="", width=30, height=30,
fg_color=THEME["widget_bg"], hover_color=THEME["hover"],
text_color=THEME["text"], command=self.toggle)
self.toggle_button.grid(row=0, column=1, padx=10, pady=5)
self.content_frame = ctk.CTkFrame(
self, fg_color=THEME["card_bg"], corner_radius=0)
self.content_frame.grid(
row=1, column=0, sticky="ew", padx=15, pady=(0, 15))
self.content_frame.grid_columnconfigure(0, weight=1)
def toggle(self):
if self.is_expanded:
self.content_frame.grid_remove()
self.toggle_button.configure(text="")
else:
self.content_frame.grid(
row=1, column=0, sticky="ew", padx=15, pady=(0, 15))
self.toggle_button.configure(text="")
self.is_expanded = not self.is_expanded
class DownloadWindow(ctk.CTkToplevel):
def __init__(self, master, filename):
super().__init__(master)
self.title("Update Downloader")
self.geometry("400x150")
self.attributes("-topmost", True)
self.configure(fg_color=THEME["bg"])
try:
x = master.winfo_x() + (master.winfo_width()//2) - 200
y = master.winfo_y() + (master.winfo_height()//2) - 75
self.geometry(f"+{x}+{y}")
except:
pass
ctk.CTkLabel(self, text=f"Downloading {filename}...", text_color=THEME["accent"], font=get_font(
12)).pack(pady=(30, 10))
self.prog = ctk.CTkProgressBar(
self, width=300, progress_color=THEME["success"])
self.prog.pack(pady=10)
self.prog.set(0)
self.lbl = ctk.CTkLabel(self, text="0%", text_color=THEME["text_sec"])
self.lbl.pack()
def update_progress(self, val):
self.prog.set(val)
self.lbl.configure(text=f"{int(val*100)}%")
self.update_idletasks()
# -----------------------------------------------------------------------------
# VENTANA PRINCIPAL DE PREFERENCIAS
# -----------------------------------------------------------------------------
class PreferencesWindow(ctk.CTkToplevel):
def __init__(self, master, version, owner, repo):
super().__init__(master)
self.title("Warlock-Studio - Preferences")
self.geometry("650x750")
self.configure(fg_color=THEME["bg"])
self.attributes("-topmost", True)
try:
if getattr(sys, 'frozen', False):
base_dir = os.path.dirname(sys.executable)
else:
base_dir = os.path.dirname(os.path.abspath(__file__))
icon_path = os.path.join(base_dir, "Assets", "logo.ico")
self.iconbitmap(icon_path)
except:
pass
self.curr_ver = version
self.upd_mgr = UpdateManager(owner, repo, version)
self.config = ConfigManager.load_config()
self.create_ui()
self.after(100, lambda: self.focus_force())
def create_ui(self):
# HEADER
head = ctk.CTkFrame(self, fg_color="transparent", height=80)
head.pack(fill="x", padx=25, pady=15)
t_frame = ctk.CTkFrame(head, fg_color="transparent")
t_frame.pack(side="left")
ctk.CTkLabel(t_frame, text="WARLOCK", font=("Impact", 36),
text_color=THEME["title"]).pack(side="left")
ctk.CTkLabel(t_frame, text="- STUDIO", font=("Impact", 36),
text_color=THEME["text"]).pack(side="left")
ver_badge = ctk.CTkLabel(head, text=f"v{self.curr_ver}", fg_color=THEME["widget_bg"],
text_color=THEME["accent"], corner_radius=6, padx=12, font=get_font(12, "bold"))
ver_badge.pack(side="right", padx=10)
self.status_lbl = ctk.CTkLabel(
head, text="", font=get_font(11, "bold"))
self.status_lbl.pack(side="right", padx=10)
# SCROLLABLE CONTENT
self.scroll_frame = ctk.CTkScrollableFrame(self, fg_color=THEME["bg"], scrollbar_button_color=THEME["border"],
label_text="SETTINGS MENU", label_text_color=THEME["text_sec"],
label_font=get_font(10, "bold"))
self.scroll_frame.pack(fill="both", expand=True, padx=20, pady=(0, 20))
self.scroll_frame.grid_columnconfigure(0, weight=1)
self._build_general_menu()
self._build_system_menu()
self._build_updates_menu()
self._build_logs_menu()
self._build_about_menu()
self.after(500, self._run_scan)
# --- MENUS ---
def _build_general_menu(self):
menu = CollapsibleMenu(self.scroll_frame, "General Settings")
frame = menu.content_frame
c1 = SettingCard(frame, "USER INTERFACE")
self._add_dropdown(frame, "Theme Mode", "app_theme", ["Dark", "Light", "System"],
lambda v: self._update("app_theme", v, lambda: ctk.set_appearance_mode(v)))
self._add_slider(frame, "Window Opacity", "window_opacity", 0.5, 1.0, 50,
lambda v: self._update("window_opacity", v, lambda: self.master.attributes("-alpha", v)))
self._add_slider(frame, "UI Scaling", "ui_scaling", 0.8, 1.5, 7,
lambda v: self._update("ui_scaling", v, lambda: ctk.set_widget_scaling(v)))
c2 = SettingCard(frame, "BEHAVIOR")
self._add_switch(frame, "Keep Window on Top", "keep_window_on_top",
lambda: self.master.attributes("-topmost", self.config["keep_window_on_top"]))
self._add_switch(frame, "Check Updates on Startup", "check_updates_on_startup",
lambda: self._update("check_updates_on_startup", self.config["check_updates_on_startup"]))
self._add_switch(frame, "Auto-Close App when Task Finishes", "auto_close_on_finish",
lambda: self._update("auto_close_on_finish", self.config["auto_close_on_finish"]))
c3 = SettingCard(frame, "MAINTENANCE")
row = ctk.CTkFrame(frame, fg_color="transparent")
row.pack(fill="x", padx=5, pady=10)
ctk.CTkButton(row, text="Clean Temporary Files", fg_color="#4A0000", hover_color=THEME["error"], border_color=THEME["error"], border_width=1,
command=self._clean_temp).pack(side="left", expand=True, fill="x", padx=(0, 5))
ctk.CTkButton(row, text="Reset All Settings", fg_color="transparent", border_color=THEME["warning"], border_width=1, text_color=THEME["warning"],
hover_color="#332200", command=self._reset_settings).pack(side="right", expand=True, fill="x", padx=(5, 0))
def _build_system_menu(self):
self.hw_menu = CollapsibleMenu(
self.scroll_frame, "System & AI Configuration")
frame = self.hw_menu.content_frame
SettingCard(frame, "HARDWARE DIAGNOSTICS (NEO ENGINE)")
self.hw_content = ctk.CTkFrame(frame, fg_color="transparent")
self.hw_content.pack(fill="both", padx=10, pady=5)
self.btn_scan = ctk.CTkButton(frame, text="Run Hardware Scan", fg_color=THEME["border"], hover_color=THEME["hover"],
command=self._run_scan, height=35)
self.btn_scan.pack(pady=15, padx=10)
SettingCard(frame, "PROCESSING PRIORITY")
self._add_dropdown(frame, "FFmpeg/AI Priority", "process_priority", ["Normal", "Above Normal", "High"],
lambda v: self._update("process_priority", v))
def _run_scan(self):
self.btn_scan.configure(state="disabled", text="Scanning System...")
for widget in self.hw_content.winfo_children():
widget.destroy()
ctk.CTkLabel(self.hw_content, text="Scanning with NEO Engine... Please wait.",
text_color=THEME["text_sec"]).pack(pady=20)
threading.Thread(target=self._thread_scan, daemon=True).start()
def _thread_scan(self):
specs = HardwareScanner.get_specs_detailed()
recs = HardwareScanner.get_smart_recommendations(specs)
if self.winfo_exists():
self.after(0, lambda: self._render_specs(specs, recs))
def _render_specs(self, specs, recs):
if not self.winfo_exists():
return
self.btn_scan.configure(state="normal", text="Refresh Hardware Info")
for widget in self.hw_content.winfo_children():
widget.destroy()
grid = ctk.CTkFrame(self.hw_content, fg_color="transparent")
grid.pack(fill="x")
grid.grid_columnconfigure(1, weight=1)
items = [("CPU", specs['cpu_name']), ("Cores", f"{specs['cpu_cores']} Logical Cores"),
("RAM",
f"{specs['ram_total']} GB (Used: {specs['ram_used']} GB)"),
("GPU", specs['gpu_name']), ("VRAM", f"{specs['gpu_vram']} GB"), ("OS", specs['os'])]
for i, (label, val) in enumerate(items):
ctk.CTkLabel(grid, text=label, font=get_font(11, "bold"), text_color=THEME["text_sec"], anchor="w").grid(
row=i, column=0, sticky="w", pady=4, padx=5)
ctk.CTkLabel(grid, text=str(val), font=get_font(11), text_color=THEME["accent"], anchor="w").grid(
row=i, column=1, sticky="w", padx=20, pady=4)
rec_frame = ctk.CTkFrame(
self.hw_content, fg_color="#1A1A1A", corner_radius=6)
rec_frame.pack(fill="x", padx=10, pady=20)
ctk.CTkLabel(rec_frame, text="RECOMMENDED AI SETTINGS",
text_color=THEME["success"], font=get_font(11, "bold")).pack(pady=(10, 10))
rec_grid = ctk.CTkFrame(rec_frame, fg_color="transparent")
rec_grid.pack(pady=(0, 10), padx=10)
r_items = [("Tiles Resolution", recs.get("Recommended Tiles", "N/A")),
("VRAM Limit", recs.get("Safe VRAM Limit", "N/A")),
("AI Threads", recs.get("Multithreading", "OFF"))]
for i, (k, v) in enumerate(r_items):
ctk.CTkLabel(rec_grid, text=k + ": ", text_color=THEME["text_sec"], anchor="e").grid(
row=i, column=0, padx=(10, 5), pady=2, sticky="e")
ctk.CTkLabel(rec_grid, text=v, text_color="#FFFFFF", font=get_font(
12, "bold"), anchor="w").grid(row=i, column=1, padx=(0, 10), pady=2, sticky="w")
def _build_updates_menu(self):
menu = CollapsibleMenu(self.scroll_frame, "Updates & Changelog")
frame = menu.content_frame
v_frame = ctk.CTkFrame(frame, fg_color="transparent")
v_frame.pack(pady=15)
ctk.CTkLabel(v_frame, text="CURRENT VERSION", font=get_font(
10), text_color=THEME["text_sec"]).pack()
ctk.CTkLabel(v_frame, text=f"v{self.curr_ver}", font=(
"Impact", 42), text_color=THEME["accent"]).pack()
self.btn_upd = ctk.CTkButton(frame, text="Check for Updates", height=45,
fg_color=THEME["border"], hover_color=THEME["hover"], font=get_font(14, "bold"), command=self._check_update)
self.btn_upd.pack(fill="x", padx=60, pady=(0, 20))
ctk.CTkLabel(frame, text="CHANGELOG / STATUS:", font=get_font(11, "bold"),
text_color=THEME["text_sec"], anchor="w").pack(fill="x", pady=(10, 5), padx=5)
self.upd_log = ctk.CTkTextbox(frame, height=200, fg_color="#111111", text_color=THEME["text"], font=(
"Consolas", 11), border_width=1, border_color=THEME["widget_bg"])
self.upd_log.pack(fill="x", expand=True, pady=5, padx=5)
self.upd_log.insert(
"0.0", "Click 'Check for Updates' to connect to GitHub repository...")
def _check_update(self):
self.btn_upd.configure(state="disabled", text="Checking GitHub...")
self.upd_log.delete("0.0", "end")
self.upd_log.insert("end", "Connecting to repository...\n")
threading.Thread(target=self._thread_upd, daemon=True).start()
def _thread_upd(self):
res = self.upd_mgr.check_update()
if self.winfo_exists():
self.after(0, lambda: self._res_upd(res))
def _res_upd(self, res):
is_new, tag, assets, body = res
self.btn_upd.configure(state="normal", text="Check Again")
self.upd_log.delete("0.0", "end")
if is_new is None:
self.upd_log.insert("end", f"Connection Error: {tag}\n")
elif is_new:
self.upd_log.insert(
"end", f"NEW UPDATE AVAILABLE: v{tag}\n\n--- CHANGELOG ---\n\n{body}\n")
if messagebox.askyesno("Update Found", f"Version v{tag} available. Download?"):
target = next(
(a for a in assets if a['name'].endswith('.exe')), None)
if target:
self._start_download(
target['browser_download_url'], target['name'])
else:
webbrowser.open(
"https://github.com/Ivan-Ayub97/Warlock-Studio/releases")
else:
self.upd_log.insert(
"end", f"You are using the latest version (v{tag}).")
def _start_download(self, url, name):
dw = DownloadWindow(self, name)
def t():
try:
tmp = os.path.join(os.getenv('TEMP'), name)
self.upd_mgr.download(url, tmp, dw.update_progress)
dw.destroy()
if messagebox.askyesno("Install", "Download complete. Install now?"):
os.startfile(tmp)
sys.exit(0)
except Exception as e:
dw.destroy()
messagebox.showerror("Download Error", str(e))
threading.Thread(target=t, daemon=True).start()
def _build_logs_menu(self):
menu = CollapsibleMenu(self.scroll_frame, "Log Management")
frame = menu.content_frame
ctrl = ctk.CTkFrame(frame, fg_color="transparent")
ctrl.pack(fill="x", padx=5, pady=5)
ctk.CTkButton(ctrl, text="Refresh Logs", width=120,
fg_color=THEME["widget_bg"], command=self._load_logs).pack(side="left", padx=5)
ctk.CTkButton(ctrl, text="Export All Logs (.zip)", width=160,
fg_color=THEME["info_bg"], command=self._export_logs).pack(side="right", padx=5)
self.log_text = ctk.CTkTextbox(frame, font=("Consolas", 11), fg_color="#111111", text_color="#DDDDDD",
wrap="none", border_width=1, border_color=THEME["widget_bg"], height=200)
self.log_text.pack(fill="x", expand=True, padx=5, pady=5)
self._load_logs()
def _load_logs(self):
self.log_text.delete("0.0", "end")
log_dir = os.path.join(os.path.expanduser('~'), 'Documents')
patterns = [os.path.join(log_dir, "Warlock*Logs", "*.log"),
os.path.join(log_dir, "Warlock*Logs", "*.txt")]
found_files = []
for p in patterns:
found_files.extend(glob.glob(p))
found_files.sort(key=os.path.getmtime, reverse=True)
if not found_files:
self.log_text.insert("end", "No log files found.")
return
latest = found_files[0]
self.log_text.insert(
"end", f"--- LOADING LOG: {os.path.basename(latest)} ---\n\n")
try:
with open(latest, "r", encoding="utf-8", errors='replace') as f:
self.log_text.insert("end", f.read())
except Exception as e:
self.log_text.insert("end", f"Error reading log: {e}")
def _export_logs(self):
try:
save_path = filedialog.asksaveasfilename(
defaultextension=".zip", filetypes=[("ZIP", "*.zip")])
if not save_path:
return
log_dir = os.path.join(os.path.expanduser('~'), 'Documents')
folders = glob.glob(os.path.join(log_dir, "Warlock*Logs"))
if not folders:
return
with zipfile.ZipFile(save_path, 'w') as zf:
for folder in folders:
for root, _, files in os.walk(folder):
for file in files:
zf.write(os.path.join(root, file), arcname=file)
messagebox.showinfo("Export", "Logs exported successfully!")
except Exception as e:
messagebox.showerror("Error", str(e))
def _build_about_menu(self):
menu = CollapsibleMenu(self.scroll_frame, "About Warlock-Studio")
frame = menu.content_frame
ctk.CTkLabel(frame, text="WARLOCK-STUDIO", font=("Impact",
40), text_color=THEME["title"]).pack(pady=(20, 5))
ctk.CTkLabel(frame, text=f"Version {self.curr_ver}", font=get_font(
12), text_color=THEME["accent"]).pack(pady=(0, 20))
SettingCard(frame, "DEVELOPER & PROJECT")
ctk.CTkLabel(frame, text="Developed by Ivan-Ayub97",
font=get_font(12, "bold")).pack(pady=5)
link_frame = ctk.CTkFrame(frame, fg_color="transparent")
link_frame.pack(pady=10)
ctk.CTkButton(link_frame, text="GitHub Repository", fg_color="#24292e", width=140, command=lambda: webbrowser.open(
"https://github.com/Ivan-Ayub97/Warlock-Studio")).pack(side="left", padx=10)
ctk.CTkButton(link_frame, text="SourceForge", fg_color="#EE7600", width=140, command=lambda: webbrowser.open(
"https://sourceforge.net/projects/warlock-studio/")).pack(side="left", padx=10)
SettingCard(frame, "LICENSES")
base_dir = getattr(sys, '_MEIPASS', os.path.dirname(
os.path.abspath(__file__)))
license_path = os.path.join(base_dir, "Assets", "license.txt")
try:
with open(license_path, "r", encoding="utf-8") as f:
l_txt = f.read()
except:
l_txt = "License file not found."
ld = ctk.CTkTextbox(frame, height=200, fg_color="#111111",
text_color=THEME["text"], font=("Consolas", 10))
ld.pack(fill="x", expand=True, pady=10, padx=20)
ld.insert("0.0", l_txt)
ld.configure(state="disabled")
# --- HELPERS ---
def _update(self, key, val, callback=None):
if isinstance(val, float):
val = round(val, 2)
self.config[key] = val
ConfigManager.save_config(self.config)
if callback:
callback()
self.status_lbl.configure(text="Saved ✓", text_color=THEME["success"])
self.after(2000, lambda: self.status_lbl.configure(text=""))
def _add_slider(self, parent, text, key, min_v, max_v, steps, cmd):
f = ctk.CTkFrame(parent, fg_color="transparent")
f.pack(fill="x", padx=5, pady=5)
ctk.CTkLabel(f, text=text, width=140, anchor="w",
font=get_font(11)).pack(side="left")
val_lbl = ctk.CTkLabel(
f, text=f"{self.config.get(key, min_v):.2f}", width=40, text_color=THEME["accent"])
val_lbl.pack(side="right")
def internal_cmd(v):
val_lbl.configure(text=f"{v:.2f}")
cmd(v)
s = ctk.CTkSlider(f, from_=min_v, to=max_v, number_of_steps=steps, command=internal_cmd,
progress_color=THEME["accent"], button_color=THEME["accent"], button_hover_color=THEME["accent_hover"])
s.set(self.config.get(key, min_v))
s.pack(side="right", fill="x", expand=True, padx=10)
def _add_switch(self, parent, text, key, cmd):
def internal_cmd():
self.config[key] = bool(sw.get())
ConfigManager.save_config(self.config)
if cmd:
cmd()
self.status_lbl.configure(
text="Saved ✓", text_color=THEME["success"])
self.after(1500, lambda: self.status_lbl.configure(text=""))
sw = ctk.CTkSwitch(parent, text=text, command=internal_cmd, font=get_font(11),
progress_color=THEME["accent"], button_color="#FFFFFF", button_hover_color="#EEEEEE")
if self.config.get(key, False):
sw.select()
sw.pack(anchor="w", padx=10, pady=8)
def _add_dropdown(self, parent, text, key, values, cmd):
f = ctk.CTkFrame(parent, fg_color="transparent")
f.pack(fill="x", padx=5, pady=5)
ctk.CTkLabel(f, text=text, width=140, anchor="w",
font=get_font(11)).pack(side="left")
om = ctk.CTkOptionMenu(f, values=values, command=cmd, font=get_font(11),
fg_color=THEME["widget_bg"], button_color=THEME["accent"],
button_hover_color=THEME["accent_hover"], text_color=THEME["bg"])
om.set(self.config.get(key, values[0]))
om.pack(side="right", fill="x", expand=True, padx=10)
def _clean_temp(self):
n = 0
cwd = os.getcwd()
patterns = ["*.tmp", "*.checkpoint",
"*.part", "temp_*", "*_frames.txt"]
for p in patterns:
for f in glob.glob(os.path.join(cwd, p)):
try:
os.remove(f)
n += 1
except:
pass
messagebox.showinfo(
"Clean", f"Cleanup complete.\nRemoved {n} temporary files.")
def _reset_settings(self):
if messagebox.askyesno("Reset", "Restore default settings?"):
ConfigManager.reset_config()
self.destroy()
# -----------------------------------------------------------------------------
# BOTÓN PRINCIPAL (INTEGRACIÓN)
# -----------------------------------------------------------------------------
class PreferencesButton(ctk.CTkButton):
def __init__(self, master, current_version, repo_owner="Ivan-Ayub97", repo_name="Warlock-Studio", **kwargs):
super().__init__(master, text="", width=100, height=28,
fg_color=THEME["widget_bg"], border_color=THEME["border"], border_width=1,
hover_color=THEME["hover"], text_color=THEME["text"],
command=self.open_window, **kwargs)
self.ver = current_version
self.repo = (repo_owner, repo_name)
self._apply_startup_config()
def open_window(self):
for w in self.master.winfo_children():
if isinstance(w, PreferencesWindow):
w.lift()
w.focus_force()
return
PreferencesWindow(self.master, self.ver, *self.repo)
def _apply_startup_config(self):
c = ConfigManager.load_config()
try:
ctk.set_appearance_mode(c.get("app_theme", "Dark"))
ctk.set_widget_scaling(c.get("ui_scaling", 1.0))
except:
pass
if c.get("window_opacity", 1.0) < 1.0:
self.master.attributes("-alpha", c["window_opacity"])
if c.get("keep_window_on_top", False):
self.master.attributes("-topmost", True)