2026-02-13 10:59:49 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
# PNGizer: convert any file into PNG image and back
|
2026-02-13 11:14:35 +02:00
|
|
|
# Depends on mktemp, tar, gzip, ImageMagick and pngcrush
|
2026-02-13 10:59:49 +02:00
|
|
|
# Created by Luxferre in 2026, released into public domain
|
|
|
|
|
|
|
|
|
|
# Convert any raw data file to PNG
|
|
|
|
|
# Usage: pngize_raw $infile $pngfile
|
|
|
|
|
pngize_raw() {
|
|
|
|
|
temp_ppm="$(mktemp)"
|
|
|
|
|
# get raw input size
|
|
|
|
|
fsize=$(wc -c < "$1")
|
|
|
|
|
# calculate image side length to fit everything
|
|
|
|
|
sidelen=$(echo "scale=0;1 + sqrt($fsize / 3 + 1)" | bc -l)
|
|
|
|
|
# how many trailing zero bytes we need
|
|
|
|
|
remlen=$((sidelen * sidelen * 3 - fsize))
|
|
|
|
|
# shape the PPM file:
|
|
|
|
|
# 1. header (PPM binary)
|
|
|
|
|
printf 'P6\n%s %s\n255\n' $sidelen $sidelen > $temp_ppm
|
|
|
|
|
# 2. body (raw file data)
|
|
|
|
|
cat "$1" >> $temp_ppm
|
|
|
|
|
# 3. trailing zero bytes
|
|
|
|
|
for i in $(seq 1 $remlen); do printf '\x00' >> $temp_ppm; done
|
|
|
|
|
# convert PPM to PNG and remove the temporary PPM
|
|
|
|
|
magick ppm:$temp_ppm png:$ofile
|
|
|
|
|
rm -f $temp_ppm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# extract any raw data file from PNG
|
|
|
|
|
# Usage: unpngize_raw $pngfile $outfile
|
|
|
|
|
unpngize_raw() {
|
|
|
|
|
temp_ppm="$(mktemp)"
|
|
|
|
|
# convert PNG to PPM (should be P6)
|
|
|
|
|
magick png:$1 ppm:$temp_ppm
|
|
|
|
|
# extract the raw body
|
|
|
|
|
tail -n +4 $temp_ppm > $2
|
|
|
|
|
# remove the temporary PPM
|
|
|
|
|
rm -f $temp_ppm
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Convert any file or directory to PNG
|
|
|
|
|
pngize() {
|
|
|
|
|
ofile="$2"
|
|
|
|
|
[ -z "$2" ] && ofile="$1.png"
|
|
|
|
|
temp_arch="$(mktemp)"
|
|
|
|
|
# containerize the input
|
2026-02-13 11:14:35 +02:00
|
|
|
GZIP=-9 tar czvf $temp_arch "$1"
|
2026-02-13 10:59:49 +02:00
|
|
|
# run the conversion
|
|
|
|
|
pngize_raw $temp_arch $ofile
|
|
|
|
|
rm -f $temp_arch
|
|
|
|
|
# apply compression
|
|
|
|
|
pngcrush -ow $ofile
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Extract the file or directory from PNG
|
|
|
|
|
unpngize() {
|
|
|
|
|
temp_arch="$(mktemp)"
|
|
|
|
|
unpngize_raw "$1" $temp_arch
|
2026-02-13 11:14:35 +02:00
|
|
|
gzip -dcq $temp_arch | tar xvf -
|
2026-02-13 10:59:49 +02:00
|
|
|
rm -f $temp_arch
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# entry point
|
|
|
|
|
|
|
|
|
|
[ -z "$2" ] && echo 'No input file specified! Exiting...' && exit 1
|
|
|
|
|
if [ "$1" = "e" ]; then
|
|
|
|
|
[ -z "$3" ] && echo "No output file specified! Using $2.png as output file"
|
|
|
|
|
pngize "$2" "$3"
|
|
|
|
|
elif [ "$1" = "d" ]; then
|
|
|
|
|
unpngize "$2"
|
|
|
|
|
else
|
|
|
|
|
echo 'Invalid mode! Use e for encoding or d for decoding'
|
|
|
|
|
fi
|