Scripts to help with batch processing textures

When processing a batch of textures, there can be some quirks that need to be handled. E.g A tiny number of terrain textures have 8-bit alpha layers. It doesn't appear that those particular textures need or use 256 levels of transparency, or use transparency any differently from textures with 1-bit alpha layers. So it's curious why they're different. And about half of the terrain textures contain a very narrow alpha border which also doesn't appear to have much function, but it does necessitate a different file compression format.

It would appear that the terrain texturing system would function equally well if all the .dds files used the same compression and alpha formats. But they don't and for the sake of originality or equivalency it's worth preserving those differences when processing batches of files. Hence the need to make some scripts to sort texture files according to their compression and alpha formats.

SWG textures can use dxt1, dxt3, or dxt5 compression. The main difference is the existence and bit depth of an alpha layer. Here is a batch file to sort .dds texture files according to the dxt compression format. It copies files into DXT1, DXT3, and DXT5 folders.
Code:
:: dxt_sorter.bat
:: Uses ImageMagick to determine the dxt compression format
:: Copies .dds files to folders according to format

@echo off
setlocal enabledelayedexpansion

:: Create destination folders
for %%d in (DXT1 DXT3 DXT5) do (
    if not exist %%d (
        mkdir %%d
        echo Created folder: %%d
    )
)

:: Initialize counters
set /a countDXT1=0
set /a countDXT3=0
set /a countDXT5=0
set /a countSkipped=0

:: Loop through all .dds files
for %%f in (*.dds) do (
    magick identify -verbose "%%f" > temp_output.txt

    set "compressionType="

    findstr /r /c:"^[ ][ ]Compression: DXT1" temp_output.txt >nul
    if not errorlevel 1 set "compressionType=DXT1"

    findstr /r /c:"^[ ][ ]Compression: DXT3" temp_output.txt >nul
    if not errorlevel 1 set "compressionType=DXT3"

    findstr /r /c:"^[ ][ ]Compression: DXT5" temp_output.txt >nul
    if not errorlevel 1 set "compressionType=DXT5"

    if "!compressionType!"=="DXT1" (
        echo Copying %%f to DXT1
        copy /Y "%%f" DXT1\ >nul
        set /a countDXT1+=1
    ) else if "!compressionType!"=="DXT3" (
        echo Copying %%f to DXT3
        copy /Y "%%f" DXT3\ >nul
        set /a countDXT3+=1
    ) else if "!compressionType!"=="DXT5" (
        echo Copying %%f to DXT5
        copy /Y "%%f" DXT5\ >nul
        set /a countDXT5+=1
    ) else (
        echo Skipped %%f - unknown compression type
        set /a countSkipped+=1
    )

    del temp_output.txt
)

:: Show summary
set /a totalCount=countDXT1 + countDXT3 + countDXT5
echo.
echo Files copied to DXT1: %countDXT1%
echo Files copied to DXT3: %countDXT3%
echo Files copied to DXT5: %countDXT5%
echo Files copied (total): %totalCount%
echo Files skipped: %countSkipped%

SWG textures can use 1-bit, 4-bit, or 8-bit alpha layers. Here is a batch file to sort .dds texture files according to the alpha layer bit depth. It copies files into alpha_8bit, alpha_4bit, and alpha_1bit folders.

Code:
:: alpha_sorter.bat
:: Uses ImageMagick to determine the dds alpha layer format
:: Copies .dds files to folders according to format

@echo off
setlocal enabledelayedexpansion

:: Create destination folders
for %%d in (alpha_8bit alpha_4bit alpha_1bit) do (
    if not exist %%d (
        mkdir %%d
        echo Created folder: %%d
    )
)

:: Initialize counters
set /a count8=0
set /a count4=0
set /a count1=0
set /a countSkipped=0

:: Loop through all .dds files
for %%f in (*.dds) do (
    magick identify -verbose "%%f" > temp_output.txt

    set "alphaType="

    findstr /r /c:"^[ ]*Alpha: 8-bit" temp_output.txt >nul
    if not errorlevel 1 set "alphaType=8"

    findstr /r /c:"^[ ]*Alpha: 4-bit" temp_output.txt >nul
    if not errorlevel 1 set "alphaType=4"

    findstr /r /c:"^[ ]*Alpha: 1-bit" temp_output.txt >nul
    if not errorlevel 1 set "alphaType=1"

    if "!alphaType!"=="8" (
        echo Copying %%f to alpha_8bit
        copy /Y "%%f" alpha_8bit\ >nul
        set /a count8+=1
    ) else if "!alphaType!"=="4" (
        echo Copying %%f to alpha_4bit
        copy /Y "%%f" alpha_4bit\ >nul
        set /a count4+=1
    ) else if "!alphaType!"=="1" (
        echo Copying %%f to alpha_1bit
        copy /Y "%%f" alpha_1bit\ >nul
        set /a count1+=1
    ) else (
        echo Skipped %%f - no alpha
        set /a countSkipped+=1
    )

    del temp_output.txt
)

:: Show summary
set /a totalAlpha=count8 + count4 + count1
echo.
echo Files copied to alpha_8bit: %count8%
echo Files copied to alpha_4bit: %count4%
echo Files copied to alpha_1bit: %count1%
echo Files copied (total): %totalAlpha%
echo Files skipped: %countSkipped%

SWG textures can have broken alpha layers after they have been extracted from .tre files. Normally the alpha layer will be all white (255 value) or contain a mask. But sometimes the alpha layer can have a 0 value which makes the texture appear invisible or very dark ingame. Here is a powershell script to sort .dds texture files according to the median alpha layer value. It copies files into a folder called tobefixed.

