73 lines
1.9 KiB
Bash
73 lines
1.9 KiB
Bash
#!/bin/sh
|
|||
|
|
# PNGizer: convert any file into PNG image and back
|
||
|
|
# Depends on mktemp, tar, ImageMagick and pngcrush
|
||
|
|
# 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
|
||
|
|
tar cf $temp_arch "$1"
|
||
|
|
# 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
|
||
|
|
tar xf $temp_arch
|
||
|
|
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
|