Asset-Frameworker/Project Notes/OUTPUT_FORMAT_PLAN.md
2025-04-29 18:26:13 +02:00

103 lines
7.3 KiB
Markdown

# Plan: Implement Input-Based Output Format Logic
This plan outlines the steps to modify the Asset Processor Tool to determine the output format of texture maps based on the input file format and specific rules.
## Requirements Summary
Based on user clarifications:
1. **JPG Input -> JPG Output:** If the original source map is a JPG, the output for that map (at all processed resolutions) will also be JPG (8-bit).
2. **TIF Input -> PNG/EXR Output:** If the original source map is a TIF, the output will be PNG (if the target bit depth is 8-bit, or if 16-bit PNG is the configured preference) or EXR (if the target bit depth is 16-bit and EXR is the configured preference).
3. **Other Inputs (PNG, etc.) -> Configured Output:** For other input formats, the output will follow the existing logic based on target bit depth (using configured 16-bit or 8-bit formats, typically EXR/PNG).
4. **`force_8bit` Rule:** If a map type has a `force_8bit` rule, it overrides the input format. Even if the input was 16-bit TIF, the output will be 8-bit PNG.
5. **Merged Maps:** The output format is determined by the highest format in the hierarchy (EXR > TIF > PNG > JPG) based on the *original* formats of the input files used in the merge. However, if the highest format is TIF, the actual output will be PNG/EXR based on the target bit depth. The target bit depth itself is determined separately by the merge rule's `output_bit_depth` setting.
6. **JPG Resizing:** Resized JPGs will be saved as JPG.
## Implementation Plan
**Phase 1: Data Gathering Enhancement**
1. **Modify `_inventory_and_classify_files` in `asset_processor.py`:**
* When classifying map files, extract and store the original file extension (e.g., `.jpg`, `.tif`, `.png`) along with the `source_path`, `map_type`, etc., within the `self.classified_files["maps"]` list.
**Phase 2: Implement New Logic for Individual Maps (`_process_maps`)**
1. **Modify `_process_maps` in `asset_processor.py`:**
* Inside the loop processing each `map_info`:
* Retrieve the stored original file extension.
* Determine the target output bit depth (8 or 16) using the existing logic (`config.get_bit_depth_rule`, source data type).
* **Implement New Format Determination:**
* Initialize `output_format` and `output_ext`.
* Check the `force_8bit` rule first: If the rule is `force_8bit`, set `output_format = 'png'` and `output_ext = '.png'`, regardless of input format.
* If not `force_8bit`:
* If `original_extension == '.jpg'` and `target_bit_depth == 8`: Set `output_format = 'jpg'`, `output_ext = '.jpg'`.
* If `original_extension == '.tif'`:
* If `target_bit_depth == 16`: Determine format (EXR/PNG) and extension based on `config.get_16bit_output_formats()`.
* If `target_bit_depth == 8`: Set `output_format = 'png'`, `output_ext = '.png'`.
* If `original_extension` is neither `.jpg` nor `.tif` (e.g., `.png`):
* If `target_bit_depth == 16`: Determine format (EXR/PNG) and extension based on `config.get_16bit_output_formats()`.
* If `target_bit_depth == 8`: Set `output_format = config.get_8bit_output_format()` (likely 'png'), `output_ext = f".{output_format}"`.
* **Remove Old Logic:** Delete the code block that checks `self.config.resolution_threshold_for_jpg`.
* Set `save_params` based on the *newly determined* `output_format` (e.g., `cv2.IMWRITE_JPEG_QUALITY` for JPG, `cv2.IMWRITE_PNG_COMPRESSION` for PNG).
* Proceed with data type conversion (if needed based on target bit depth and format requirements like EXR needing float16) and saving using `cv2.imwrite` with the determined `output_path_temp` (using the new `output_ext`) and `save_params`. Ensure fallback logic (e.g., EXR -> PNG) still functions correctly if needed.
**Phase 3: Implement New Logic for Merged Maps (`_merge_maps`)**
1. **Modify `_merge_maps` in `asset_processor.py`:**
* Inside the loop for each `current_res_key`:
* When loading input maps (`loaded_inputs`), also retrieve and store their *original* file extensions (obtained during classification and now available via `self.classified_files["maps"]`, potentially needing a lookup based on `res_details['path']` or storing it earlier).
* **Determine Highest Input Format:** Iterate through the original extensions of the loaded inputs for this resolution. Use the hierarchy (EXR > TIF > PNG > JPG) to find the highest format present.
* **Determine Final Output Format:**
* Start with the `highest_input_format`.
* If `highest_input_format == 'tif'`:
* Check the target bit depth determined by the merge rule (`output_bit_depth`).
* If `target_bit_depth == 16`: Set final format based on `config.get_16bit_output_formats()` (EXR/PNG).
* If `target_bit_depth == 8`: Set final format to `png`.
* Otherwise (JPG, PNG, EXR), the final format is the `highest_input_format`.
* Set `output_ext` based on the `final_output_format`.
* Set `save_params` based on the `final_output_format`.
* Proceed with merging channels, converting the merged data to the target bit depth specified by the *merge rule*, and saving using `cv2.imwrite` with the determined `merged_output_path_temp` (using the new `output_ext`) and `save_params`.
**Phase 4: Configuration and Documentation**
1. **Modify `config.py`:**
* Comment out or remove the `RESOLUTION_THRESHOLD_FOR_JPG` variable as it's no longer used. Add a comment explaining why it was removed.
2. **Update `readme.md`:**
* Modify the "Features" section (around line 21) and the "Configuration" section (around lines 36-40, 86) to accurately describe the new output format logic:
* Explain that JPG inputs result in JPG outputs.
* Explain that TIF inputs result in PNG/EXR outputs based on target bit depth and config.
* Explain the merged map format determination based on input hierarchy (with the TIF->PNG/EXR adjustment).
* Mention the removal of the JPG resolution threshold.
## Visual Plan (Mermaid)
```mermaid
graph TD
A[Start] --> B(Phase 1: Enhance Classification);
B --> B1(Store original extension in classified_files['maps']);
B1 --> C(Phase 2: Modify _process_maps);
C --> C1(Get original extension);
C --> C2(Determine target bit depth);
C --> C3(Apply New Format Logic);
C3 -- force_8bit --> C3a[Format=PNG];
C3 -- input=.jpg, 8bit --> C3b[Format=JPG];
C3 -- input=.tif, 16bit --> C3c[Format=EXR/PNG (Config)];
C3 -- input=.tif, 8bit --> C3d[Format=PNG];
C3 -- input=other, 16bit --> C3c;
C3 -- input=other, 8bit --> C3e[Format=PNG (Config)];
C3a --> C4(Remove JPG Threshold Check);
C3b --> C4;
C3c --> C4;
C3d --> C4;
C3e --> C4;
C4 --> C5(Set Save Params & Save);
C5 --> D(Phase 3: Modify _merge_maps);
D --> D1(Get original extensions of inputs);
D --> D2(Find highest format via hierarchy);
D2 --> D3(Adjust TIF -> PNG/EXR based on target bit depth);
D3 --> D4(Determine target bit depth from rule);
D4 --> D5(Set Save Params & Save Merged);
D5 --> E(Phase 4: Config & Docs);
E --> E1(Update config.py - Remove threshold);
E --> E2(Update readme.md);
E2 --> F[End];