Code:
# dark_alphas.ps1
# Uses ImageMagick to find low median alpha layer values
# Copies .dds files into 'tobefixed' folder

# Create the destination folder if it doesn't exist
$destination = "tobefixed"
if (-not (Test-Path $destination)) {
    New-Item -ItemType Directory -Path $destination | Out-Null
}

$copiedCount = 0

# Looks in the \alpha folders created by alpha_sorter.bat
Get-ChildItem -Path . -Recurse -Include *.dds | Where-Object {
    $_.Directory.Name -like "alpha*"
} | ForEach-Object {
    $file = $_.FullName
    $output = magick identify -verbose $file

    $inAlphaBlock = $false
    $medianAlpha = $null

    # Alpha:
    foreach ($line in $output) {
        if ($line -match "^\s{4}Alpha:") {
            $inAlphaBlock = $true
            continue
        }
        # median:
        if ($inAlphaBlock -and $line -match "^\s{6}median:\s+(\d+)") {
            $medianAlpha = [int]$matches[1]
            break
        }
        # avoid other non-Alpha medians
        if ($inAlphaBlock -and $line -match "^\s{4}\w+:") {
            $inAlphaBlock = $false
        }
    }

    # expected value is 255, anything below that might be problematic
    if ($medianAlpha -ne 255) {
        Write-Host "$($_.FullName) - median alpha: $medianAlpha"
        Copy-Item -Path $file -Destination $destination
        $copiedCount++
    }
}

# Show summary
Write-Host "`nFiles copied (total): $copiedCount"

To fix a texture with a 0 value alpha layer, i.e to set it to 255, use ImageMagick command line tool like this:
Code:
magick input.dds -alpha on -channel A -evaluate set 100% +channel output.dds

The scripts rely on ImageMagick command line tools which can be downloaded from https://imagemagick.org/script/download.php#windows
The scripts use the 'magick identify -verbose' command which produces an output like this:
Code:
C:\projects\swgterrain25>magick identify -verbose dirt_mudcrack.dds
Image:
  Filename: dirt_mudcrack.dds
  Permissions: rw-rw-rw-
  Format: DDS (Microsoft DirectDraw Surface)
  Class: DirectClass
  Geometry: 256x256+0+0
  Units: Undefined
  Colorspace: sRGB
  Type: TrueColorAlpha
  Base type: Undefined
  Endianness: LSB
  Depth: 8-bit
  Channels: 4.0
  Channel depth:
    Red: 8-bit
    Green: 8-bit
    Blue: 8-bit
    Alpha: 8-bit
  Channel statistics:
    Pixels: 65536
    Red:
      min: 132  (0.517647)
      max: 222 (0.870588)
      mean: 196.97 (0.772433)
      median: 200 (0.784314)
      standard deviation: 12.9269 (0.0506937)
      kurtosis: 2.16464
      skewness: -1.43974
      entropy: 0.779197
    Green:
      min: 81  (0.317647)
      max: 219 (0.858824)
      mean: 172.815 (0.677705)
      median: 178 (0.698039)
      standard deviation: 22.9897 (0.0901559)
      kurtosis: 0.513973
      skewness: -0.942304
      entropy: 0.867643
    Blue:
      min: 57  (0.223529)
      max: 206 (0.807843)
      mean: 150.79 (0.591335)
      median: 154 (0.603922)
      standard deviation: 22.8355 (0.0895511)
      kurtosis: 0.046352
      skewness: -0.603107
      entropy: 0.846145
    Alpha:
      min: 0  (0)
      max: 4 (0.0156863)
      mean: 6.10352e-05 (2.39354e-07)
      median: 0 (0)
      standard deviation: 0.015625 (6.12745e-05)
      kurtosis: 65529
      skewness: 255.988
      entropy: 0.000266154
  Image statistics:
    Overall:
      min: 0  (0)
      max: 222 (0.870588)
      mean: 130.144 (0.510368)
      median: 133 (0.521569)
      standard deviation: 14.6919 (0.0576155)
      kurtosis: 16382.9
      skewness: 63.2508
      entropy: 0.623313
  Alpha: srgba(206,199,181,0)   #CEC7B500
  Rendering intent: Perceptual
  Gamma: 0.454545
  Chromaticity:
    red primary: (0.64,0.33,0.03)
    green primary: (0.3,0.6,0.1)
    blue primary: (0.15,0.06,0.79)
    white point: (0.3127,0.329,0.3583)
  Matte color: grey74
  Background color: white
  Border color: srgb(223,223,223)
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 256x256+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: DXT5
  Orientation: Undefined
  Properties:
    date:create: 2025-11-12T13:15:09+00:00
    date:modify: 2025-10-25T14:13:30+00:00
    date:timestamp: 2025-11-13T13:03:52+00:00
    signature: 3902e469a8af2521b0468ae4ad4259a3abf220c98e98c91e45fae2bc4dbca20f
  Artifacts:
    verbose: true
  Tainted: False
  Filesize: 87536B
  Number pixels: 65536
  Pixel cache type: Memory
  Pixels per second: 25.9107MP
  User time: 0.003u
  Elapsed time: 0:01.002
  Version: ImageMagick 7.1.2-8 Q16-HDRI x64 a3b13d1:20251026 https://imagemagick.org
 

Attachments

  • zeroalphaterrain.jpg
    zeroalphaterrain.jpg
    181.4 KB · Views: 9
  • alphaborderterrain.jpg
    alphaborderterrain.jpg
    215.8 KB · Views: 8
Last edited:
Back
Top