Skip to content

Instantly share code, notes, and snippets.

@adrenak
Created June 8, 2026 08:28
Show Gist options
  • Select an option

  • Save adrenak/e646b7b3a2eb78704e3e1b5ea85e5a8f to your computer and use it in GitHub Desktop.

Select an option

Save adrenak/e646b7b3a2eb78704e3e1b5ea85e5a8f to your computer and use it in GitHub Desktop.
tar2jpg
#!/usr/bin/env bash
set -euo pipefail
TEMP_DIR=""
DOWNLOADED_FFMPEG=false
cleanup() {
if [ "$DOWNLOADED_FFMPEG" = true ] && [ -n "$TEMP_DIR" ]; then
rm -rf "$TEMP_DIR"
fi
}
trap cleanup EXIT
show_help() {
cat << EOF
TGA to JPG Converter
Usage:
$0 [QUALITY]
Quality Options:
--low Smallest file size, noticeable compression
--medium Balanced quality and size
--high High quality (recommended)
--veryhigh Near-lossless quality, largest files
Examples:
$0 --high
$0 --low
EOF
}
QUALITY_LEVEL="${1:-}"
case "$QUALITY_LEVEL" in
--low) Q=20 ;;
--medium) Q=10 ;;
--high) Q=4 ;;
--veryhigh) Q=1 ;;
-h|--help) show_help; exit 0 ;;
*) echo "Invalid or missing argument."; echo; show_help; exit 1 ;;
esac
download_file() {
local url="$1"
local out="$2"
if command -v curl >/dev/null 2>&1; then
curl -L "$url" -o "$out"
elif command -v wget >/dev/null 2>&1; then
wget "$url" -O "$out"
else
echo "Error: Neither curl nor wget is available."
exit 1
fi
}
extract_archive() {
local archive="$1"
local dest="$2"
case "$archive" in
*.zip)
command -v unzip >/dev/null 2>&1 || { echo "Error: unzip is required."; exit 1; }
unzip -q "$archive" -d "$dest"
;;
*.tar.xz)
tar -xJf "$archive" -C "$dest"
;;
*)
echo "Error: Unsupported archive: $archive"
exit 1
;;
esac
}
FFMPEG_BIN="ffmpeg"
if ! command -v ffmpeg >/dev/null 2>&1; then
echo ""
echo "⚠️ ffmpeg not found."
echo "Temporarily downloading portable ffmpeg..."
echo ""
TEMP_DIR="$(mktemp -d)"
DOWNLOADED_FFMPEG=true
OS="$(uname -s)"
ARCH="$(uname -m)"
case "$OS" in
Darwin)
case "$ARCH" in
arm64) FFMPEG_URL="https://ffmpeg.martin-riedl.de/redirect/latest/macos/arm64/release/ffmpeg.zip" ;;
x86_64) FFMPEG_URL="https://ffmpeg.martin-riedl.de/redirect/latest/macos/amd64/release/ffmpeg.zip" ;;
*) echo "Error: Unsupported macOS architecture: $ARCH"; exit 1 ;;
esac
ARCHIVE_FILE="$TEMP_DIR/ffmpeg.zip"
;;
Linux)
case "$ARCH" in
x86_64|amd64) FFMPEG_URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" ;;
aarch64|arm64) FFMPEG_URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz" ;;
*) echo "Error: Unsupported Linux architecture: $ARCH"; exit 1 ;;
esac
ARCHIVE_FILE="$TEMP_DIR/ffmpeg.tar.xz"
;;
MINGW*|MSYS*|CYGWIN*)
FFMPEG_URL="https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
ARCHIVE_FILE="$TEMP_DIR/ffmpeg.zip"
;;
*)
echo "Error: Unsupported OS: $OS"
exit 1
;;
esac
download_file "$FFMPEG_URL" "$ARCHIVE_FILE"
echo "Extracting ffmpeg..."
extract_archive "$ARCHIVE_FILE" "$TEMP_DIR"
FFMPEG_BIN="$(find "$TEMP_DIR" -type f \( -name "ffmpeg" -o -name "ffmpeg.exe" \) | head -n 1)"
if [ ! -f "$FFMPEG_BIN" ]; then
echo "Error: Failed to locate ffmpeg executable."
exit 1
fi
chmod +x "$FFMPEG_BIN"
echo "Using temporary ffmpeg:"
echo "$FFMPEG_BIN"
fi
shopt -s nullglob nocaseglob
FOUND=false
for file in *.tga; do
FOUND=true
filename="${file%.*}"
output="${filename}.jpg"
echo ""
echo "Converting:"
echo " Input : $file"
echo " Output: $output"
"$FFMPEG_BIN" -loglevel error -y -i "$file" \
-q:v "$Q" \
-pix_fmt yuvj420p \
"$output"
done
if [ "$FOUND" = false ]; then
echo "No TGA files found in current directory."
exit 0
fi
echo ""
echo "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment